OpenGL程序未显示彩色三角形,而是黑色,即使我同时加载了两个着色器

时间:2018-11-14 01:47:41

标签: c++ opengl graphics fragment-shader vertex-shader

更新: 我通过将类对象Mesh和ShaderLoader创建为指针并将其初始化为new ShaderLoader();来解决了该问题。 我不明白为什么有人可以告诉我那有帮助吗?

我已经开始学习OpenGL,并决定看看我学到了什么。 因此,我创建了此代码,使其可以仅在屏幕上显示三角形。

这是我的顶点着色器:

#version 330                                                                  

layout (location = 0) in vec3 pos;                                           

out vec4 vCol;                                                              

uniform mat4 model;                                                          
uniform mat4 projection;         
uniform mat4 view;

void main()                                                                   
{                                                                            
    gl_Position = vec4(pos, 1.0);                                    
    vCol = vec4(clamp(pos, 0.0f, 1.0f), 1.0);                                 
}

这是我的片段着色器:

#version 330                                                                  

in vec4 vCol;                                                                

out vec4 colour;                                                             

void main()                                                                  
{                                                                             
    colour = vCol;                                                       
}

这是负责加载名为ShaderLoader的着色器的代码

#pragma once

    #include <iostream>
    #include <GL/glew.h>
    #include <fstream>
    #include <cstring>


    using namespace std;

    class ShaderLoader {
    public:
        char *code; // test public variable

        ShaderLoader();
        ~ShaderLoader();

        void clear();
        ShaderLoader(const char *vertexPath, const char *fragmentPath);
        void AddShaders(GLuint referenceProgram, const char *sourceCode, GLenum referenceEnum);
        char* readFile(const char* fileLocation);
        void useProgram();

        GLuint getProjection() { return uniformProjection; }
        GLuint getModel() { return uniformModel; }
        GLuint getView() { return uniformView; }

    private:
        GLuint program, uniformModel, uniformProjection, uniformView;


    };





    #include "ShaderLoader.h"
    ShaderLoader::ShaderLoader()
    {
        program = 0;
        uniformModel = 0;
        uniformProjection = 0;
        uniformView = 0;
        code = nullptr;
    }
    void ShaderLoader::clear()
    {
        if (program != 0)
        {
            glDeleteProgram(program);
            program = 0;
        }
        uniformModel = 0;
        uniformProjection = 0;
        uniformView = 0;
    }
    ShaderLoader::~ShaderLoader()
    {
        clear();

    }
    char* ShaderLoader::readFile(const char* fileLocation)
    {
        bool firstCopy = true;
        char *continuation = new char[1024];
        code = new char[10000];
        ifstream file(fileLocation, ios::in);
        if (!file.is_open())
        {
            cout << "Cannot open " << fileLocation << endl;
            file.close();
            return nullptr;
        }
        while (!file.eof())
        {
            char *line = new char[1024];
            file.getline(line, strlen(line) - 1);
            if (!firstCopy)
            {
                strcat_s(code, 10000, "\n");
                strcat_s(code, 10000, line);
            }
            if (firstCopy)
            {
                strcpy_s(code, 10000, line);
                firstCopy = false;
            }
            delete[] line;
        }
        file.close();
        delete[] continuation;
        return code;
    }
    void ShaderLoader::AddShaders(GLuint referenceProgram, const char *sourceCode, GLenum referenceEnum)
    {
        GLuint shader = glCreateShader(referenceEnum);
        if (!shader)
        {
            cout << " Could not create shader." << endl;
            return;
        }
        const GLchar *src[1];
        src[0] = sourceCode;
        GLint size[1];
        size[0] = strlen(sourceCode);


        GLchar log[1024] = { 0 };
        int success = 0;
        glShaderSource(shader, 1, src, size);
        glCompileShader(shader);

        glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(shader, sizeof(log), nullptr, log);
            cout << "Shader compilation failed: " << log <<endl;
            return;
        }
        glAttachShader(program, shader);

    }
    ShaderLoader::ShaderLoader(const char *vertexPath, const char *fragmentPath)
    {

         char *vertexSource = readFile(vertexPath);
         char *fragmentSource = readFile(fragmentPath);

        cout << vertexSource << endl;
        cout << fragmentSource << endl;
        program = glCreateProgram();
        if (!program)
        {
            std::cout << "Could not create program" << std::endl;
        }
        AddShaders(program, vertexSource, GL_VERTEX_SHADER);
        AddShaders(program, fragmentSource, GL_FRAGMENT_SHADER);
        GLchar log[1024] = { 0 };
        int success = 0;

        glLinkProgram(program);
        glGetProgramiv(program, GL_LINK_STATUS, &success);
        if (!success)
        {
            glGetProgramInfoLog(program, sizeof(log), nullptr, log);
            cout << "Program linking failed: " << log << endl;
            return;
        }

        glValidateProgram(program);
        glGetProgramiv(program, GL_VALIDATE_STATUS, &success);
        if (!success)
        {
            glGetProgramInfoLog(program, sizeof(log), nullptr, log);
            cout << "Program validation failed: " << log << endl;
            return;
        }
        delete[] code;
        //uniformModel = glGetUniformLocation(program, "model");
        //uniformProjection = glGetUniformLocation(program, "projection");
        //uniformView = glGetUniformLocation(program, "view");
    }
    void ShaderLoader::useProgram()
    {
        glUseProgram(program);
    }

现在,代码用于加载和显示名为 Mesh 的三角形之类的网格:

#pragma once
#include <GL/glew.h>
#include <iostream>
using namespace std;
class Mesh
{
public:
    Mesh();
    ~Mesh();

    void createMesh(GLfloat *vertices, unsigned int *indices, unsigned int numOfVertices, unsigned int numOfIndices);
    void clearMesh();
    void displayMesh();

private:
    GLuint VAO, VBO, IBO;
    GLsizei indexCount;
};



#include "Mesh.h"



Mesh::Mesh()
{
    VAO = 0;
    VBO = 0;
    IBO = 0;
    indexCount = 0;
}


Mesh::~Mesh()
{
    clearMesh();
}


void Mesh::createMesh(GLfloat *vertices, unsigned int *indices, unsigned int numOfVertices, unsigned int numOfIndices)
{

    indexCount = numOfIndices;

    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * numOfVertices, vertices, GL_STATIC_DRAW);

    glGenBuffers(1, &IBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * numOfIndices, indices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);


    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

}


void Mesh::displayMesh()
{

    glBindVertexArray(VAO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
    glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

}



void Mesh::clearMesh()
{
    if (VAO != 0)
    {
        glDeleteVertexArrays(1, &VAO);
        VAO = 0;
    }
    if (VBO != 0)
    {
        glDeleteBuffers(1, &VBO);
        VBO = 0;
    }
    if (IBO != 0)
    {
        glDeleteBuffers(1, &IBO);
        IBO = 0;
    }


    indexCount = 0;

}

最后是MAIN:

#include <iostream>
#include "ShaderLoader.h"
#include "Mesh.h"
#include "GLFW/glfw3.h"
#include <GL/glew.h>
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include <gtc/type_ptr.hpp>


const int SCREEN_WIDTH = 800, SCREEN_HEIGHT = 600; 
int screenWidth, screenHeight;


Mesh triangle1;
Mesh triangle2;
ShaderLoader shader;

const char* vertexPath = "resources/shaders/shader.vs";
const char* fragmentPath = "resources/shaders/shader.fs";

void createObjects()
{

    unsigned int indices[] = {
        0, 3, 1,
        1, 3, 2,
        2, 3, 0,
        0, 1, 2
    };

    GLfloat vertices[] = {
        -1.0f, -1.0f, 0.0f,
        0.0f, -1.0f, 1.0f,
        1.0f, -1.0f, 0.0f,
        0.0f, 1.0f, 0.0f
    };

    triangle1 = Mesh();
    triangle1.createMesh(vertices, indices, 12, 12);

    triangle2 = Mesh();
    triangle2.createMesh(vertices, indices, 12, 12);

    cout << "Objects created" << endl;
}

void enableShaders()
{
    shader = ShaderLoader(vertexPath, fragmentPath);
    cout << "Shaders enabled" << endl;

}

int main()
{
    if (!glfwInit())
    {

        cout << "Could not initialize glfw." << endl;
        glfwTerminate();
        return 1;

    }

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
    glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);

    GLFWwindow *window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "GoldSpark Engine Test", nullptr, nullptr);

    glfwGetFramebufferSize(window, &screenWidth, &screenHeight);

    if (window == nullptr)
    {
        cout << "Window could not be created." << endl;
        glfwDestroyWindow(window);
        glfwTerminate();
    }
    glfwMakeContextCurrent(window);

    if (glewInit() != GLEW_OK)
    {
        cout << "Could not initialize GLEW";
        glfwDestroyWindow(window);
        glfwTerminate();
        return 1;
    }

    glewExperimental = true;

    glEnable(GL_DEPTH_TEST);

    enableShaders();
    createObjects();
    glViewport(0, 0, screenWidth, screenHeight);

    while(!glfwWindowShouldClose(window))
    {

        glfwPollEvents();

        glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


        shader.useProgram();
        triangle1.displayMesh();
        glUseProgram(0);

        glfwSwapBuffers(window);
    }

    triangle1.clearMesh();
    triangle2.clearMesh();
    shader.clear();
    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}

我试图在这里找到为什么我的三角形没有变色而我不能。我尝试将片段着色器中的变量 color 初始化为 vec4(1.0f,0.0f,0.0f,1.0f) >但它仍然没有画出来。三角形仍然是黑色。我在这里想念什么,谁能告诉我?

如果您发现这很复杂,请阅读github代码,以便您可以复制/粘贴并查看出了什么问题:

Link to this Code on my github

0 个答案:

没有答案