There are two shaders, vertex and fragment
const char *vShaderstr =
"#version 300 es\n"
"layout(location = 0) in vec4 a_color;\n"
"layout(location = 1) in vec2 a_position;\n"
"out vec4 v_color;\n"
"void main()\n"
"{\n"
" v_color = a_color;\n"
" gl_Position.xy = a_position;\n"
" gl_Position.z = 0.0;\n"
" gl_Position.w = 1.0;\n"
"}";
const char *fShaderstr =
"#version 300 es\n"
"precision lowp float;\n"
"in vec4 v_color;\n"
"out vec4 o_fragColor;\n"
"void main()\n"
"{\n"
" o_fragColor = v_color;\n"
"}";
The problem is that I do not have colors in float, but in bytes of unsigned ones. And positions in int, instead of in float. And vec as I poned in the float. To send data to the pipeline I use such commands.
glVertexAttribPointer ( 0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, pixels );
glVertexAttribPointer ( 1, 2, GL_INT, GL_FALSE, 0, vertices );
glEnableVertexAttribArray ( 0 );
glEnableVertexAttribArray ( 1 );
glDrawArrays ( GL_POINTS, 0, max_draw );
pixels from bytes. vertices of int.
See the Khronos group reference page for OpneGL ES glVertexAttribPointer
:
For
glVertexAttribPointer
, if normalized is set toGL_TRUE
, it indicates that values stored in an integer format are to be mapped to the range [-1,1] (for signed values) or [0,1] (for unsigned values) when they are accessed and converted to floating point. Otherwise, values will be converted to floats directly without normalization.For
glVertexAttribIPointer
, only the integer typesGL_BYTE
,GL_UNSIGNED_BYTE
,GL_SHORT
,GL_UNSIGNED_SHORT
,GL_INT
,GL_UNSIGNED_INT
are accepted. Values are always left as integer values.
You have to convert the color channels of the RGB colors form the range [0, 255] to [0.0, 1.0]. So you have to use:
// normalized = GL_TRUE: [0, 255] -> [0.0, 1.0]
glVertexAttribPointer( 0, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, pixels );
But you want to use vertex coordinates as they are, as integral coordinates. So you have tou use glVertexAttribIPointer
(focus on the I
):
// glVertexAttribIPointer because of integer coordinates
glVertexAttribIPointer( 1, 2, GL_INT, 0, vertices );
The type of the vertex attribue in the vertex shader has to be changed from vec2
to ivec2
because the data type of the coordinates is GL_INT
:
#version 300 es
layout(location = 0) in vec4 a_color;
layout(location = 1) in ivec2 a_position; // <---- ivec2
out vec4 v_color;
uniform mat4 u_projection;
void main()
{
v_color = a_color;
vec2 p = vec2(a_position); // <---- convert from int to float
gl_Position = u_projection * vec4( p.xy, 0.0, 1.0 );
}
Further note, that gl_Position
is a clip space coordinate transformed to the normalized device coordinates (NDC) by dividing with the w
component. In normalized device space, the bottom left is at (-1.0, -1.0) and the top right at (1.0, 1.0). The normalized device coordinates are then linearly mapped to the Window Coordinates (viewport which is set by glViewport
).
You have to setup a projection matrix, which transforms the vertex coordinates to the clip space (and finally normalized device space).
The following example sets an orthographic projection matrix, which projects screen space coordinates, where the upper left is ( 0 , 0 ) and the bottom right is ( width
, height
):
GLuint shader_prog = .... ; // shader program object
float width = .... ; // viewport width in pixel
float height = .... ; // viewport height in pixel
float prj_mat[] =
{
2.0f/width, 0.0f, 0.0f, 0.0f,
0.0f, -2.0f/height, 0.0f, 0.0f,
0.0f, 0.0f, -1.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 1.0f
};
glLinkProgram( shader_prog );
GLint prj_loc = glGetUniformLocation( shader_prog, "u_projection" );
glUseProgram( shader_prog );
glUniformMatrix4fv( prj_loc, 1, GL_FALSE, prj_mat );
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.