OpenGL 工作着色器?
OpenGL work shader?
有两个着色器,顶点和片段
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.
的顶点
请参阅 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. 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.
您必须将 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
是剪辑 space 坐标通过除以 w
分量转换为标准化设备坐标 (NDC)。在标准化设备 space 中,左下角位于 (-1.0, -1.0),右上角位于 (1.0, 1.0)。然后将标准化的设备坐标线性映射到 Window 坐标(由 glViewport
设置的视口)。
您必须设置一个投影矩阵,它将顶点坐标转换为剪辑 space(最后归一化设备 space)。
下面的例子设置了一个正交投影矩阵,投影屏幕space坐标,其中左上角为(0,0) 右下角是 (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 );
有两个着色器,顶点和片段
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.
的顶点请参阅 OpneGL ES glVertexAttribPointer
的 Khronos 组参考页面:
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.
您必须将 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
是剪辑 space 坐标通过除以 w
分量转换为标准化设备坐标 (NDC)。在标准化设备 space 中,左下角位于 (-1.0, -1.0),右上角位于 (1.0, 1.0)。然后将标准化的设备坐标线性映射到 Window 坐标(由 glViewport
设置的视口)。
您必须设置一个投影矩阵,它将顶点坐标转换为剪辑 space(最后归一化设备 space)。
下面的例子设置了一个正交投影矩阵,投影屏幕space坐标,其中左上角为(0,0) 右下角是 (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 );