简体   繁体   English

OpenGL工作着色器?

[英]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. 并且位置int,而不是float。 And vec as I poned in the float. 和vec,就像我在浮标中浮出水面一样。 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. int的顶点。

See the Khronos group reference page for OpneGL ES glVertexAttribPointer : 有关OpneGL ES glVertexAttribPointer请参阅Khronos组参考页:

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. 对于glVertexAttribPointer ,如果将normalized设置为GL_TRUE ,则表示以整数格式存储的值在它们被映射到[-1,1](对于有符号值)或[0,1](对于无符号值)时会被映射。被访问并转换为浮点数。 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. 对于glVertexAttribIPointer ,仅接受整数类型GL_BYTEGL_UNSIGNED_BYTEGL_SHORTGL_UNSIGNED_SHORTGL_INTGL_UNSIGNED_INT 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]. 您必须将RGB颜色的颜色通道从[0,255]转换为[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 (关注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 : 类型在顶点着色器顶点attribue的必须从改变vec2ivec2因为坐标的数据类型是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. 还要注意, gl_Position是通过除以w分量而转换为归一化设备坐标(NDC)的剪辑空间坐标。 In normalized device space, the bottom left is at (-1.0, -1.0) and the top right at (1.0, 1.0). 在规范化的设备空间中,左下角为(-1.0,-1.0),右上角为(1.0,1.0)。 The normalized device coordinates are then linearly mapped to the Window Coordinates (viewport which is set by glViewport ). 然后将规范化的设备坐标线性映射到窗口坐标(由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 ): 下面的示例设置的正投影矩阵,突出屏幕空间坐标,其中左上角为(0,0)和右下侧( widthheight ):

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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