OpenGL 矩形莫名其妙地占据了整个 window
OpenGL rectangle inexplicably takes up entire window
所以我正在使用 GLEW 和 SDL2。目前我无法绘制一个简单的矩形。
我以前做过这个并且让它工作没问题。 (我检查了我的旧代码,但没有发现任何显着差异)
输出应该是这样的,除了不同的背景颜色。
但是,输出如下所示:
当我使用 Renderdoc 检查输出时,所有的值似乎都是它们应该的值,但由于某种原因,输出矩形明显大于视口。 (假设输出中的白色边框 window 代表视口。)
我用谷歌搜索了一下,但找不到解决此问题的方法。我想我只是在某处遗漏了一个函数调用,这导致程序以一种奇怪的方式输出东西。
这是相关代码
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;
}
}
}
Renderer.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);
}
gl_Position = vec4(a_pos, 0.0f);
gl_Position中的X/Y/Z坐标除以W坐标得到屏幕坐标。您将 W 坐标设置为 0,这意味着 X 和 Y 坐标变为无穷大和 - 无穷大(1/0 和 -1/0)并且 Z 坐标变为 NaN。
改为:
vvvv
gl_Position = vec4(a_pos, 1.0f);
所以我正在使用 GLEW 和 SDL2。目前我无法绘制一个简单的矩形。 我以前做过这个并且让它工作没问题。 (我检查了我的旧代码,但没有发现任何显着差异)
输出应该是这样的,除了不同的背景颜色。
但是,输出如下所示:
当我使用 Renderdoc 检查输出时,所有的值似乎都是它们应该的值,但由于某种原因,输出矩形明显大于视口。 (假设输出中的白色边框 window 代表视口。)
我用谷歌搜索了一下,但找不到解决此问题的方法。我想我只是在某处遗漏了一个函数调用,这导致程序以一种奇怪的方式输出东西。
这是相关代码
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;
}
}
}
Renderer.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);
}
gl_Position = vec4(a_pos, 0.0f);
gl_Position中的X/Y/Z坐标除以W坐标得到屏幕坐标。您将 W 坐标设置为 0,这意味着 X 和 Y 坐标变为无穷大和 - 无穷大(1/0 和 -1/0)并且 Z 坐标变为 NaN。
改为:
vvvv gl_Position = vec4(a_pos, 1.0f);