GLSL 在多个程序中使用相同的布局位置
GLSL using same layout locations with multiple programs
我可以使用以下代码使用多个程序进行渲染:
main.cpp
中主循环接近尾声的片段
. . .
glUseProgram( programID1 );
glEnableVertexAttribArray( 0 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[0] );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 20, (void*)0 );
//only needed XY coordinates for the simple 2D I'm making
glEnableVertexAttribArray( 1 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[0] );
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 20, (void*)8 );
//the third 'UV' coordinate chooses a tile from my 2d texture array
glDrawArrays( GL_TRIANGLES, 0, sizeof( vertuvbuffer0_data ) / 5 );
//every vertex takes 5 floats, so to get total number I divide by 5
glDisableVertexAttribArray( 0 );
glDisableVertexAttribArray( 1 );
glUseProgram( programID2 );
glEnableVertexAttribArray( 2 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[1] );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 20, (void*)0 );
glEnableVertexAttribArray( 3 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[1] );
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 20, (void*)8 );
glDrawArrays( GL_TRIANGLES, 0, sizeof( vertuvbuffer1_data ) / 5 );
...
glDisableVertexAttribArray( 2 );
glDisableVertexAttribArray( 3 );
. . .
这显然是在不同的着色器中使用单独的布局,我在尝试这样做时遇到了麻烦:
. . .
glUseProgram( programID1 );
glEnableVertexAttribArray( 0 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[0] );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 20, (void*)0 );
glEnableVertexAttribArray( 1 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[0] );
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 20, (void*)8 );
glDrawArrays( GL_TRIANGLES, 0, sizeof( vertuvbuffer0_data ) / 5 );
glDisableVertexAttribArray( 0 );
glDisableVertexAttribArray( 1 );
glUseProgram( programID2 );
glEnableVertexAttribArray( 0 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[1] );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 20, (void*)0 );
glEnableVertexAttribArray( 1 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[1] );
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 20, (void*)8 );
glDrawArrays( GL_TRIANGLES, 0, sizeof( vertuvbuffer1_data ) / 5 );
...
glDisableVertexAttribArray( 0 );
glDisableVertexAttribArray( 1 );
. . .
顶点着色器有各自的布局位置。
我不确定如何实现类似的东西,如果没有办法做到这一点,我将不得不为我想绘制的每个对象编写不同的顶点着色器,我无法想象那会是案例.
我希望这是有道理的,那么此时我可以做什么?
编辑:
在仔细研究了我的代码之后,我决定重写所有 ~500 行作为我的主程序的实际代码。它实在是太坏了,无法挽救,到处都是乱七八糟的评论,而且奇怪的行为对我来说根本没有用。我还选择使用 VAO 而不是直接使用 VBO 和 glVertexAttribPointer()
进行渲染,因为在我的代码混乱中,这实际上只适用于一个 VAO。现在我可以使用相同的 program/vertex 着色器渲染多个 VBO(以及几个 VAO),这是我想要的行为。
使用以下代码:
在着色器创建中链接程序之前:
glBindAttribLocation( ProgramID, 0, "in_Position" );
//0 being the lication in the shader and
//"in_Position" being the name inside the shader
在 "do while" 循环之前:
. . .
GLuint vao[2];
glGenVertexArrays( 2, vao );
glBindVertexArray( vao[0] );
GLfloat vbo0_data[] = {
// Positions
-1.0f, -1.0f,
1.0f, -1.0f,
0.0f, 1.0f
}
GLuint vbo[2];
glGenBuffers( 2, vbo );
glBindBuffer( GL_ARRAY_BUFFER, vbo[0] );
glBufferData( GL_ARRAY_BUFFER, sizeof( vbo0_data ), vbo0_data, GL_STATIC_DRAW );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 );
glEnableVertexAttribArray( 0 );
glBindVertexArray( vao[1] );
GLfloat vbo1_data[] = {
// Positions
-1.0f, 1.0f,
1.0f, 1.0f,
0.0f, -1.0f
}
glBindBuffer( GL_ARRAY_BUFFER, vbo[1] );
glBufferData( GL_ARRAY_BUFFER, sizeof( vbo1_data ), vbo1_data, GL_STATIC_DRAW );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 );
glEnableVertexAttribArray( 0 );
. . .
内部绘图循环:
. . .
glClear( GL_COLOR_BUFFER_BIT );
glUseProgram( ProgramID );
glBindVertexArrays( vao[0] );
glDrawArrays( GL_TRIANGLES, 0, 3 );
GlBindVertexArrays( vao[1] );
glDrawArrays( GL_TRIANGLES, 0, 3 );
. . .
pass-through 着色器只是写了一个半透明的红色,在三角形相交的地方变成了纯红色,我知道我可以把 VAO 放在一个循环中进行绘图,但这更像是一个概念证明来展示它对我有用。
现在是重写其余代码的繁琐部分...
我可以使用以下代码使用多个程序进行渲染:
main.cpp
. . .
glUseProgram( programID1 );
glEnableVertexAttribArray( 0 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[0] );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 20, (void*)0 );
//only needed XY coordinates for the simple 2D I'm making
glEnableVertexAttribArray( 1 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[0] );
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 20, (void*)8 );
//the third 'UV' coordinate chooses a tile from my 2d texture array
glDrawArrays( GL_TRIANGLES, 0, sizeof( vertuvbuffer0_data ) / 5 );
//every vertex takes 5 floats, so to get total number I divide by 5
glDisableVertexAttribArray( 0 );
glDisableVertexAttribArray( 1 );
glUseProgram( programID2 );
glEnableVertexAttribArray( 2 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[1] );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 20, (void*)0 );
glEnableVertexAttribArray( 3 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[1] );
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 20, (void*)8 );
glDrawArrays( GL_TRIANGLES, 0, sizeof( vertuvbuffer1_data ) / 5 );
...
glDisableVertexAttribArray( 2 );
glDisableVertexAttribArray( 3 );
. . .
这显然是在不同的着色器中使用单独的布局,我在尝试这样做时遇到了麻烦:
. . .
glUseProgram( programID1 );
glEnableVertexAttribArray( 0 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[0] );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 20, (void*)0 );
glEnableVertexAttribArray( 1 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[0] );
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 20, (void*)8 );
glDrawArrays( GL_TRIANGLES, 0, sizeof( vertuvbuffer0_data ) / 5 );
glDisableVertexAttribArray( 0 );
glDisableVertexAttribArray( 1 );
glUseProgram( programID2 );
glEnableVertexAttribArray( 0 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[1] );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 20, (void*)0 );
glEnableVertexAttribArray( 1 );
glBindBuffer( GL_ARRAY_BUFFER, vertuvbuffer[1] );
glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 20, (void*)8 );
glDrawArrays( GL_TRIANGLES, 0, sizeof( vertuvbuffer1_data ) / 5 );
...
glDisableVertexAttribArray( 0 );
glDisableVertexAttribArray( 1 );
. . .
顶点着色器有各自的布局位置。
我不确定如何实现类似的东西,如果没有办法做到这一点,我将不得不为我想绘制的每个对象编写不同的顶点着色器,我无法想象那会是案例.
我希望这是有道理的,那么此时我可以做什么?
编辑:
在仔细研究了我的代码之后,我决定重写所有 ~500 行作为我的主程序的实际代码。它实在是太坏了,无法挽救,到处都是乱七八糟的评论,而且奇怪的行为对我来说根本没有用。我还选择使用 VAO 而不是直接使用 VBO 和 glVertexAttribPointer()
进行渲染,因为在我的代码混乱中,这实际上只适用于一个 VAO。现在我可以使用相同的 program/vertex 着色器渲染多个 VBO(以及几个 VAO),这是我想要的行为。
使用以下代码:
在着色器创建中链接程序之前:
glBindAttribLocation( ProgramID, 0, "in_Position" );
//0 being the lication in the shader and
//"in_Position" being the name inside the shader
在 "do while" 循环之前:
. . .
GLuint vao[2];
glGenVertexArrays( 2, vao );
glBindVertexArray( vao[0] );
GLfloat vbo0_data[] = {
// Positions
-1.0f, -1.0f,
1.0f, -1.0f,
0.0f, 1.0f
}
GLuint vbo[2];
glGenBuffers( 2, vbo );
glBindBuffer( GL_ARRAY_BUFFER, vbo[0] );
glBufferData( GL_ARRAY_BUFFER, sizeof( vbo0_data ), vbo0_data, GL_STATIC_DRAW );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 );
glEnableVertexAttribArray( 0 );
glBindVertexArray( vao[1] );
GLfloat vbo1_data[] = {
// Positions
-1.0f, 1.0f,
1.0f, 1.0f,
0.0f, -1.0f
}
glBindBuffer( GL_ARRAY_BUFFER, vbo[1] );
glBufferData( GL_ARRAY_BUFFER, sizeof( vbo1_data ), vbo1_data, GL_STATIC_DRAW );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, (void*)0 );
glEnableVertexAttribArray( 0 );
. . .
内部绘图循环:
. . .
glClear( GL_COLOR_BUFFER_BIT );
glUseProgram( ProgramID );
glBindVertexArrays( vao[0] );
glDrawArrays( GL_TRIANGLES, 0, 3 );
GlBindVertexArrays( vao[1] );
glDrawArrays( GL_TRIANGLES, 0, 3 );
. . .
pass-through 着色器只是写了一个半透明的红色,在三角形相交的地方变成了纯红色,我知道我可以把 VAO 放在一个循环中进行绘图,但这更像是一个概念证明来展示它对我有用。
现在是重写其余代码的繁琐部分...