【问题标题】:OpenGL work shader?OpenGL工作着色器?
【发布时间】:2018-07-26 13:17:56
【问题描述】:

有两个着色器,顶点和片段

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

问题是我没有浮点颜色,而是无符号字节。并在 int 中定位,而不是在 float 中。和 vec,就像我在花车里思考的那样。要将数据发送到管道,我使用此类命令。

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

字节中的像素。 int 的顶点。

【问题讨论】:

  • 您使用的是 C 还是 C++?
  • 我正在使用 c!!!!

标签: c opengl-es shader


【解决方案1】:

查看OpneGL ES glVertexAttribPointer 的 Khronos 组参考页面:

对于glVertexAttribPointer,如果 normalized 设置为GL_TRUE,则表示以整数格式存储的值将映射到范围 [-1,1](对于有符号值)或 [0,1] (对于无符号值)当它们被访问并转换为浮点时。否则,值将直接转换为浮点数而不进行规范化。

对于glVertexAttribIPointer,仅接受整数类型GL_BYTEGL_UNSIGNED_BYTEGL_SHORTGL_UNSIGNED_SHORTGL_INTGL_UNSIGNED_INT。值始终保留为整数值。

您必须将 RGB 颜色的颜色通道从 [0, 255] 范围转换为 [0.0, 1.0]。所以你必须使用:

// normalized = GL_TRUE: [0, 255] -> [0.0, 1.0]
glVertexAttribPointer( 0, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, pixels );

但是您想按原样使用顶点坐标,作为积分坐标。所以你必须使用glVertexAttribIPointer(关注I):

// glVertexAttribIPointer because of integer coordinates
glVertexAttribIPointer( 1, 2, GL_INT, 0, vertices );

顶点着色器中顶点属性的类型必须从vec2更改为ivec2,因为坐标的数据类型是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 );
}

进一步注意,gl_Position 是一个剪辑空间坐标,通过除以w 组件转换为标准化设备坐标 (NDC)。在标准化设备空间中,左下角位于 (-1.0, -1.0) 处,右上角位于 (1.0, 1.0) 处。然后将标准化的设备坐标线性映射到窗口坐标(由glViewport 设置的视口)。

您必须设置一个投影矩阵,它将顶点坐标转换为剪辑空间(最后是标准化的设备空间)。

下面的例子设置一个正交投影矩阵,投影屏幕空间坐标,其中左上角是(0,0),右下角是(@987654344 @,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 );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2015-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多