Scofield Tran
Scofield Tran

Reputation: 840

OpenGLES can not use input argument in vertex shader in iOS

I'm new on OpenGLES, I want to draw an image. I have a problem when using an input float variable in my shader file. My sample code here

--- The drawing code

//Loading image texture with name "texName"
//........

//get index attribute and uniform

**//Get index of flag**
GLuint a_ver_flag_drawing_type = glGetAttribLocation(program[PROGRAM_POINT].id, "a_drawingType");

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");

//Bind image texture with name "texName"
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_DYNAMIC_DRAW);

**//Set value for flag**
glVertexAttrib1f(a_ver_flag_drawing_type, 1.0f);

glVertexAttribPointer(a_position_location, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GL_FLOAT), (void*)(0));
glVertexAttribPointer(a_texture_coordinates_location, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GL_FLOAT), (void*)(2 * sizeof(GL_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];

--- My vertex shader file

//Flag
attribute float a_drawingType;
varying highp float v_drawing_type;

//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()
{
      v_drawing_type = a_drawingType;

//    if (fabs(a_drawingType - 1.0) < 0.00001) {
//        //Draw texture
           //v_TextureCoordinates = a_TextureCoordinates;
           //gl_Position = a_Position;
//    } else {
           //Draw some other stuff
//    }

    //Draw texture
    v_TextureCoordinates = a_TextureCoordinates;
    gl_Position = a_Position;
}

--- My fragment shader file

precision mediump float;

uniform sampler2D texture;
varying lowp vec4 color;

uniform sampler2D u_TextureUnit;
varying vec2 v_TextureCoordinates;

varying highp float v_drawing_type;

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

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

If just these code, I can draw my desired image. But if I uncomment the if statement code on vertex shader file

if (fabs(a_drawingType - 1.0) < 0.00001) {
      //Draw texture
     v_TextureCoordinates = a_TextureCoordinates;
     gl_Position = a_Position;
} else {
     //Draw some other stuff
}

the image is not rendered on screen anymore. I really don't know why it is. I want this flag to modify my drawing. If a_drawing_type is 1.0, I will draw image, else I will draw somethings else. I debug my drawing code and see if I uncomment this if statement, I can get indexes of these attribute at these lines

**//Get index of flag**
GLuint a_ver_flag_drawing_type = glGetAttribLocation(program[PROGRAM_POINT].id, "a_drawingType");

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");

but if I comment the if statement, debug again and see that these indexes will have value 4294967295, I think it's max int value when it can't get the indexes.

Can anyone figure out for me what is the problem with if statement, I totally spent 2 days for this issue.

UPDATED: I fixed above problem based on @Anonymous answer, but I have another issue related to it: I want to pass the value of a_drawingType on vertex shader to the variable v_drawing_type in fragment shader, so the line of code

v_drawing_type = a_drawingType;

on vertex shader is right, isn't it? but now in fragment shader file, I add an if statement to check the value of the v_drawing_type

if (abs(v_drawing_type - 1.0) < 0.0001) {

}

it will also raise crash problem at line

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

Do I still miss somethings or I'm doing wrong

Upvotes: 0

Views: 168

Answers (1)

Anonymous
Anonymous

Reputation: 2172

Well, let's start from correcting sizeof(). There are plenty of places in your code using sizeof incorrectly:

sizeof(GL_FLOAT)

GL_FLOAT is enum (not float), you should rather use sizeof(GLfloat) or sizeof(float) I belive it is fine on iOS, because sizeof(int) in fact is equal to sizeof(float), however it is mistake.

Second, more importand thing is your fabs() call. First of all it should be abs() not fabs(). Also why there are 2 arguments? As far as I know abs() takes only 1 argument. I am pretty sure these things are reason of your headake, your shader cannot be compiled, so you don't get your image on screen.

Upvotes: 3

Related Questions