Texture does not fit in the square - OpenGL

老子叫甜甜 提交于 2021-02-08 08:32:51

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!