Search code examples
opengl-es-2.0opengl-4

What is differences between glVertexAttribPointer and glVertexAttrib1f


In opengl es 2.0 when I wanted to change the attribute named "a_degree" in vertex shader at first I used glVertexAttribPointer and glEnableVertexAttribArray with true parameters but the behaviour is totally different when I used glVertexAttrib1f why?

here is my shaders code:

const char* CGraphic::VERTEX_SHADER_SOURCE =
"attribute vec4 a_position;     \n"
"attribute vec2 a_texCoord;     \n"
"attribute vec4 a_color;        \n"
"attribute float a_degree;      \n"
"varying lowp vec4 v_color;     \n"
"varying vec2 v_texCoord;       \n"
"void main()                    \n"
"{                              \n"
"   float radianS = a_degree*   "
"   (3.14159265/180.0);         \n"
"   float s = sin(radianS);     \n"
"   float c = cos(radianS);     \n"
"   mat4 mvpMatrix=mat4(        \n"
"       c,-s,0,0,               "
"       s,c,0,0,                "
"       0,0,1,0,                "
"       0,0,0,1);             \n"
"   v_color = a_color;        \n"
"   gl_Position = a_position*mvpMatrix; \n"
"   v_texCoord = a_texCoord;  \n"
"}                            \n";

const char* CGraphic::FRAGMENT_SHADER_SOURCE =
"precision mediump float;     \n"
"                             \n"
"varying vec4 vColor;         \n"
"varying vec2 v_texCoord;     \n"
"uniform sampler2D s_texture; \n"
"                             \n"
"void main()                  \n"
"{                            \n"
"  gl_FragColor = texture2D( s_texture, v_texCoord );\n"
"}                            \n";

use with:

glEnableVertexAttribArray ( m_shaderData.rotateLoc );
glVertexAttribPointer ( m_shaderData.rotateLoc, 1, GL_FLOAT,
                            GL_FALSE, 0, &degree );

vs

glVertexAttrib1f(m_shaderData.rotateLoc,degree);

In fact glVertexAttrib1f work fine in this situation and my texture rotate correctly but with glVertexAttribPointer just one point of the texture rotate that isn't my desire.


Solution

  • glVertexAttrib allows you to specify a fixed value for the attribute.

    In contrast, glVertexAttribPointer when enabled via glEnableVertexAttribArray allows you to specify a unique value for each vertex.

    Read more here: https://www.khronos.org/opengles/sdk/docs/man/xhtml/glVertexAttrib.xml https://www.khronos.org/opengles/sdk/docs/man/xhtml/glVertexAttribPointer.xml

    So, if you are drawing a triangle with multiple points, you would need to specify a separate degree for each point when using glVertexAttribPointer. Thus, degree would need to be a float[], while it looks like you're only specifying a single value right now as a float.

    Most likely the values after degree in memory are zeros, which is why the other points are not rotating.

    If you want the value to be the same, you CAN use glVertexAttrib. If you're never going to specify it per vertex, using a uniform value is likely better.