zoukankan      html  css  js  c++  java
  • OpenGL——外部读档+异常报错

    从外部读取shader文件:

    先添加Shader类:

    再创建vertexSource.txt和fragmentSource.txt两个文件:

    如图填入shader:

    在shader.h宣告:

     在shader.cpp中从外部读档:

    #include "Shader.h"
    #include <iostream>
    #include<fstream>
    #include <sstream>
    #define GLEW_STATIC
    #include <GL/glew.h>
    #include <GLFW/glfw3.h>
    
    using namespace std;
    
    Shader::Shader(const char* vertexPath,const char* fragmentPath)
    { // 1. 从文件路径中获取顶点/片段着色器
        ifstream vertexFile;
        ifstream fragmentFile;
        stringstream vertexSStream;
        stringstream fragmentSStream;
    
        // 打开文件
        vertexFile.open(vertexPath);
        fragmentFile.open(fragmentPath);
        vertexFile.exceptions(ifstream::failbit || ifstream::badbit);
        fragmentFile.exceptions(ifstream::failbit || ifstream::badbit);
    
        try
        {
            if (!vertexFile.is_open()||!fragmentFile.is_open())//没有打开,丢出异常
            {
                throw exception("open file error");
            }
            vertexSStream << vertexFile.rdbuf();//从硬盘读取资料
            fragmentSStream << fragmentFile.rdbuf();//从硬盘读取资料
    
            vertexString = vertexSStream.str();//转成字符串
            fragmentString = fragmentSStream.str();
    
            vertexSource = vertexString.c_str();
            fragmentSource = fragmentString.c_str();
             
            unsigned int vertex, fragment;
    
            vertex = glCreateShader(GL_VERTEX_SHADER);
            glShaderSource(vertex, 1, &vertexSource, NULL);
            glCompileShader(vertex);
            checkCompileErrors(vertex, "VERTEX");//异常报错提示
    
            fragment = glCreateShader(GL_FRAGMENT_SHADER);
            glShaderSource(fragment, 1, &fragmentSource, NULL);
            glCompileShader(fragment);
            checkCompileErrors(fragment, "FRAGMENT");//异常报错提示
    
            ID = glCreateProgram();
            glAttachShader(ID, vertex);
            glAttachShader(ID, fragment);
            glLinkProgram(ID);
            checkCompileErrors(ID, "PROGRAM");//异常报错提示
    
            glDeleteShader(vertex);
            glDeleteShader(fragment);
    
        }
        catch (const std::exception&ex)
        {
            printf(ex.what());//如果错误就跳到这执行 
        }
    }
    
    void Shader::use() {
        glUseProgram(ID);
    }
    
    void Shader::checkCompileErrors(unsigned int ID, std::string type) //宣告
    {//测试报错
        int success;
        char infoLog[512];
    
        if (type!="PROGRAM")
        {
            glGetShaderiv(ID, GL_COMPILE_STATUS, &success);
            if (!success) {
                glGetShaderInfoLog(ID, 512, NULL, infoLog);
                cout << "shader compile error:" << infoLog << endl;
            }
        }
        else
        {
            glGetProgramiv(ID, GL_LINK_STATUS, &success);
            if (!success)
            {
                glGetProgramInfoLog(ID, 512, NULL, infoLog);
                cout << "progam Linking error:" << infoLog << endl;
            }
        }
    };

    main.cpp写入:

    #include <iostream>
    #define GLEW_STATIC
    #include <GL/glew.h>
    #include <GLFW/glfw3.h>
    #include "Shader.h"
    
    float vertices[] = {
            -0.5f,-0.5f,0.0f,1.0f,0,0,
            0.5f,-0.5f,0.0f,0,1.0f,0,
            0.5f,0.5f,0.0f,0,0,1.0f,
            -0.5f,0.5f,0.0f,1.0f,0,1.0f
    };
    
    unsigned int indices[] = { // 注意索引从0开始! 
        0, 1, 2,  //第一个三角形
        0, 2, 3   //第二个三角形
    };
    
    
    //函数在main之前存档
    void processInput(GLFWwindow* window) {
        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        {//退出键关闭窗口
            glfwSetWindowShouldClose(window, true);
        }
    }
    int main(int argc, char* argv[]) {
    
        glfwInit();//初始化和创建窗口
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//提示用主版本号为3
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);//次版本号为3,即为3.3版本的OpenGL
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    
        //open GLFW window
        GLFWwindow* window = glfwCreateWindow(800, 600, "Test window", NULL, NULL);//800*600的窗口
    
        if (window == NULL) {//如果为空指针
            //std::cout << "open window failed." << std::endl;//打印失败
            printf("open window failes.");
            glfwTerminate();//终止
            return -1;
            //return EXIT_FAILURE;
        }
    
        glfwMakeContextCurrent(window);
    
        //init GLEW
        glewExperimental = true;
    
        if (glewInit() != GLEW_OK)
        {
            printf("Init GLEW failed.");
            //std::cout << "glew init failed." << std::endl;
            glfwTerminate();
            return -1;//-1代表不正常退出
        }
    
        glViewport(0, 0, 800, 600);//前两个参数控制窗口左下角的位置,后两个参数设置可绘制的像素大小
    
        //第一个参数表示我们打算将其应用到所有的三角形的正面和背面,第二个参数告诉我们用线来绘制
        //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//线框模式
        //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);//关掉线框模式
    
        Shader* myshader = new Shader("vertexSource.txt", "fragmentSource.txt");//指针调用
    
        unsigned int VAO;
        glGenVertexArrays(1, &VAO);
        glBindVertexArray(VAO);
    
        unsigned int VBO;//顶点缓冲对象
        glGenBuffers(1, &VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);//顶点缓冲对象的缓冲类型是GL_ARRAY_BUFFER,使用glBindBuffer函数把新创建的缓冲绑定到GL_ARRAY_BUFFER目标上
        //调用glBufferData函数,它会把之前定义的顶点数据复制到缓冲的内存中
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
        
        unsigned int EBO;
        glGenBuffers(1, &EBO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    
        //顶点属性,顶点属性的大小(vec3),数据类型,是否数据被标准化,步长,强制类型转换(表示位置数据在缓冲中起始位置的偏移量)
        glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
        glEnableVertexAttribArray(6);//启用顶点属性
        glVertexAttribPointer(7, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3*sizeof(float)));
        glEnableVertexAttribArray(7);//启用顶点属性
        while (!glfwWindowShouldClose(window))
        {
    
            processInput(window);
            glClearColor(0.2f, 0.3f, 0.3f, 1.0);//清屏颜色填充RGB,透明度
            glClear(GL_COLOR_BUFFER_BIT);
    
            glBindVertexArray(VAO);
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    
            myshader->use();
            glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);//改为glDrawElements即可。6为索引个数,0表示偏移。
            glfwSwapBuffers(window);
            glfwPollEvents();
        }
    
        glfwTerminate();
    
        return 0;
    }

     运行结果:没错!

     现在,修改vertexSource文件内容:

     运行:没出现图像,并且命令窗口报异常。

    莫说我穷的叮当响,大袖揽清风。 莫讥我困时无处眠,天地做床被。 莫笑我渴时无美酒,江湖来做壶。
  • 相关阅读:
    HTML和CSS 基本要点必看
    CSS
    六个选择器
    HTML初级课程 (自学可懂)
    this
    1.作用域链
    js if 语句
    js数据类型
    ifelse语句
    三元运算符
  • 原文地址:https://www.cnblogs.com/huang--wei/p/10571940.html
Copyright © 2011-2022 走看看