着色器不呈现 window
Shader does not render to window
我有两种方法的测试代码。第一个使用单个 VBO,顶点和纹理坐标交织在一起,在 window 上绘制一个正方形。第二个使用三个 VBO 的数组来定义顶点、纹理坐标和颜色值。
第一种方法成功地在 window 的中心呈现了一个黑色方块。第二种方法不渲染任何东西。我开始使用 RenderDoc 进行故障排除,发现在“网格查看器”选项卡下,第一个方法的 glDrawArrays()
调用列出了顶点和纹理坐标。当检查来自第二种方法的 glDrawArrays()
调用时,所有传递的值都是 0.
任何人都可以向我解释为什么会发生这种情况以及如何解决它吗?
第一种方法:
public static void GenDrawQuad() {
int quadVAO = 0;
int quadVBO = 0;
float vertices[] = {
// Positions Texcoords
-0.5f, 0.5f, 0.0f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.0f, -0.5f,-0.5f,
0.5f, 0.5f, 0.0f, 0.5f, 1.5f,
0.5f, -0.5f, 0.0f, 0.5f,-0.5f,
};
// Gen VAO to contain VBO
quadVAO = glGenVertexArrays();
glBindVertexArray(quadVAO);
// Gen and fill vertex buffer (VBO)
quadVBO = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
// Bind vertex attributes (position, texcoords)
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 5*Float.BYTES,0); //Positions
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, false, 5*Float.BYTES,3*Float.BYTES); //Texcoords
// Draw quad
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
// Delete buffers (VBO and VAO)
glDeleteBuffers(quadVBO);
glDeleteVertexArrays(quadVAO);
}
第一种方法的RenderDoc:
第二种方法:
public static void GenDrawQuadAlt() {
int quadVAO = 0;
int[] quadVBO = {0, 0, 0};
Shader shaderProgram = GetShaderDefault();
float vertices[] = {
// Positions
-0.5f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
float[] texcoords = {
0.5f, -0.5f,
-0.5f, -0.5f,
0.5f, 0.5f,
0.5f, -0.5f
};
float[] colour = {
255, 109, 154, 255,
255, 109, 154, 255,
255, 109, 154, 255,
255, 109, 154, 255
};
// Gen VAO to contain VBO
quadVAO = glGenVertexArrays();
glBindVertexArray(quadVAO);
// Gen and fill vertex buffer (VBO)
quadVBO[0] = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[0]);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
quadVBO[1] = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[1]);
glBufferData(GL_ARRAY_BUFFER, texcoords, GL_STATIC_DRAW);
quadVBO[2] = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[2]);
glBufferData(GL_ARRAY_BUFFER, colour, GL_STATIC_DRAW);
// Bind vertex attributes (position, texcoords)
glEnableVertexAttribArray(shaderProgram.getLocs().get(LOC_VERTEX_POSITION.ShaderLocationInt));
glVertexAttribPointer(shaderProgram.getLocs().get(LOC_VERTEX_POSITION.ShaderLocationInt), 3, GL_FLOAT,
false, 0,0); //Positions
glEnableVertexAttribArray(shaderProgram.getLocs().get(LOC_VERTEX_TEXCOORD01.ShaderLocationInt));
glVertexAttribPointer(shaderProgram.getLocs().get(LOC_VERTEX_TEXCOORD01.ShaderLocationInt), 2, GL_FLOAT,
false, 0,0); //Texcoords
glEnableVertexAttribArray(shaderProgram.getLocs().get(LOC_VERTEX_COLOR.ShaderLocationInt));
glVertexAttribPointer(shaderProgram.getLocs().get(LOC_VERTEX_COLOR.ShaderLocationInt), 4, GL_FLOAT,
false, 0, 0); //Colours
// Draw quad
glUseProgram(shaderProgram.getId());
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
glUseProgram(0);
// Delete buffers (VBO and VAO)
glDeleteBuffers(quadVBO);
glDeleteVertexArrays(quadVAO);
}
第二种方法的RenderDoc:
::编辑::
经过一些修改后,我现在有了以下方法,它将值放在我的着色器的预期位置并给我一个 gl_Position 输出,但不渲染到屏幕。
public static void GenDrawQuadAlt() {
int quadVAO = 0;
int[] quadVBO = {0, 0, 0, 0};
Shader shaderProgram = rlglData.getState().getCurrentShader();
float vertices[] = {
-0.5f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
float[] texcoords = {
0.5f, -0.5f,
-0.5f, -0.5f,
0.5f, 0.5f,
0.5f, -0.5f
};
float[] colour = {
255, 109, 154, 255,
255, 109, 154, 255,
255, 109, 154, 255,
255, 109, 154, 255
};
int[] indices = {
0, 1, 2,
0, 2, 3
};
// Gen VAO to contain VBO
quadVAO = glGenVertexArrays();
glBindVertexArray(quadVAO);
// Gen and fill vertex buffer (VBO)
quadVBO[0] = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[0]);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT,
false, 0,0); //Positions
glEnableVertexAttribArray(0);
quadVBO[1] = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[1]);
glBufferData(GL_ARRAY_BUFFER, texcoords, GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT,
false, 0,0); //Texcoords
glEnableVertexAttribArray(1);
quadVBO[2] = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[2]);
glBufferData(GL_ARRAY_BUFFER, colour, GL_STATIC_DRAW);
glVertexAttribPointer(3, 4, GL_FLOAT,
false, 0, 0); //Colours
glEnableVertexAttribArray(3);
quadVBO[3] = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[3]);
glBufferData(GL_ARRAY_BUFFER, indices, GL_STATIC_DRAW);
// Draw quad
glUseProgram(shaderProgram.getId());
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.length/3);
glBindVertexArray(0);
glUseProgram(0);
// Delete buffers (VBO and VAO)
glDeleteBuffers(quadVBO);
glDeleteVertexArrays(quadVAO);
}
我的顶点着色器:
#version 330
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec4 vertexColor;
out vec2 fragTexCoord;
out vec4 fragColor;
uniform mat4 mvp;
void main()
{
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;
gl_Position = vec4(vertexPosition.x, vertexPosition.y, vertexPosition.z, 1.0);
}
我的片段着色器:
#version 330
in vec2 fragTexCoord;
in vec4 fragColor;
out vec4 finalColor;
uniform sampler2D texture0;
uniform vec4 colDiffuse;
void main()
{
vec4 texelColor = texture(texture0, fragTexCoord);
finalColor = texelColor*colDiffuse*fragColor;
}
您正在将位置、uv、颜色缓冲到三个不同的缓冲区,所有缓冲区都指向 GL_ARRAY_BUFFER
目标。您一次只能 draw/interact 一个目标 + 缓冲区组合。此外,您还缺少 glVertexAttribpointer
中的正确步幅
您需要像处理第一个顶点数据那样合并您的顶点数据:
float vertices[] = {
// Positions Texcoords color
-0.5f, 0.5f, 0.0f, -0.5f, 0.5f, 255, 109, 154, 255,
然后在这里使用正确的步幅:
glVertexAttribPointer(0, 3, GL_FLOAT, false, 9*Float.BYTES, 0); // positions
glVertexAttribPointer(1, 2, GL_FLOAT, false, 9*Float.BYTES, 3*Float.BYTES); // texcoords
glVertexAttribPointer(2, 4, GL_FLOAT, false, 9*Float.BYTES, 5*Float.BYTES); // color
glVertexAttribPointer
将实际绑定到 GL_ARRAY_BUFFER
目标的缓冲区对象与属性相关联。您必须在调用 glVertexAttribPointer
:
之前绑定缓冲区对象
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[0]);
glVertexAttribPointer(shaderProgram.getLocs().get(LOC_VERTEX_POSITION.ShaderLocationInt), 3, GL_FLOAT,
false, 0,0); //Positions
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[1]);
glVertexAttribPointer(shaderProgram.getLocs().get(LOC_VERTEX_TEXCOORD01.ShaderLocationInt), 2, GL_FLOAT,
false, 0,0); //Texcoords
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[3]);
glVertexAttribPointer(shaderProgram.getLocs().get(LOC_VERTEX_COLOR.ShaderLocationInt), 4, GL_FLOAT,
false, 0, 0); //Colours
在使用 glGetUniformLocation()
设置着色器属性后,我发现由于着色器构造函数中的错误,未定义着色器位置值。一旦我纠正了这个错误,我的四边形就被绘制到了屏幕上。
感谢所有的帮助和输入!
我有两种方法的测试代码。第一个使用单个 VBO,顶点和纹理坐标交织在一起,在 window 上绘制一个正方形。第二个使用三个 VBO 的数组来定义顶点、纹理坐标和颜色值。
第一种方法成功地在 window 的中心呈现了一个黑色方块。第二种方法不渲染任何东西。我开始使用 RenderDoc 进行故障排除,发现在“网格查看器”选项卡下,第一个方法的 glDrawArrays()
调用列出了顶点和纹理坐标。当检查来自第二种方法的 glDrawArrays()
调用时,所有传递的值都是 0.
任何人都可以向我解释为什么会发生这种情况以及如何解决它吗?
第一种方法:
public static void GenDrawQuad() {
int quadVAO = 0;
int quadVBO = 0;
float vertices[] = {
// Positions Texcoords
-0.5f, 0.5f, 0.0f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.0f, -0.5f,-0.5f,
0.5f, 0.5f, 0.0f, 0.5f, 1.5f,
0.5f, -0.5f, 0.0f, 0.5f,-0.5f,
};
// Gen VAO to contain VBO
quadVAO = glGenVertexArrays();
glBindVertexArray(quadVAO);
// Gen and fill vertex buffer (VBO)
quadVBO = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
// Bind vertex attributes (position, texcoords)
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 5*Float.BYTES,0); //Positions
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, false, 5*Float.BYTES,3*Float.BYTES); //Texcoords
// Draw quad
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
// Delete buffers (VBO and VAO)
glDeleteBuffers(quadVBO);
glDeleteVertexArrays(quadVAO);
}
第一种方法的RenderDoc:
第二种方法:
public static void GenDrawQuadAlt() {
int quadVAO = 0;
int[] quadVBO = {0, 0, 0};
Shader shaderProgram = GetShaderDefault();
float vertices[] = {
// Positions
-0.5f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
float[] texcoords = {
0.5f, -0.5f,
-0.5f, -0.5f,
0.5f, 0.5f,
0.5f, -0.5f
};
float[] colour = {
255, 109, 154, 255,
255, 109, 154, 255,
255, 109, 154, 255,
255, 109, 154, 255
};
// Gen VAO to contain VBO
quadVAO = glGenVertexArrays();
glBindVertexArray(quadVAO);
// Gen and fill vertex buffer (VBO)
quadVBO[0] = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[0]);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
quadVBO[1] = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[1]);
glBufferData(GL_ARRAY_BUFFER, texcoords, GL_STATIC_DRAW);
quadVBO[2] = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[2]);
glBufferData(GL_ARRAY_BUFFER, colour, GL_STATIC_DRAW);
// Bind vertex attributes (position, texcoords)
glEnableVertexAttribArray(shaderProgram.getLocs().get(LOC_VERTEX_POSITION.ShaderLocationInt));
glVertexAttribPointer(shaderProgram.getLocs().get(LOC_VERTEX_POSITION.ShaderLocationInt), 3, GL_FLOAT,
false, 0,0); //Positions
glEnableVertexAttribArray(shaderProgram.getLocs().get(LOC_VERTEX_TEXCOORD01.ShaderLocationInt));
glVertexAttribPointer(shaderProgram.getLocs().get(LOC_VERTEX_TEXCOORD01.ShaderLocationInt), 2, GL_FLOAT,
false, 0,0); //Texcoords
glEnableVertexAttribArray(shaderProgram.getLocs().get(LOC_VERTEX_COLOR.ShaderLocationInt));
glVertexAttribPointer(shaderProgram.getLocs().get(LOC_VERTEX_COLOR.ShaderLocationInt), 4, GL_FLOAT,
false, 0, 0); //Colours
// Draw quad
glUseProgram(shaderProgram.getId());
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindVertexArray(0);
glUseProgram(0);
// Delete buffers (VBO and VAO)
glDeleteBuffers(quadVBO);
glDeleteVertexArrays(quadVAO);
}
第二种方法的RenderDoc:
::编辑::
经过一些修改后,我现在有了以下方法,它将值放在我的着色器的预期位置并给我一个 gl_Position 输出,但不渲染到屏幕。
public static void GenDrawQuadAlt() {
int quadVAO = 0;
int[] quadVBO = {0, 0, 0, 0};
Shader shaderProgram = rlglData.getState().getCurrentShader();
float vertices[] = {
-0.5f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
float[] texcoords = {
0.5f, -0.5f,
-0.5f, -0.5f,
0.5f, 0.5f,
0.5f, -0.5f
};
float[] colour = {
255, 109, 154, 255,
255, 109, 154, 255,
255, 109, 154, 255,
255, 109, 154, 255
};
int[] indices = {
0, 1, 2,
0, 2, 3
};
// Gen VAO to contain VBO
quadVAO = glGenVertexArrays();
glBindVertexArray(quadVAO);
// Gen and fill vertex buffer (VBO)
quadVBO[0] = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[0]);
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT,
false, 0,0); //Positions
glEnableVertexAttribArray(0);
quadVBO[1] = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[1]);
glBufferData(GL_ARRAY_BUFFER, texcoords, GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT,
false, 0,0); //Texcoords
glEnableVertexAttribArray(1);
quadVBO[2] = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[2]);
glBufferData(GL_ARRAY_BUFFER, colour, GL_STATIC_DRAW);
glVertexAttribPointer(3, 4, GL_FLOAT,
false, 0, 0); //Colours
glEnableVertexAttribArray(3);
quadVBO[3] = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[3]);
glBufferData(GL_ARRAY_BUFFER, indices, GL_STATIC_DRAW);
// Draw quad
glUseProgram(shaderProgram.getId());
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.length/3);
glBindVertexArray(0);
glUseProgram(0);
// Delete buffers (VBO and VAO)
glDeleteBuffers(quadVBO);
glDeleteVertexArrays(quadVAO);
}
我的顶点着色器:
#version 330
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec4 vertexColor;
out vec2 fragTexCoord;
out vec4 fragColor;
uniform mat4 mvp;
void main()
{
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;
gl_Position = vec4(vertexPosition.x, vertexPosition.y, vertexPosition.z, 1.0);
}
我的片段着色器:
#version 330
in vec2 fragTexCoord;
in vec4 fragColor;
out vec4 finalColor;
uniform sampler2D texture0;
uniform vec4 colDiffuse;
void main()
{
vec4 texelColor = texture(texture0, fragTexCoord);
finalColor = texelColor*colDiffuse*fragColor;
}
您正在将位置、uv、颜色缓冲到三个不同的缓冲区,所有缓冲区都指向 GL_ARRAY_BUFFER
目标。您一次只能 draw/interact 一个目标 + 缓冲区组合。此外,您还缺少 glVertexAttribpointer
您需要像处理第一个顶点数据那样合并您的顶点数据:
float vertices[] = {
// Positions Texcoords color
-0.5f, 0.5f, 0.0f, -0.5f, 0.5f, 255, 109, 154, 255,
然后在这里使用正确的步幅:
glVertexAttribPointer(0, 3, GL_FLOAT, false, 9*Float.BYTES, 0); // positions
glVertexAttribPointer(1, 2, GL_FLOAT, false, 9*Float.BYTES, 3*Float.BYTES); // texcoords
glVertexAttribPointer(2, 4, GL_FLOAT, false, 9*Float.BYTES, 5*Float.BYTES); // color
glVertexAttribPointer
将实际绑定到 GL_ARRAY_BUFFER
目标的缓冲区对象与属性相关联。您必须在调用 glVertexAttribPointer
:
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[0]);
glVertexAttribPointer(shaderProgram.getLocs().get(LOC_VERTEX_POSITION.ShaderLocationInt), 3, GL_FLOAT,
false, 0,0); //Positions
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[1]);
glVertexAttribPointer(shaderProgram.getLocs().get(LOC_VERTEX_TEXCOORD01.ShaderLocationInt), 2, GL_FLOAT,
false, 0,0); //Texcoords
glBindBuffer(GL_ARRAY_BUFFER, quadVBO[3]);
glVertexAttribPointer(shaderProgram.getLocs().get(LOC_VERTEX_COLOR.ShaderLocationInt), 4, GL_FLOAT,
false, 0, 0); //Colours
在使用 glGetUniformLocation()
设置着色器属性后,我发现由于着色器构造函数中的错误,未定义着色器位置值。一旦我纠正了这个错误,我的四边形就被绘制到了屏幕上。
感谢所有的帮助和输入!