在iOS上的OpenGLES上绘制冲突

时间:2014-12-17 21:35:58

标签: ios opengl-es shader texture2d

我正在编写一个应用程序,允许绘制自由风格(使用手指)和绘图图像。我在OpenGL ES glFragColor depend on if condition on Fragment shader in iOS发布了我的一个问题。感谢许多建议,我解决了这个问题。现在我还有另一个新问题。

我有2个程序,其ID为PROGRAM_POINT(绘图自由风格)和PROGRAM_POINT_0(绘制图像)。这些都是初始化的。每个程序都有一对着色器文件。 PROGRAM_POINT具有名为point.vsh和point.fsh的着色器文件。对于PROGRAM_POINT_0是texture.vsh和texture.fsh。

以下是这些文件

---- point.vsh ------

attribute vec4 inVertex;

uniform mat4 MVP;
uniform float pointSize;
uniform lowp vec4 vertexColor;

varying lowp vec4 color;

void main()
{
    gl_Position = MVP * inVertex;
    gl_PointSize = pointSize;
    color = vertexColor;
}

---- point.fsh -------

precision mediump float;

uniform sampler2D texture;
varying lowp vec4 color;

void main()
{
    //Drawing point
    gl_FragColor = color * texture2D(texture, gl_PointCoord);
}

---- texture.vsh --------

attribute vec4 a_Position;
attribute vec2 a_TextureCoordinates;

varying vec2 v_TextureCoordinates;

void main()
{
    v_TextureCoordinates = a_TextureCoordinates;
    gl_Position = a_Position;
}

---- texture.fsh ------

precision mediump float;

uniform sampler2D u_TextureUnit;
varying vec2 v_TextureCoordinates;

void main()
{
    //Draw texture
    gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);
}

此外,这里是绘图自由风格和图像

---绘制自由风格-----

    glBindBuffer(GL_ARRAY_BUFFER, vboId);
    glBufferData(GL_ARRAY_BUFFER, vertexCount*2*sizeof(GLfloat), vertexBuffer, GL_DYNAMIC_DRAW);

    glEnableVertexAttribArray(ATTRIB_VERTEX);
    glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, GL_FALSE, 0, 0);

    // the brush texture will be bound to texture unit 0
    glUniform1i(program[PROGRAM_POINT].uniform[UNIFORM_TEXTURE], 0);

    glUseProgram(program[PROGRAM_POINT].id);
    glDrawArrays(GL_POINTS, 0, (int)vertexCount);

---绘制图像-----

    GLuint a_position_location = glGetAttribLocation(program[PROGRAM_POINT_0].id, "a_Position");
    GLuint a_texture_coordinates_location = glGetAttribLocation(program[PROGRAM_POINT_0].id, "a_TextureCoordinates");
    GLuint u_texture_unit_location = glGetUniformLocation(program[PROGRAM_POINT_0].id, "u_TextureUnit");

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texName);
    glUniform1i(u_texture_unit_location, 0);

    const float textrect[] = {-1.0f, -1.0f, 0.0f, 0.0f,
        -1.0f,  1.0f, 0.0f, 1.0f,
        1.0f, -1.0f, 1.0f, 0.0f,
        1.0f,  1.0f, 1.0f, 1.0f};

    glBindBuffer(GL_ARRAY_BUFFER, vboId_1);
    glBufferData(GL_ARRAY_BUFFER, sizeof(textrect), textrect, GL_STATIC_DRAW);

    glVertexAttribPointer(a_position_location, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(0));
    glVertexAttribPointer(a_texture_coordinates_location, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));

    glEnableVertexAttribArray(a_position_location);
    glEnableVertexAttribArray(a_texture_coordinates_location);

    glUseProgram(program[PROGRAM_POINT_0].id);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    [context presentRenderbuffer:GL_RENDERBUFFER];

现在如果我执行以下步骤就会出现问题:

  • 绘制自由风格(仍然很好)

Still fine

  • 绘制图像(仍然很好)

Still fine

  • 再次绘制自由风格(问题发生!!!)

PROBLEM !!!

3号和4号的颜色改变了,看起来很糟糕。我想在绘制图像后它会合并或冲突。绘制图像后是否需要清除缓冲区

2 个答案:

答案 0 :(得分:2)

point.fsh片段着色器使用纹理,但是你的"绘制自由风格" GL代码没有glBindTexture。所以它将使用最后一个glBindTexture-ed纹理。

此外,"绘制自由风格"启用一个顶点属性数组。

glEnableVertexAttribArray(ATTRIB_VERTEX)

然而"绘制图像"启用两个属性数组。

glEnableVertexAttribArray(a_position_location);
glEnableVertexAttribArray(a_texture_coordinates_location);

你应该在另一个glDrawArrays之前调用glDisableVertexAttribArray。

或者您可以使用VAO。请查看the Apple Document

答案 1 :(得分:0)

我找到了解决方案,只需在绘制图像后重新绑定画笔纹理(绘制自由样式的纹理)。绘图图像将另一个纹理绑定到缓冲区,然后继续绘制自由样式,因为openGLES仍然使用以前的绑定纹理,在这种情况下是图像。