本文介绍了OpenGL ES glFragColor取决于iOS中Fragment Shader的条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在iOS上编写一个应用程序,该应用程序可以绘制自由样式(使用手指)并在屏幕上绘制图像.我使用OpenGL ES来实现.我有2个功能,一个是自由绘制样式,一个是绘制纹理

I'm writing an app on iOS allows drawing free style (using finger) and drawing image on screen. I use OpenGL ES to implement. I have 2 functions, one is drawing free style, one is drawing texture

-代码自由绘制样式

- (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];
}

-代码绘图纹理

- (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(统一).它们用于在顶点着色器和片段着色器上设置标志,以确定两个文件上的自由绘制样式或纹理

Notice 2 variables a_ver_flag_drawing_type (attribute) and u_fra_flag_drawing_type (uniform). They're use for setting flags on vertex shader and fragment shader to determine drawing free style or texture on both files

-顶点着色器

//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;
    }

}

-片段着色器

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用于顶点着色器,而Uniform v_drawing_type用于片段着色器.依靠这些标志可以知道绘制自由样式或纹理的方式.

My idea is setting these flags from drawing code at drawing time. Attribute a_drawingType is used for vertex shader and Uniform v_drawing_type is used for fragment shader. Depending these flags to know draw free style or texture.

但是,如果我独立运行,每次只有一种类型(如果运行自由绘图样式,在顶点着色器和片段着色器文件上注释代码配置绘图纹理,反之亦然),则可以根据需要进行绘制.如果将它们组合在一起,它不仅无法绘制,而且会使应用崩溃

But if I run independently, each time just one type (if run drawing free style, comment code config drawing texture on vertex shader and fragment shader file and vice versa) it can draw as I want. If I combine them, it not only can't draw but also makes app crash as

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

我是OpenGL ES和GLSL语言的新手,所以我不确定要设置这样的标志是对还是错.谁能帮我

I'm new for OpenGL ES and GLSL language, so I'm not sure my thinking about setting flags like that is right or wrong. Can anyone help me

推荐答案

那么,为什么不构建2个单独的着色器程序并在其中一个上使用useProgram(),而不是将标志值发送给GL并进行昂贵的条件分支在顶点,尤其是片段着色器中?

So why don't you just build 2 seperate shader programs and useProgram() on one of them, instead of sending flag values to GL and making expensive conditional branch in vertex and especially fragment shader?

这篇关于OpenGL ES glFragColor取决于iOS中Fragment Shader的条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-21 08:03