Good afternoon,
I know this is probably not the best way to word a question as it seems like “something is wrong” and I apologize ahead of time, but I have been going over this code for a while now and cannot seem to make any headway. I am using OpenGL ES version 3.2 with OpenGL EGL. I’m hoping it is something stupid simple that I am overlooking because I have been staring at the code too long
I am trying to apply a texture to a quad geometry but all I get is a black PPM file image when I render. Maybe I am not correctly using textures? I just don’t know at this point, so if anyone could take a quick look at the sample code and let me know if I am doing something obviously wrong that would be greatly appreciated.
The vertex shader follows:
#version 430 core
layout (location = 0) in vec3 aPos;
layout (location = 1) out vec2 TexCoord;
void main()
{
gl_Position = vec4(aPos, 1.0);
TexCoord = (aPos.xy + vec2(1.0)) / 2.0;
}
The fragment shader follows:
#version 430 core
layout (location = 0) in vec2 TexCoord;
layout (location = 1) out vec4 FragColor;
layout (binding = 0) uniform sampler2D uTexture;
void main()
{
FragColor = texture(uTexture, TexCoord);
}
I will spare all the gory details of properly accessing EGL display and setting of context as well as creation of shader program, herein defined as shaderProgram, that is done before the code shown in the following C++ code snippet.
I know that the EGL and shader function calls are working as no errors via glGetProgramiv
for linking or validation of shader program (I also was able to properly render the standard hello triangle from OpenGL tutorial with these operations).
Also, the value of width and height is 640 and 480, respectively.
...
// Use the previously compiled shader program
glUseProgram(shaderProgram);
// Create a texture from a floating point array
const int textureWidth = 512;
const int textureHeight = 512;
float* textureData = new float[textureWidth * textureHeight * 4];
for (int i = 0; i < textureWidth * textureHeight * 4; ++i)
{
textureData[i] = i / 100000.0f;
}
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, textureWidth, textureHeight, 0, GL_RGBA, GL_FLOAT, textureData);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
delete[] textureData;
// Create a frame buffer and attach the texture to it
GLuint framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
// Create a vertex buffer and index buffer for a quad
float vertices[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f
};
GLfloat texCoords[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f
};
GLuint indices[] = {
0, 1, 2,
2, 3, 0
};
GLuint VBO, VAO, EBO, textureCoordLoc;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &textureCoordLoc);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, textureCoordLoc);
glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords), texCoords, GL_STATIC_DRAW);
glVertexAttribPointer(textureCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
glEnableVertexAttribArray(textureCoordLoc);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// Render the offscreen quad and apply the texture
glViewport(0, 0, width, height);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
std::vector<float> framebufferData(width * height * 4);
glReadPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, framebufferData.data());
// The following method writes out PPM file and works with the "hello triangle" example of
// OpenGL tutorial
saveImage(out_file, framebufferData, width, height);
// Render the quad to the default framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// Cleanup
glDeleteTextures(1, &texture);
glDeleteFramebuffers(1, &framebuffer);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
glDeleteVertexArrays(1, &VAO);
...
Once again, I apologize for the ambiguous “something isn’t working” kind of question, but I have no absolutely idea why there is no image shown except black and am looking for a potential starting point if anything.
Thanks for your time and any help.