简体   繁体   中英

OpenGL work shader?

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 to GL_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 types GL_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM