OpenGL 模型在一段时间内呈现良好,然后在随机时间后呈现稀疏
OpenGL model renders fine for a while, then it renders sparsely after a random amount of time
我整理了一个示例 OpenGL 演示,发现了一个问题。我可以正确加载和渲染模型。然而,几秒钟后,模型停止正确渲染。
编辑:从正常到不良的变化发生在随机数秒后并立即发生。一旦坏了,就再也回不去了。
EventLoop::Start() 函数现在所做的就是阻塞并在循环中调用回调,直到 isRunning 为 false。
这是模型出错前的样子:
这是几秒钟后的样子:
这是我的代码:
// nasty globals
static Camera* camera;
static ModelData dragonModel;
static ShaderProgram program;
using namespace std;
// called by an event loop class until isRunning is false
void callback(bool *isRunning)
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
// update the camera position
switch(event.type)
{
case SDL_QUIT:
*isRunning = false;
SDL_Quit();
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_UP:
camera->MoveBy(glm::vec3(0, 1, 0));
break;
case SDLK_DOWN:
camera->MoveBy(glm::vec3(0, -1, 0));
break;
case SDLK_RIGHT:
camera->MoveBy(glm::vec3(1, 0, 0));
break;
case SDLK_LEFT:
camera->MoveBy(glm::vec3(-1, 0, 0));
break;
case SDLK_w:
camera->MoveTo(glm::vec3(0, 0, -5));
break;
case SDLK_s:
camera->MoveTo(glm::vec3(0, 0, 5));
break;
default:
break;
}
default:
break;
}
}
// calc matrices
glm::mat4 scale = glm::scale(glm::mat4(), glm::vec3(1, 1, 1));
glm::mat4 model = scale * glm::mat4(1.0);
glm::mat4 MVP = DisplayManager::GetProjectionMatrix() * model;
// send the final matrix over
GLuint MVPLoc = glGetUniformLocation(program.id, "MVP");
glUniformMatrix4fv(MVPLoc, 1, GL_FALSE, glm::value_ptr(MVP));
// clear and draw
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, dragonModel.num_indices, GL_UNSIGNED_INT, NULL);
DisplayManager::Swap(); // SDL_GL_SwapWindow()
}
#undef main
int main(void)
{
// create a display and get the camera
DisplayManager::Create("yay", 800, 600);
camera = DisplayManager::GetCamera();
glClearColor(0, 0, 0, 1);
DisplayManager::Swap();
// load the dragon model
load_model(&dragonModel, "dragon.obj");
// load the shader program
program = ShaderManager::LoadProgram("basicShader.vert", "basicShader.frag");
ShaderManager::SetCurrentProgram(program);
if(!IsValidProgram(program))
{
printf("\ninvalid program detected\n");
}
// set up the model's VAO and leave it bound
glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK);
GLuint dragonVAO = -1;
GLuint VBO = -1;
GLuint EBO = -1;
glGenVertexArrays(1, &dragonVAO);
glBindVertexArray(dragonVAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, dragonModel.num_vertices * 3 * sizeof(GLfloat), dragonModel.vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, dragonModel.num_indices * sizeof(GLuint), dragonModel.indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
glEnableVertexAttribArray(0);
// free the model because we don't need our copy
free_model(&dragonModel);
// start the event loop
EventLoop eventLoop;
eventLoop.SetLoopCallback(&callback);
eventLoop.Start();
return 0;
}
这是我的着色器:
basicShader.vert
#version 330
uniform mat4 MVP;
layout(location = 0) in vec3 in_position;
out vec4 passed_color;
void main(void)
{
gl_Position = MVP * vec4(in_position, 1.0f);
passed_color = vec4(normalize(in_position), 1.0f);
}
basicShader.frag
#version 330
in vec4 passed_color;
void main(void)
{
gl_FragColor = passed_color;
}
我尝试过的:
- 更新驱动程序
- 确保索引的数量在
它搞砸了。
我没有看到任何模型数据更新或绘制调用更改会导致这种情况发生。我怀疑 glDrawElements、glClear、我的矩阵更新和我的上下文的创建:
void DisplayManager::Create(const char *title, int width, int height)
{
SDL_Init(SDL_INIT_VIDEO);
camera_ = new Camera();
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
window_ = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
glContext_ = SDL_GL_CreateContext(window_);
SDL_GL_MakeCurrent(window_, glContext_);
SDL_GL_SetSwapInterval(1);
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if(err != GLEW_OK)
{
printf("glew failed to init: %s", glewGetErrorString(err));
}
}
AMD 游戏进化!!!
有一次,在渲染立方体时,"Turning On" 和 "Save Highlight - Ctrl F2" 出现在我屏幕的左上角。显然这是 AMD Gaming Evolved 的屏幕截图。碰巧我的渲染在消息出现的同时出现了问题。
我终止了进程 "Raptr Desktop",我的模型现在可以正确渲染了!
我已经通知AMD并卸载了程序。
盯着我的代码好几天试图找到错误后,这很滑稽:)
我整理了一个示例 OpenGL 演示,发现了一个问题。我可以正确加载和渲染模型。然而,几秒钟后,模型停止正确渲染。
编辑:从正常到不良的变化发生在随机数秒后并立即发生。一旦坏了,就再也回不去了。
EventLoop::Start() 函数现在所做的就是阻塞并在循环中调用回调,直到 isRunning 为 false。
这是模型出错前的样子:
这是几秒钟后的样子:
这是我的代码:
// nasty globals
static Camera* camera;
static ModelData dragonModel;
static ShaderProgram program;
using namespace std;
// called by an event loop class until isRunning is false
void callback(bool *isRunning)
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
// update the camera position
switch(event.type)
{
case SDL_QUIT:
*isRunning = false;
SDL_Quit();
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym)
{
case SDLK_UP:
camera->MoveBy(glm::vec3(0, 1, 0));
break;
case SDLK_DOWN:
camera->MoveBy(glm::vec3(0, -1, 0));
break;
case SDLK_RIGHT:
camera->MoveBy(glm::vec3(1, 0, 0));
break;
case SDLK_LEFT:
camera->MoveBy(glm::vec3(-1, 0, 0));
break;
case SDLK_w:
camera->MoveTo(glm::vec3(0, 0, -5));
break;
case SDLK_s:
camera->MoveTo(glm::vec3(0, 0, 5));
break;
default:
break;
}
default:
break;
}
}
// calc matrices
glm::mat4 scale = glm::scale(glm::mat4(), glm::vec3(1, 1, 1));
glm::mat4 model = scale * glm::mat4(1.0);
glm::mat4 MVP = DisplayManager::GetProjectionMatrix() * model;
// send the final matrix over
GLuint MVPLoc = glGetUniformLocation(program.id, "MVP");
glUniformMatrix4fv(MVPLoc, 1, GL_FALSE, glm::value_ptr(MVP));
// clear and draw
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawElements(GL_TRIANGLES, dragonModel.num_indices, GL_UNSIGNED_INT, NULL);
DisplayManager::Swap(); // SDL_GL_SwapWindow()
}
#undef main
int main(void)
{
// create a display and get the camera
DisplayManager::Create("yay", 800, 600);
camera = DisplayManager::GetCamera();
glClearColor(0, 0, 0, 1);
DisplayManager::Swap();
// load the dragon model
load_model(&dragonModel, "dragon.obj");
// load the shader program
program = ShaderManager::LoadProgram("basicShader.vert", "basicShader.frag");
ShaderManager::SetCurrentProgram(program);
if(!IsValidProgram(program))
{
printf("\ninvalid program detected\n");
}
// set up the model's VAO and leave it bound
glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK);
GLuint dragonVAO = -1;
GLuint VBO = -1;
GLuint EBO = -1;
glGenVertexArrays(1, &dragonVAO);
glBindVertexArray(dragonVAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, dragonModel.num_vertices * 3 * sizeof(GLfloat), dragonModel.vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, dragonModel.num_indices * sizeof(GLuint), dragonModel.indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);
glEnableVertexAttribArray(0);
// free the model because we don't need our copy
free_model(&dragonModel);
// start the event loop
EventLoop eventLoop;
eventLoop.SetLoopCallback(&callback);
eventLoop.Start();
return 0;
}
这是我的着色器:
basicShader.vert
#version 330
uniform mat4 MVP;
layout(location = 0) in vec3 in_position;
out vec4 passed_color;
void main(void)
{
gl_Position = MVP * vec4(in_position, 1.0f);
passed_color = vec4(normalize(in_position), 1.0f);
}
basicShader.frag
#version 330
in vec4 passed_color;
void main(void)
{
gl_FragColor = passed_color;
}
我尝试过的:
- 更新驱动程序
- 确保索引的数量在 它搞砸了。
我没有看到任何模型数据更新或绘制调用更改会导致这种情况发生。我怀疑 glDrawElements、glClear、我的矩阵更新和我的上下文的创建:
void DisplayManager::Create(const char *title, int width, int height)
{
SDL_Init(SDL_INIT_VIDEO);
camera_ = new Camera();
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
window_ = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
glContext_ = SDL_GL_CreateContext(window_);
SDL_GL_MakeCurrent(window_, glContext_);
SDL_GL_SetSwapInterval(1);
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if(err != GLEW_OK)
{
printf("glew failed to init: %s", glewGetErrorString(err));
}
}
AMD 游戏进化!!!
有一次,在渲染立方体时,"Turning On" 和 "Save Highlight - Ctrl F2" 出现在我屏幕的左上角。显然这是 AMD Gaming Evolved 的屏幕截图。碰巧我的渲染在消息出现的同时出现了问题。
我终止了进程 "Raptr Desktop",我的模型现在可以正确渲染了!
我已经通知AMD并卸载了程序。
盯着我的代码好几天试图找到错误后,这很滑稽:)