OpenGL + SDL + glew 初始化成功后不绘制任何东西
OpenGL + SDL + glew doesn't draw anything after successful initialization
所以我一直在寻找解决这个问题的方法,但我能找到的都已经过时了。我的问题是,在初始化 SDL 并且 glew 没有错误之后,window 打开并且除 1、0 或 -1 之外的其他 Z 上的任何内容都不会呈现。并且将 Z 设置为这三个值中的任何一个都不会做任何事情。这是我的代码。我在 header 中包含了 glew 和 sdl 并且 loop 方法是主程序循环。
#include "Controller.h"
int Controller::loop() {
// Initialize
if(!init())
return -1;
SDL_Event _event;
// Main loop
while(_running) {
// Loop through all input
while(SDL_PollEvent(&_event))
event(_event);
// Game logic
step();
// Game drawing
draw();
}
// End game
end();
return 0;
}
bool Controller::init() {
// Initialize SDL
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
return false;
// Create window
if ((_mainWindow = SDL_CreateWindow("GAME", 200, 200, 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL)) == NULL)
return false;
// Create context
_mainContext = SDL_GL_CreateContext(_mainWindow);
// Make it active
SDL_GL_MakeCurrent(_mainWindow, _mainContext);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
// Initialize glew
glewExperimental = GL_TRUE;
if (glewInit() != 0)
return false;
return true;
}
void Controller::event(SDL_Event& _event) {
switch(_event.type) {
case SDL_KEYDOWN:
switch (_event.key.keysym.sym) {
case SDLK_ESCAPE:
_running = false;
break;
default:
std::cout << "Key has been pressed." << std::endl;
}
default:
break;
}
_world[_currentWorld].event(_event);
}
void Controller::step() {
_world[_currentWorld].step();
}
void Controller::draw() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_TRIANGLES);
glVertex3f(-1.0f, -0.5f, -4.0f); // A
glVertex3f(1.0f, -0.5f, -4.0f); // B
glVertex3f(0.0f, 0.5f, -4.0f); // C
glEnd();
//_world[_currentWorld].draw();
SDL_GL_SwapWindow(_mainWindow);
}
void Controller::end() {
SDL_GL_DeleteContext(_mainContext);
SDL_DestroyWindow(_mainWindow);
SDL_Quit();
}
您没有任何转换矩阵。因此,可见 z 的范围是 [-1, 1]。如果您从中指定值,相应的部分将被剪掉(并且不可见)。
anything on other Z than 1, 0 or -1 won't render.
在 OpenGL 的规范化设备坐标系中,查看体积 只是沿所有三个维度从 -1 到 1 的规范化立方体。
因为你没有应用任何变换,你基本上直接在 NDC space 中绘制(实际上,它会是剪辑 space,但如果你输入 w 坐标,那将与 NDC 相同处处为 1,默认情况下为 1)。因此,将 z 设置为 < -1.0 或 > 1.0 将导致顶点位于查看体积之外。不过,介于两者之间的任何值(不仅仅是 0.0)都应该有效。
And also setting Z to any of those three values doesn't do anything at all.
我不能 100% 确定我是否正确理解了这个问题。我认为您希望对象沿着 z 移动得越远,它们就会显得越小。但是 GL 将 总是 通过简单地在 xy 平面中进行光栅化来进行正交(非透视)投影。如果你想要透视效果,你必须做一些透视 transformation,通常,这是通过 4x4 均匀投影矩阵完成的。
我建议您先学习线性代数和齐次 spaces/投影变换的基础知识,然后再尝试深入研究 OpenGL 或 D3D 等渲染 API。
此外,您的代码存在一些问题:
您在创建上下文后请求 GL 上下文版本,这将没有任何效果(它只会告诉 SDL 下次创建 GL 上下文时要做什么) .您似乎还要求 "modern" OpenGL 版本 3.3。但是,您用于绘图的代码在现代 GL 中已 弃用 ,并且这些功能已在核心配置文件中完全删除。如果你现在开始学习 GL,我强烈建议你学习现代的 OpenGL,而不是 20 年前的这种过时的东西。看看 this tutorial,它也涉及数学的某些方面。
所以我一直在寻找解决这个问题的方法,但我能找到的都已经过时了。我的问题是,在初始化 SDL 并且 glew 没有错误之后,window 打开并且除 1、0 或 -1 之外的其他 Z 上的任何内容都不会呈现。并且将 Z 设置为这三个值中的任何一个都不会做任何事情。这是我的代码。我在 header 中包含了 glew 和 sdl 并且 loop 方法是主程序循环。
#include "Controller.h"
int Controller::loop() {
// Initialize
if(!init())
return -1;
SDL_Event _event;
// Main loop
while(_running) {
// Loop through all input
while(SDL_PollEvent(&_event))
event(_event);
// Game logic
step();
// Game drawing
draw();
}
// End game
end();
return 0;
}
bool Controller::init() {
// Initialize SDL
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
return false;
// Create window
if ((_mainWindow = SDL_CreateWindow("GAME", 200, 200, 640, 480, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL)) == NULL)
return false;
// Create context
_mainContext = SDL_GL_CreateContext(_mainWindow);
// Make it active
SDL_GL_MakeCurrent(_mainWindow, _mainContext);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
// Initialize glew
glewExperimental = GL_TRUE;
if (glewInit() != 0)
return false;
return true;
}
void Controller::event(SDL_Event& _event) {
switch(_event.type) {
case SDL_KEYDOWN:
switch (_event.key.keysym.sym) {
case SDLK_ESCAPE:
_running = false;
break;
default:
std::cout << "Key has been pressed." << std::endl;
}
default:
break;
}
_world[_currentWorld].event(_event);
}
void Controller::step() {
_world[_currentWorld].step();
}
void Controller::draw() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_TRIANGLES);
glVertex3f(-1.0f, -0.5f, -4.0f); // A
glVertex3f(1.0f, -0.5f, -4.0f); // B
glVertex3f(0.0f, 0.5f, -4.0f); // C
glEnd();
//_world[_currentWorld].draw();
SDL_GL_SwapWindow(_mainWindow);
}
void Controller::end() {
SDL_GL_DeleteContext(_mainContext);
SDL_DestroyWindow(_mainWindow);
SDL_Quit();
}
您没有任何转换矩阵。因此,可见 z 的范围是 [-1, 1]。如果您从中指定值,相应的部分将被剪掉(并且不可见)。
anything on other Z than 1, 0 or -1 won't render.
在 OpenGL 的规范化设备坐标系中,查看体积 只是沿所有三个维度从 -1 到 1 的规范化立方体。
因为你没有应用任何变换,你基本上直接在 NDC space 中绘制(实际上,它会是剪辑 space,但如果你输入 w 坐标,那将与 NDC 相同处处为 1,默认情况下为 1)。因此,将 z 设置为 < -1.0 或 > 1.0 将导致顶点位于查看体积之外。不过,介于两者之间的任何值(不仅仅是 0.0)都应该有效。
And also setting Z to any of those three values doesn't do anything at all.
我不能 100% 确定我是否正确理解了这个问题。我认为您希望对象沿着 z 移动得越远,它们就会显得越小。但是 GL 将 总是 通过简单地在 xy 平面中进行光栅化来进行正交(非透视)投影。如果你想要透视效果,你必须做一些透视 transformation,通常,这是通过 4x4 均匀投影矩阵完成的。
我建议您先学习线性代数和齐次 spaces/投影变换的基础知识,然后再尝试深入研究 OpenGL 或 D3D 等渲染 API。
此外,您的代码存在一些问题:
您在创建上下文后请求 GL 上下文版本,这将没有任何效果(它只会告诉 SDL 下次创建 GL 上下文时要做什么) .您似乎还要求 "modern" OpenGL 版本 3.3。但是,您用于绘图的代码在现代 GL 中已 弃用 ,并且这些功能已在核心配置文件中完全删除。如果你现在开始学习 GL,我强烈建议你学习现代的 OpenGL,而不是 20 年前的这种过时的东西。看看 this tutorial,它也涉及数学的某些方面。