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并卸载了程序。

盯着我的代码好几天试图找到错误后,这很滑稽:)