[英]OpenGL texture displaying as black
我第一次將 OpenGL 與 GLFW、GLEW 和 GLM 一起使用。 我或多或少地遵循了一個教程,但也轉移了注意力以專注於我目前感興趣的方面。
目前,我正在嘗試將像素繪制到紋理,然后將其作為全屏四邊形顯示在屏幕上。 但是,紋理始終顯示為黑色,我不確定哪里出錯了。
在這里初始化紋理(以及全屏四邊形):
int InitializeRenderTarget(GameManager* gameManager)
{
// Vertex Array Object
GLuint vertexArrayID;
glGenVertexArrays(1, &vertexArrayID);
glBindVertexArray(vertexArrayID);
programID = LoadShaders("Source/Graphics/SimpleVertexShader.vert", "Source/Graphics/RenderTextureFragmentShader.frag");
// The texture we're going to render to
glGenTextures(1, &renderedTexture);
glBindTexture(GL_TEXTURE_2D, renderedTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
gameManager->GRID_SIZE, gameManager->GRID_SIZE,
0, GL_RGB, GL_UNSIGNED_BYTE, 0);
glGenerateMipmap(GL_TEXTURE_2D);
// The fullscreen quad's FBO
static const GLfloat g_quad_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f, //0.0f, 0.0f,
1.0f, -1.0f, 0.0f, //1.0f, 0.0f,
-1.0f, 1.0f, 0.0f, //0.0f, 1.0f,
-1.0f, 1.0f, 0.0f, //0.0f, 1.0f,
1.0f, -1.0f, 0.0f, //1.0f, 0.0f,
1.0f, 1.0f, 0.0f, //1.0f, 1.0f
};
glGenBuffers(1, &quad_vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_quad_vertex_buffer_data), g_quad_vertex_buffer_data, GL_STATIC_DRAW);
texID = glGetUniformLocation(programID, "renderedTexture");
glEnable(GL_TEXTURE_2D);
return 0;
}
在此處繪制紋理:
void RenderToTexture(GameManager* gameManager)
{
glBindTexture(GL_TEXTURE_2D, renderedTexture);
float* particleColors = gameManager->getParticleColors();
glTexSubImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
gameManager->GRID_SIZE, gameManager->GRID_SIZE,
0, GL_RGB, GL_FLOAT, (GLvoid*)particleColors);
glGenerateMipmap(GL_TEXTURE_2D);
// Poor filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
在此處繪制到屏幕:
void RenderToScreen()
{
// Render to the screen
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Render on the whole framebuffer, complete from the lower left corner to the upper right
glViewport(100, 100, screenWidth-200, screenHeight-200);
// Clear the screen
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use our shader
glUseProgram(programID);
// Bind our texture in Texture Unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, renderedTexture);
// Set our "renderedTexture" sampler to use Texture Unit 0
glUniform1i(texID, 0);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangles !
glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles
glDisableVertexAttribArray(0);
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
}
主循環:
int main(void)
{
if (InitializeWindow() != 0) {
fprintf(stderr, "Failed to open GLFW window.\n");
getchar();
glfwTerminate();
return -1;
}
GameManager* gameManager = gameManager->getInstance();
if (InitializeRenderTarget(gameManager) != 0) {
fprintf(stderr, "Failed to initialize render target.\n");
getchar();
glfwTerminate();
return -1;
}
do {
gameManager->Update();
RenderToTexture(gameManager);
RenderToScreen();
} // Check if the ESC key was pressed or the window was closed
while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0);
CleanUp();
return 0;
}
頂點着色器:
#version 460 core
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
// Output data ; will be interpolated for each fragment.
out vec2 UV;
void main(){
gl_Position = vec4(vertexPosition_modelspace, 1);
UV = (vertexPosition_modelspace.xy+vec2(1,1))/2.0;
}
最后是片段着色器:
#version 460 core
in vec2 UV;
out vec4 color;
uniform sampler2D renderedTexture;
void main(){
color = texture(renderedTexture, UV);
//color = vec4(UV.x, UV.y, 0, 1);
}
我相當確定我正在將四邊形正確地繪制到屏幕上,因為我在片段着色器中使用注釋掉的線來制作漂亮的彩色漸變效果。 但是,我可能沒有正確綁定紋理。
我確認particleColors
數組確實包含正確的浮點值。 我嘗試將所有紅色設置為1.0f
1.0f
並將所有值設置為255.0f
(以防萬一)。
我嘗試添加如下行:
glEnable(GL_TEXTURE_2D);
glGenerateMipmap(GL_TEXTURE_2D);
// Poor filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
基於我看到的其他一些帖子,但我還沒有看到任何明顯的效果。
我還嘗試更改頂點和片段着色器計算和使用 UV 的方式,但這只會讓事情變得更糟,因為此時甚至不會出現漸變效果。
希望你能弄清楚我錯過了什么。 感謝您的任何幫助。
您使用的glTexSubImage2D
完全錯誤。 第二個和第三個 arguments 是偏移量,第四個和第五個 arguments 是大小:
glTexSubImage2D(GL_TEXTURE_2D, 0, GL_RGBA, gameManager->GRID_SIZE, gameManager->GRID_SIZE, 0, GL_RGB, GL_FLOAT, (GLvoid*)particleColors);
glTexSubImage2D(
GL_TEXTURE_2D, 0,
0, 0, gameManager->GRID_SIZE, gameManager->GRID_SIZE,
GL_RGB, GL_FLOAT, (GLvoid*)particleColors);
glEnable(GL_TEXTURE_2D);
僅在使用固定的 function 管道且沒有着色器程序時才有意義。
我想通了。 Rabbid76 的修正是重要的第一步。
之后我用我的像素陣列玩了一些,在把它變小后發現我的紋理底部確實有一條小像素線。 更多的探索,我發現我實際上填錯了我的像素數據。 在我的循環中修復我的邏輯錯誤,正確地填充了紋理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.