首页 > 解决方案 > OpenGL矩形莫名占满整个窗口

问题描述

所以我正在使用 GLEW 和 SDL2。目前我在绘制一个简单的矩形时遇到了麻烦。我以前做过这个,让它工作没问题。(我检查了我的旧代码,但找不到任何显着差异)

除了不同的背景颜色之外,这是输出的样子。 在此处输入图像描述

但是,这是输出的样子: 在此处输入图像描述

当我使用 Renderdoc 检查输出时,所有值似乎都应该是,但由于某种原因,输出矩形明显大于视口。(假设输出窗口中的白色边框代表视口。) 在此处输入图像描述

我用谷歌搜索了一下,但找不到任何解决这个问题的方法。我想我只是在某处遗漏了一个函数调用,这导致程序以一种奇怪的方式输出东西。

这是相关代码

游戏.cpp

#include "Game.h"

void Game::Game::main_loop()
{
    //Placeholder setup;
    float vertices[] = {
        -0.5f, -0.5f, 0.0f,
         0.5f, -0.5f, 0.0f,
         0.5f,  0.5f, 0.0f,
        -0.5f,  0.5f, 0.0f,
    };
    unsigned int indices[] = { 
        0, 1, 2,
        2, 3, 0 
    };  

    unsigned int vertex_array, vertex_buffer, element_buffer;

    glGenVertexArrays(1, &vertex_array);
    glBindVertexArray(vertex_array);

    glGenBuffers(1, &vertex_buffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glGenBuffers(1, &element_buffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    Asset::Loader l;
    auto s = l.load_shader("res/GUI/Shaders/Textured_quad.vert", "res/GUI/Shaders/Textured_quad.frag");

    keep_going = true;
    while(keep_going)
    {
        handle_events();
        renderer.clear();

        s->use(); //Just calls 'glUseProgram' on the shader inside this object
        glBindVertexArray(vertex_array);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

        renderer.show();
    }
}

void Game::Game::handle_events()
{
    while(SDL_PollEvent(&event))
    {
        switch(event.type)
        {
        case SDL_MOUSEBUTTONDOWN:
        case SDL_QUIT:
            keep_going = false;
        }
    }
}

渲染器.cpp

#include "Renderer.h"

Game::Graphics::Renderer::Renderer()
{
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

    window = SDL_CreateWindow(
        "GUI", 
        SDL_WINDOWPOS_CENTERED_DISPLAY(1),
        SDL_WINDOWPOS_CENTERED_DISPLAY(1),
        640,
        480,
        SDL_WINDOW_OPENGL
    );

    context = SDL_GL_CreateContext(
        window
    );

    if(!window)
    {
        std::cerr << "Window Error: " << SDL_GetError() << std::endl;
        return;
    }

    if(!context)
    {
        std::cerr << "GL Context Error: " << SDL_GetError() << std::endl;
        return;
    }

    glewInit();

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glViewport(0, 0, 640, 480);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_LIGHTING);
    glDisable(GL_BLEND);
}

Game::Graphics::Renderer::~Renderer()
{
    SDL_HideWindow(window);
    SDL_GL_DeleteContext(context);
    SDL_DestroyWindow(window);
}

void Game::Graphics::Renderer::clear()
{
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void Game::Graphics::Renderer::show()
{
    SDL_GL_SwapWindow(window);
}

着色器

#version 330 core

layout (location = 0) in vec3 a_pos;

void main()
{
    gl_Position = vec4(a_pos, 0.0f);
}

//fragment
#version 330 core

out vec4 o_color;

void main()
{
    o_color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}

标签: c++openglrenderingsdl-2

解决方案


gl_Position = vec4(a_pos, 0.0f);

gl_Position 中的 X/Y/Z 坐标除以 W 坐标得到屏幕坐标。您将 W 坐标设置为 0,这意味着 X 和 Y 坐标变为无穷大和 -infinity(1/0 和 -1/0),Z 坐标变为 NaN。

将其更改为:

                          vvvv
gl_Position = vec4(a_pos, 1.0f);

推荐阅读