【问题标题】:OpenGL rectangle inexplicably takes up entire windowOpenGL矩形莫名占满整个窗口
【发布时间】:2020-10-19 19:04:18
【问题描述】:

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

除了背景颜色不同之外,输出应该是这样的。

但是,输出如下所示:

当我使用 Renderdoc 检查输出时,所有值似乎都与它们应该的一样,但由于某种原因,输出矩形明显大于视口。 (假设输出窗口中的白色边框代表视口。)

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

这是相关代码

game.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++ opengl rendering sdl-2


【解决方案1】:
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);

【讨论】:

  • 这最终成为了罪魁祸首。我忽略了那个数字。谢谢。
  • " 您将 W 坐标设置为 0,这意味着 X 和 Y 坐标变为无穷大和 -infinity" 实际上不是的情况。透视分割出现在 剪辑之后,并且一个点 (x,y,z,0) 将满足剪辑条件 -w &lt;= x,y,z &lt;= w 仅适用于 x=y=z=0 的非常特殊的情况(这是一个非常奇怪的特殊情况,从未出现如果使用适当的投影矩阵),但对于所有其他点,处理实际上是明确定义的。
  • @derhass 嗯,那它为什么会渲染任何东西呢?
  • 因为图元可能仍与视图体积相交。如果你有w=0,点基本上在无穷大,但如果你有一个图元,例如顶点(-1,-1,-1,0)(1,1,1,0),它将直接穿过视图体积,并被裁剪为有限多边形(属性如果使用 w=0,插值仍然会出错,但基本的光栅化会起作用)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-21
  • 1970-01-01
  • 1970-01-01
  • 2019-10-29
  • 1970-01-01
  • 2021-04-27
  • 2011-08-30
相关资源
最近更新 更多