Текстура не помещается в квадрат - OpenGL

Я пытаюсь создать квадрат и поместить в него красный круг. Как вы можете видеть в простом 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);

простой.верт:

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

простой.фрагмент:

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

person Simon Müller    schedule 08.12.2016    source источник
comment
Зависит от того, какие данные вы вводите. Вам обязательно нужно написать краткое введение для вашего вопроса (что вы пытаетесь сделать...). Начинать с целой кучи кода никогда не бывает хорошей идеей. Прочитайте Как спросить.   -  person Nico Schertler    schedule 08.12.2016
comment
Я отредактировал вопрос.   -  person Simon Müller    schedule 08.12.2016
comment
Покажите вершины четырехугольника. Я предполагаю, что inVAO — это просто полноэкранный квадроцикл?   -  person Nico Schertler    schedule 08.12.2016
comment
Нет. Углы -1,-1, -1,1, 1,-1 и 1,1. Я отредактировал код.   -  person Simon Müller    schedule 08.12.2016


Ответы (1)


Вы должны изменить окно просмотра при рисовании текстуры. Если вы используете область просмотра окна, OpenGL предполагает, что текстура имеет тот же размер, что и окно. Поэтому в текстуре окажется только левый нижний угол всего изображения.

Итак, перед рендерингом в текстуру:

glViewport(0, 0, 256, 256);

... и верните это перед рисованием финальной сцены.

person Nico Schertler    schedule 08.12.2016
comment
@wEight - изменение области просмотра необходимо, потому что OP сначала рисует текстуру, а на втором этапе использует текстуру для рисования четырехугольника. Настройка области просмотра необходима только на первом этапе. Если у вас есть готовая к использованию текстура, вам не нужно с ней возиться. - person Nico Schertler; 13.05.2021