问题
I am trying to create a square and put a red circle middle of it. As you can see in the simple vert I map (-1, 1) range to (0,1) range:
coord = position.xy*0.5 + vec2(0.5,0.5);
If you look at the simple.frag, there is this line:
if(abs(length(coord - vec2(0.5,0.5))) < 0.3)
Thus I am expecting red circle at the middle of square. However this happens:
The center of circle is beyond of (0.5, 0.5). If I change that line to this:
if(abs(length(coord - vec2(0.0,0.0))) < 0.3)
Output is:
The center of the circle is at the bottom-left corner as expected. However shouldn't be the top right corner (1,1)? Also the circle is not perfect circle. What am I missing?
initializations:
Shader simpleShader("simple.vert", "simple.frag");
Shader quadShader("quad.vert", "quad.frag");
GLfloat inVertices[] = {
-1.0f, 1.0f, 0.0,
-1.0f, -1.0f, 0.0,
1.0f, -1.0f, 0.0,
-1.0f, 1.0f, 0.0,
1.0f, -1.0f, 0.0,
1.0f, 1.0f, 0.0 };
GLfloat quadVertices[] = {
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-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, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f
};
GLuint inVAO, inVBO;
glGenVertexArrays(1, &inVAO);
glGenBuffers(1, &inVBO);
glBindVertexArray(inVAO);
glBindBuffer(GL_ARRAY_BUFFER, inVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(inVertices), &inVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
glBindVertexArray(0);
GLuint quadVAO, quadVBO;
glGenVertexArrays(1, &quadVAO);
glGenBuffers(1, &quadVBO);
glBindVertexArray(quadVAO);
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glBindVertexArray(0);
GLuint textureColorbuffer;
glGenTextures(1, &textureColorbuffer);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
GLuint framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
// Create a color attachment texture
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
main loop;
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Draw our first triangle
simpleShader.Use();
glBindVertexArray(inVAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
quadShader.Use();
modelLoc = glGetUniformLocation(quadShader.Program, "model");
viewLoc = glGetUniformLocation(quadShader.Program, "view");
projLoc = glGetUniformLocation(quadShader.Program, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
glBindVertexArray(quadVAO);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer); // Use the color attachment texture as the texture of the quad plane
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
// Swap the screen buffers
glfwSwapBuffers(window);
simple.vert:
#version 330 core
layout (location = 0) in vec3 position;
out vec2 coord;
void main(){
coord = position.xy*0.5 + vec2(0.5,0.5);
gl_Position = vec4(position, 1.0f);
}
simple.frag:
#version 330 core
in vec2 coord;
out vec4 color;
void main(){
if(abs(length(coord - vec2(0.5,0.5))) < 0.3)
color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
else
color = vec4(0.0f, 1.0f, 0.0f, 1.0f);
}
quad.vert:
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoords;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec2 TexCoords;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f);
TexCoords = texCoords;
}
quad.frag:
#version 330 core
in vec2 TexCoords;
out vec4 color;
uniform sampler2D screenTexture;
void main()
{
color = texture(screenTexture, TexCoords);
}
回答1:
You have to modify your viewport when drawing to the texture. If you use the viewport of the window, OpenGL assumes that the texture has the same size as the window. Therefore, only the lower left corner of the entire image will end up in the texture.
So before rendering to the texture:
glViewport(0, 0, 256, 256);
... and revert that before drawing the final scene.
来源:https://stackoverflow.com/questions/41044215/texture-does-not-fit-in-the-square-opengl