纹理不适合正方形 - OpenGL

Posted

技术标签:

【中文标题】纹理不适合正方形 - OpenGL【英文标题】:Texture does not fit in the square - OpenGL 【发布时间】:2016-12-08 16:26:42 【问题描述】:

我正在尝试创建一个正方形并在其中放置一个红色圆圈。正如您在简单的 vert I 中看到的那样,将 (-1, 1) 范围映射到 (0,1) 范围:

coord = position.xy*0.5 + vec2(0.5,0.5);

如果你看simple.frag,有这一行:

if(abs(length(coord - vec2(0.5,0.5))) < 0.3)

因此,我期待正方形中间的红色圆圈。但是会发生这种情况:

圆心在 (0.5, 0.5) 之外。如果我将该行更改为:

if(abs(length(coord - vec2(0.0,0.0))) < 0.3)

输出是:

圆的中心如预期的那样位于左下角。但是不应该是右上角(1,1)?圆也不是完美的圆。我错过了什么?

初始化:

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);

主循环;

    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);

【问题讨论】:

取决于您输入的数据。您绝对应该为您的问题写一个简短的介绍(您要做什么......)。从一大堆代码开始从来都不是一个好主意。阅读How to Ask。 我编辑了问题。 显示四边形顶点。我假设,inVAO 只是一个全屏四边形? 不,不是。角是 -1,-1, -1,1, 1,-1 和 1,1。我编辑了代码。 【参考方案1】:

绘制到纹理时,您必须修改视口。如果使用窗口的视口,OpenGL 假定纹理与窗口的大小相同。因此,只有整个图像的左下角会出现在纹理中。

所以在渲染到纹理之前:

glViewport(0, 0, 256, 256);

...并在绘制最终场景之前将其还原。

【讨论】:

@wEight - 视口的变化是必要的,因为 OP 首先绘制到纹理,然后在第二步中使用纹理绘制四边形。仅在第一步中需要调整视口。如果您有即用型纹理,则无需费心。

以上是关于纹理不适合正方形 - OpenGL的主要内容,如果未能解决你的问题,请参考以下文章

如何在OpenGL中将像素作为纹理绘制到多边形?

Opengl渲染到纹理,但纹理为空

Qt OpenGL纹理是黑色的

在 OpenGL 4.6 中没有适合我的 alpha 混合

OpenGL着色器没有传递正确的纹理坐标

使用 VBO/IBO 的 OpenGL 纹理三角形