无法使用现代OpenGL渲染基本三角形

时间:2017-07-24 18:04:07

标签: c++ opengl glfw

我正在尝试从头开始编写一个现代的OpenGL应用程序,但我无法获得一个基本的Triangle来呈现。这很奇怪,因为我已经在一些较旧的代码中设置了这个,我无法发现我在完成所有事情方面的不同。

我正在使用着色器,据我所知,它们已正确编译和链接。

我正在使用GLFW和gl3w。

我从这段代码中得到的就是我的窗口,上面有清晰的颜色。

我会转储我的代码

Main.cpp的

#include <GL/gl3w.h>
#include "Display/Display.h"
#include "Shader/Shader.h"
#include "Mesh/Mesh.h"

#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600
#define WINDOW_TITLE "CompSci Coursework"

int main() {

    //Create Display and Context
    Display display( WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE );

    //Create Basic Shaders
    Shader basicShader( "BasicShader" );
    basicShader.useShader();

    //Create VAO
    GLuint VAO;
    glGenVertexArrays( 1, &VAO );
    glBindVertexArray( VAO );

    std::vector<float> verticies = {
            -0.5f, -0.5f,
            0.5f, -0.5f,
            0.0f, 0.5f
    };

    //Create Mesh
    Mesh triangle( verticies );

    //While Open Loop
    while ( !display.CheckShouldClose()) {

        //Clear Buffer
        glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

        //Draw Triangle
        glDrawArrays( GL_TRIANGLES, 0, 3 );

        //Update Display
        display.Update();
    }

    return 0;
}

Display.cpp

#include <iostream>
#include <GL/gl3w.h>
#include "Display.h"

Display::Display( int width, int height, const char* title ) {

    //Init GLFW
    if ( glfwInit() == 0 ) {
        std::cerr << "Could not initialise GLFW\n";
        return;
    } else {
        std::cout << "GLFW initialised\n";
    }

    //Window Hints
    glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
    glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 2 );
    glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
    glfwWindowHint( GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE );
    glfwWindowHint( GLFW_RESIZABLE, GL_FALSE );

    //Create Window
    m_window = glfwCreateWindow( width, height, title, NULL, NULL );

    //Make Context
    glfwMakeContextCurrent( m_window );

    //Initialise GL3W
    if ( gl3wInit() != 0 ) {
        std::cerr << "Could not init GL3W\n";
        return;
    } else {
        std::cout << "Initialised GL3W\n";
    }
}

Display::~Display() {

    //Delete Context
    glfwMakeContextCurrent( 0 );

    //Destroy Window
    glfwDestroyWindow( m_window );

    //Terminate GLFW
    glfwTerminate();
}

bool Display::CheckShouldClose() {

    return (bool)glfwWindowShouldClose( m_window );
}

void Display::Update() {

    //Swap Buffers
    glfwSwapBuffers( m_window );

    //Poll Events
    glfwPollEvents();
}

Mesh.cpp

#include <GL/gl3w.h>
#include <iostream>
#include "Mesh.h"

Mesh::Mesh( std::vector<float> verticies ) {

    m_verticies = verticies;

    //Generate VBO
    glGenBuffers( 1, &m_vbo );

    //Bind VBO
    glBindBuffer( GL_ARRAY_BUFFER, m_vbo );;

    //Pass Buffer Data
    glBufferData( GL_ARRAY_BUFFER, m_verticies.size() * sizeof( float), &m_verticies[0], GL_STATIC_DRAW );
}

Mesh::~Mesh() {

    glDeleteBuffers( 1, &m_vbo );
}

Shader.cpp

#include <fstream>
#include <iostream>
#include <vector>
#include <GL/gl3w.h>
#include "Shader.h"

#define SHADER_LIST { VERTEX_SHADER, FRAGMENT_SHADER }

Shader::Shader( std::string shaderName ) {

    //Load Source Code
    std::vector<std::string> shaderSources;
    shaderSources.push_back( loadShaderSource( shaderName + ".vert" ));
    shaderSources.push_back( loadShaderSource( shaderName + ".frag" ));

    //Cast into C-Style Strings
    const char* shaderSourcesCString[NUM_SHADER];
    for ( int i : SHADER_LIST ) {
        shaderSourcesCString[ i ] = shaderSources[ i ].c_str();
    }

    //Create Shaders
    m_shaders[ VERTEX_SHADER ]   = glCreateShader( GL_VERTEX_SHADER );
    m_shaders[ FRAGMENT_SHADER ] = glCreateShader( GL_FRAGMENT_SHADER );

    //Source Shaders
    glShaderSource( m_shaders[ VERTEX_SHADER ], 1, &shaderSourcesCString[ VERTEX_SHADER ], NULL );
    glShaderSource( m_shaders[ FRAGMENT_SHADER ], 1, &shaderSourcesCString[ FRAGMENT_SHADER ], NULL );

    //Compile Shaders
    for ( int i : SHADER_LIST ) {
        glCompileShader( m_shaders[ i ] );

        GLint status;
        glGetShaderiv( m_shaders[ i ], GL_COMPILE_STATUS, &status );

        if ( status != GL_TRUE ) {
            char buffer[512];
            glGetShaderInfoLog( m_shaders[ i ], 512, NULL, buffer );
            std::cerr << "Shader Compilation Error on shader " << i << ": " << buffer << "\n";
            return;
        }
    }

    //Create Program
    m_program = glCreateProgram();

    //Attach Shaders
    for ( int i : SHADER_LIST ) {
        glAttachShader( m_program, m_shaders[ i ] );
    }

    //Link Shader
    glLinkProgram( m_program );

    //Find Link Error
    {
        GLint status;
        glGetProgramiv(m_program, GL_LINK_STATUS, &status);

        if (status != GL_TRUE){
            std::cerr << "Unable to link shaders\n";

            char buffer[512];
            glGetProgramInfoLog(m_program, 512, NULL, buffer);
            std::cerr << buffer;
            return;
        }
    }

    //Bind outColor
    glBindFragDataLocation(m_program, 0, "outColor");

    //Attributes
    GLint posAttrib = glGetAttribLocation(m_program, "position");
    glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posAttrib);

    std::cout << "Shaders Compiled Successfully\n";
}

Shader::~Shader() {

    for ( int i : SHADER_LIST ) {
        //Detach Shader
        glDetachShader( m_program, m_shaders[ i ] );
        //Delete Shader
        glDeleteShader( m_shaders[ i ] );
    }

    //Delete Program
    glDeleteProgram( m_program );
}

std::string Shader::loadShaderSource( std::string filename ) {

    //Locals
    std::string output, line;

    //Open File
    std::fstream file;
    file.open( "Shaders/" + filename );

    //Check for error loading file
    if ( file.bad()) {
        std::cerr << "Could not load shader file: " << filename << "\n";
        return NULL;
    } else {
        std::cout << "Loaded shader file: " << filename << "\n";
    }

    //Read file into locals
    while ( file.good()) {
        getline( file, line );

        if ( line != "" )
            output += line + "\n";
    }

    //Return C-String
    return output;
}

void Shader::useShader() {

    glUseProgram( m_program );
}

GLuint Shader::getProgram() {

    return m_program;
}

这些是我的着色器

顶点着色器

#version 150 core

in vec2 position;

void main(){
    gl_Position = vec4(position, 0.0, 1.0);
}

片段着色器

#version 150 core

out vec4 outColor;

void main(){
    outColor = vec4(1.0, 1.0, 1.0, 1.0);
}

1 个答案:

答案 0 :(得分:2)

首先,您必须创建顶点数组缓冲区:

std::vector< GLfloat > verticies;
GLuint vbo;

glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (GLsizeiptr)verticies.size(), verticies.data(), GL_STATIC_DRAW);

连接着色器程序后,您必须确定顶点属性的索引:

GLuint prog = ...;
GLint posAttrLoc = glGetAttribLocation(prog, "position");

在绘制之前,您必须绑定并启用顶点属性:

  glBindBuffer(GL_ARRAY_BUFFER, vbo);
  glEnableVertexAttribArray(posAttrLoc );
  glVertexAttribPointer(posAttrLoc , 2, GL_FLOAT, GL_FALSE, 0, 0);
  glDrawArrays( GL_TRIANGLES, 0, 3 );