OpenGL 3+ BlackScreen - C ++

时间:2016-04-25 19:35:02

标签: c++ opengl sdl

在尝试使用SDL2 ...

在OpenGL上获得一个简单的三角形后,我得到一个黑屏

我实际上使用OpenGL初始化窗口并使用对象名称#34; EngineOpenGL"启动GLEW。 :http://pastebin.com/S4YDgY45

然后我开始一个应该渲染三角形的场景: " SceneOpenGL" :http://pastebin.com/GD4f5UDj

主文件:

#include <SDL.h>
#include <iostream>
#include <GL\glew.h>
#include "EngineOpenGl.h"

// DEBUG_MemoryLeaks
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
// _DEBUG

#include "SDLInitVideoException.h"
int main(int argc, char **argv) {
    _CrtDumpMemoryLeaks();

    EngineOpenGL * scene = new EngineOpenGL("OpenGL", 720, 1280);
    try {
        scene->init();
    } catch (const SDLInitVideoException &e) {
        delete scene;
        std::cout << "Error while initialising SDL" << std::endl;
    } catch (const SDLCreateWindowException &e) {
        delete scene;
        std::cout << "Error while initialising the window" << std::endl;
    } catch (const SDLCreateContextGLException &e) {
        delete scene;
        std::cout << "Error while creating the contextGL" << std::endl;
    } catch (const GLEWInitException &e) {
        delete scene;
        std::cout << "Error while initialising " << std::endl;
    } catch (const SceneOpenGLException &e) {
        delete scene;
        std::cout << "Error while starting the scene" << std::endl;
    }
    scene->start();
    delete scene;

    // DEBUG_MemoryLeaks
    _CrtDumpMemoryLeaks();
    // _DEBUG
    return 0;
}

FPS在控制台中显示fps,输入获取用户输入。

编辑:我实际上只是试图复制/通过代码来渲染三角形并保持不起作用......

        #include "SceneOpenGl.h"

// Shader temporaire :
#include "Shader.h"

SceneOpenGL::SceneOpenGL(SDL_Window* window) {
    if (window == NULL) {
        throw new SceneOpenGLException();
    }
    // Engine
    this->window = window;
    // Tools
    this->fps = new FPSCount();
    this->input = new Input();
    // Scene
    this->run = false;

    int w, h;
    SDL_GetWindowSize(window, &w, &h);
    this->projection = glm::perspective(70.0, (double)(w/h), 1.0, 100.0);
    this->modelview = glm::mat4(1.0);
}


SceneOpenGL::~SceneOpenGL(){
    delete fps;
    delete input;
}

void SceneOpenGL::start() {
    run = true;

    // Test en attendant ObjectGL.show() //
    GLfloat vertices[] = {
        0.5f,  0.5f, 0.0f,  // Top Right
        0.5f, -0.5f, 0.0f,  // Bottom Right
        -0.5f, -0.5f, 0.0f,  // Bottom Left
        -0.5f,  0.5f, 0.0f   // Top Left 
    };
    GLuint indices[] = {  // Note that we start from 0!
        0, 1, 3,  // First Triangle
        1, 2, 3   // Second Triangle
    };
    // Build and compile our shader program
    // Vertex shader
    const GLchar* vertexShaderSource = "#version 330 core\n"
        "layout (location = 0) in vec3 position;\n"
        "void main()\n"
        "{\n"
        "gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
        "}\0";
    const GLchar* fragmentShaderSource = "#version 330 core\n"
        "out vec4 color;\n"
        "void main()\n"
        "{\n"
        "color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
        "}\n\0";

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    // Check for compile time errors
    GLint success;
    GLchar infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // Fragment shader
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    // Check for compile time errors
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // Link shaders
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    // Check for linking errors
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    GLuint VBO, VAO, EBO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    glGenBuffers(1, &EBO);
    // Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind

    glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs), remember: do NOT unbind the EBO, keep it bound to this VAO


    // /Test //

    while (run) {
        // FPS flag
        if (fps->flag()) {
            std::cout << "FPS : " << fps->getFps() << std::endl;
        }

        // Input check/actions
        input->updateEvents();
        if (input->isKeyPush(SDL_SCANCODE_ESCAPE)) {
            run = false;
        }

        // Cleaning last frame
        glClear(GL_COLOR_BUFFER_BIT);

        // Test //
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // Draw our first triangle
        glUseProgram(shaderProgram);
        glBindVertexArray(VAO);
        //glDrawArrays(GL_TRIANGLES, 0, 6);
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
        glBindVertexArray(0);


        // FPS add frame
        fps->addFrame();

        // Rendering
        SDL_GL_SwapWindow(window);
    }
}

1 个答案:

答案 0 :(得分:2)

您绝不会将顶点数据加载到视频内存中。你有一行看起来像尝试将顶点加载到视频内存中:

glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);

....但那不是那个功能所做的。

您需要创建并绑定顶点阵列和顶点缓冲区:

GLuint vertex_array_id;
glGenVertexArrays(1, &vertex_array_id);
glBindVertexArray(vertex_array_id);
GLuint vertex_buffer_id;
glGenBuffers(1, &vertex_buffer_id);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id);

然后,在绑定此顶点数组和顶点缓冲区时,您需要向缓冲区显式提供数据:

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

然后使用glVertexAttribPointer指定数据的布局方式。

glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
glEnableVertexAttribArray(0);

顺便说一句,所有这些代码都应该在循环之外。然后在绘制循环内,您只需调用glDrawArrays