在IOS上的OpenGL ES 2.0着色器中绘制简单的线条

时间:2011-11-27 22:46:59

标签: ios opengl-es shader

我很难通过OpenGL ES 2.0着色器绘制简单的线条。 我正在尝试将glDrawArraysGL_LINES一起使用,但到目前为止我还没有成功。

我的顶点着色器是你能得到的最基本的:

attribute vec4 Position; 
attribute vec4 SourceColor; 

uniform mat4 Projection;
uniform mat4 ModelView;

varying vec4 DestinationColor; 

void main(void) { 
    DestinationColor = SourceColor; 
    gl_Position = Projection * ModelView * Position;
}

片段着色器:

varying lowp vec4 DestinationColor;

void main(void) {
    gl_FragColor = DestinationColor;
}

我有些疑惑:

  1. 如何设置原点和目标点坐标?
  2. 在这种情况下如何设置Projection和ModelView矩阵?使用正方形,ModelView矩阵将保持其中心坐标,但在Line的情况下会发生什么?
  3. 有没有人有例子?

    编辑:

    好的,我有以下代码:

        glLineVertices[0].Position[0] = origin.x;
        glLineVertices[0].Position[1] = origin.y;
        glLineVertices[0].Position[2] = 0;
        glLineVertices[0].Color[0] = 1.0f;
        glLineVertices[0].Color[1] = 0.0f;
        glLineVertices[0].Color[2] = 0.0f;
        glLineVertices[0].Color[3] = 0.0f;
        glLineVertices[0].Normal[0] = 0.0f;
        glLineVertices[0].Normal[1] = 0.0f;
        glLineVertices[0].Normal[2] = 1.0f;
    
        glLineVertices[1].Position[0] = end.x;
        glLineVertices[1].Position[1] = end.y;
        glLineVertices[1].Position[2] = 0;
        glLineVertices[1].Color[0] = 1.0f;
        glLineVertices[1].Color[1] = 0.0f;
        glLineVertices[1].Color[2] = 0.0f;
        glLineVertices[1].Color[3] = 0.0f;
        glLineVertices[1].Normal[0] = 0.0f;
        glLineVertices[1].Normal[1] = 0.0f;
        glLineVertices[1].Normal[2] = 1.0f;
    
        glGenVertexArraysOES(1, &vertexArray);
        glBindVertexArrayOES(vertexArray);
    
        glGenBuffers(1, &vertexBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
        glBufferData(GL_ARRAY_BUFFER, vertexStructureSize, glLineVertices, GL_STATIC_DRAW);
    
        glEnableVertexAttribArray(shaderManager.currentAttributeVertexPosition);
        glVertexAttribPointer(shaderManager.currentAttributeVertexPosition, 3, GL_FLOAT, GL_FALSE, sizeof(glLineVertex), 0);
        glEnableVertexAttribArray(shaderManager.currentAttributeSourceColor);
        glVertexAttribPointer(shaderManager.currentAttributeSourceColor, 4, GL_FLOAT, GL_FALSE,  sizeof(glLineVertex), (char *)12);
        glEnableVertexAttribArray(shaderManager.currentAttributeVertexNormal);
        glVertexAttribPointer(shaderManager.currentAttributeVertexNormal, 3, GL_FLOAT, GL_FALSE, sizeof(glLineVertex), (char *)28);
    

    使用渲染方法:

    - (void)render
    {
        //It might as well be the Identity Matrix, nothing happens either way.
        //modelViewMatrix = GLKMatrix4Identity;   
        modelViewMatrix = GLKMatrix4MakeTranslation(0, 0, 0.0f);    
        glUniformMatrix4fv(shaderManager.currentUniformModelViewMatrix, 1, 0, modelViewMatrix.m);
    
        glBindVertexArrayOES(vertexArray);
        glDrawArrays(GL_LINES, 0, size);  
    
    }
    

    使用此投影矩阵:

    _projectionMatrix = GLKMatrix4MakeOrtho(0, self.view.bounds.size.width, 0, self.view.bounds.size.height, -1.0f, 1.0f);
    
    [shaderManager useShaderProgram:@"LineShader"];
    
    glUniformMatrix4fv([shaderManager getUniform:@"Projection" ofShader:@"LineShader"], 1, 0, _projectionMatrix.m);
    

    我一使用:

    [lineDraw render];
    

    什么都没发生。 谁知道为什么?

2 个答案:

答案 0 :(得分:2)

我终于明白了。

这些简单的界限:

glEnableVertexAttribArray(shaderManager.currentAttributeVertexNormal);
glVertexAttribPointer(shaderManager.currentAttributeVertexNormal, 3, GL_FLOAT, GL_FALSE, sizeof(glLineVertex), (char *)28);

引起了这个问题,因为我暂时禁用了着色器中法线的使用,注释掉了相应的属性。不知道只是通过这样做,不会发生绘制,并且getError()都不会抛出任何错误。

我会认为上述答案是正确的,因为它帮助我澄清了坐标和对应的矩阵计算。在这个例子中,普通的2D线,一个不需要任何特殊的modelViewMatrix,它可以保留为“GLKMatrix4Identity”。

再次感谢:)

答案 1 :(得分:0)

  1. “原点和目标点”(假设您的意思是两个线端点)只是线的顶点,在您的情况下是发送到Position属性的值。因此,当使用glDrawArrays时,绑定到Position属性的顶点数组/ VBO(使用具有适当属性索引的glVertexAttribPointer)包含(或应该包含)所有的起点和终点线条一个接一个地存储。当然,绑定到SourceColor属性的数组必须分别包含这些顶点的颜色。

  2. Projection矩阵一如既往地设置,它包含投影变换,通常是正交投影(例如,用于平行2D视图)或透视投影(用于“真实”视图更远的物体看起来更小)。

    ModelView矩阵包含线集应具有的任何变换,并且通常由模型变换组成,模型变换将线集的顶点从其局部坐标系转换为世界坐标系,以及视图变换,它将世界空间的顶点转换为相机空间(然后通过投影变换从中转换)。

    因此对于一个正方形而言,它不仅需要包含sqaure的中心,它只取决于你想要如何转换它以及它未转换顶点的值(通过Position属性发送给OpenGL的值) )。请记住,您发送到Position属性的原始顶点位于线集的局部空间中,然后由ModelView矩阵转换为世界空间(并进一步转换为视图空间)。

    因此,如果您的线具有顶点(0,0)和(1,1),则线的枢轴点(其局部坐标系的原点)位于起点,而来自(-1,0)的线)到(1,0)的本地原点位于其中心点。它只取决于你的线的实际顶点。

  3. 但是,当然,如果所有这些对您来说都非常陌生,那么您应该深入研究一下OpenGL和计算机图形的基础知识。