OpenGL——外部读档+异常报错

时间:2021-12-27 23:42:14

从外部读取shader文件:

先添加Shader类:

OpenGL——外部读档+异常报错

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

OpenGL——外部读档+异常报错

如图填入shader:

OpenGL——外部读档+异常报错

OpenGL——外部读档+异常报错

在shader.h宣告:

OpenGL——外部读档+异常报错

在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, , &vertexSource, NULL);
glCompileShader(vertex);
checkCompileErrors(vertex, "VERTEX");//异常报错提示 fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, , &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[]; if (type!="PROGRAM")
{
glGetShaderiv(ID, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(ID, , NULL, infoLog);
cout << "shader compile error:" << infoLog << endl;
}
}
else
{
glGetProgramiv(ID, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(ID, , 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.5f,-0.5f,0.0f,,1.0f,,
0.5f,0.5f,0.0f,,,1.0f,
-0.5f,0.5f,0.0f,1.0f,,1.0f
}; unsigned int indices[] = { // 注意索引从0开始!
, , , //第一个三角形
, , //第二个三角形
}; //函数在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
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, );//次版本号为3,即为3.3版本的OpenGL
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //open GLFW window
GLFWwindow* window = glfwCreateWindow(, , "Test window", NULL, NULL);//800*600的窗口 if (window == NULL) {//如果为空指针
//std::cout << "open window failed." << std::endl;//打印失败
printf("open window failes.");
glfwTerminate();//终止
return -;
//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代表不正常退出
} glViewport(, , , );//前两个参数控制窗口左下角的位置,后两个参数设置可绘制的像素大小 //第一个参数表示我们打算将其应用到所有的三角形的正面和背面,第二个参数告诉我们用线来绘制
//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(, &VAO);
glBindVertexArray(VAO); unsigned int VBO;//顶点缓冲对象
glGenBuffers(, &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(, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); //顶点属性,顶点属性的大小(vec3),数据类型,是否数据被标准化,步长,强制类型转换(表示位置数据在缓冲中起始位置的偏移量)
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*));
glEnableVertexAttribArray();//启用顶点属性
glVertexAttribPointer(, , GL_FLOAT, GL_FALSE, * sizeof(float), (void*)(*sizeof(float)));
glEnableVertexAttribArray();//启用顶点属性
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, , GL_UNSIGNED_INT, );//改为glDrawElements即可。6为索引个数,0表示偏移。
glfwSwapBuffers(window);
glfwPollEvents();
} glfwTerminate(); return ;
}

运行结果:没错!

OpenGL——外部读档+异常报错

现在,修改vertexSource文件内容:

OpenGL——外部读档+异常报错

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

OpenGL——外部读档+异常报错