首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >OpenGL ES glFragColor依赖于iOS中片段着色器上的if条件

OpenGL ES glFragColor依赖于iOS中片段着色器上的if条件
EN

Stack Overflow用户
提问于 2014-12-16 09:32:04
回答 4查看 1.9K关注 0票数 0

我正在写一个应用程序在iOS上允许绘制自由风格(使用手指)和在屏幕上绘制图像。我使用OpenGL ES来实现。我有两个功能,一个是绘制自由样式,一个是绘制纹理

-代码绘制自由样式

代码语言:javascript
运行
复制
- (void)drawFreeStyle:(NSMutableArray *)pointArray {

        //Prepare vertex data
        .....

        // Load data to the Vertex Buffer Object
        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);

        **GLuint a_ver_flag_drawing_type = glGetAttribLocation(program[PROGRAM_POINT].id, "a_drawingType");
        glVertexAttrib1f(a_ver_flag_drawing_type, 0.0f);

        GLuint u_fra_flag_drawing_type = glGetUniformLocation(program[PROGRAM_POINT].id, "v_drawing_type");
        glUniform1f(u_fra_flag_drawing_type, 0.0);**

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

        // Display the buffer
        glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
        [context presentRenderbuffer:GL_RENDERBUFFER];
}

-代码绘制纹理

代码语言:javascript
运行
复制
- (void)drawTexture:(UIImage *)image atRect:(CGRect)rect {

    GLuint a_ver_flag_drawing_type = glGetAttribLocation(program[PROGRAM_POINT].id, "a_drawingType");

    GLuint u_fra_flag_drawing_type = glGetUniformLocation(program[PROGRAM_POINT].id, "v_drawing_type");

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

    glUseProgram(PROGRAM_POINT);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texName);
    glUniform1i(u_texture_unit_location, 0);
    glUniform1f(u_fra_flag_drawing_type, 1.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);
    glBufferData(GL_ARRAY_BUFFER, sizeof(textrect), textrect, GL_STATIC_DRAW);

    glVertexAttrib1f(a_ver_flag_drawing_type, 1.0f);

    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_ver_flag_drawing_type);
    glEnableVertexAttribArray(a_position_location);
    glEnableVertexAttribArray(a_texture_coordinates_location);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER];
}

请注意2个变量a_ver_flag_drawing_type (属性)和u_fra_flag_drawing_type (统一)。它们用于在顶点着色器和片段着色器上设置标志,以确定这两个文件上无绘制样式或纹理

-顶点着色器

代码语言:javascript
运行
复制
//Flag
attribute lowp float a_drawingType;

//For drawing
attribute vec4 inVertex;

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

varying lowp vec4 color;

//For texture
attribute vec4 a_Position;
attribute vec2 a_TextureCoordinates;

varying vec2 v_TextureCoordinates;

void main()
{
    if (abs(a_drawingType - 1.0) < 0.0001) {
        //Draw texture        
        v_TextureCoordinates = a_TextureCoordinates;
        gl_Position = a_Position;
    } else {
        //Draw free style
        gl_Position = MVP * inVertex;
        gl_PointSize = pointSize;
        color = vertexColor;
    }

}

-片段着色器

代码语言:javascript
运行
复制
precision mediump float;

uniform sampler2D texture;
varying lowp vec4 color;

uniform sampler2D u_TextureUnit;
varying vec2 v_TextureCoordinates;

uniform lowp float v_drawing_type;

void main()
{
    if (abs(v_drawing_type - 1.0) < 0.0001) {
        //Draw texture
        gl_FragColor = texture2D(u_TextureUnit, v_TextureCoordinates);
    } else {
        //Drawing free style
        gl_FragColor = color * texture2D(texture, gl_PointCoord);
    }

}

我的想法是在绘制时从绘制代码中设置这些标志。属性a_drawingType用于顶点着色器,一致v_drawing_type用于片段着色器。根据这些标志来知道绘制自由样式或纹理。

但如果我独立运行,每次只有一种类型(如果运行自由绘制样式,注释代码配置顶点着色器和片段着色器文件上的绘制纹理,反之亦然)它可以像我想要的那样绘制。如果我将它们组合在一起,它不仅不能绘制,还会使应用程序崩溃,因为

代码语言:javascript
运行
复制
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

我是OpenGL ES和GLSL语言的新手,所以我不确定我这样设置标志的想法是对还是错。有人能帮我吗?

EN

Stack Overflow用户

发布于 2014-12-17 05:16:41

所以你为什么不在其中的一个上构建两个独立的着色器程序和useProgram(),而不是将标志值发送到GL,并在顶点中进行昂贵的条件分支,特别是片段着色器?

票数 2
EN
查看全部 4 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27496144

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档