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, , &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 ;
}
运行结果:没错!

现在,修改vertexSource文件内容:

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

OpenGL——外部读档+异常报错的更多相关文章
- Python基础中所出现的异常报错总结
今天我们来探索python中大部分的异常报错 首先异常是什么,异常白话解释就是不正常,程序里面一般是指程序员输入的格式不规范,或者需求的参数类型不对应,不全等等. 打个比方很多公司年终送苹果笔记本,你 ...
- saiku中过滤窗口优化及隐藏异常报错
问题一:当取消自动查询后,点击该维度应弹出过滤条件窗口,实际无反应,只有执行一次查询后再点击该维度,才能弹出过滤条件窗口 解决办法:打开WorkspaceDropZone.js文件,找到selecti ...
- unity3d MonoDevelop引用外部自定义dll文件报错:are you missing an assembly reference?
在unity3d 编辑器 MonoDevelop 中引用外部自定义dll文件报错:are you missing an assembly reference? 因为unity还停留在.NET Fram ...
- (原创)vagrant up 异常报错,出现 There was an error while executing `VBoxManage` 的解决方法
最近在使用 vagrant homestead 时,不小心在虚拟机上使用了 exit 命令退出虚拟机,导致再使用 vagrant up 时出现以下错误: Bringing machine 'larav ...
- 【转】JAVA异常报错大全
算术异常类:ArithmeticExecption 空指针异常类:NullPointerException 类型强制转换异常:ClassCastException 数组负下标异常:NegativeAr ...
- Unity在OpenGL模式下Shader编译报错
报错信息 GLSL compilation failed: 0(21) : error C7528: OpenGL reserves names containing '__' 双击报错VS自动打开V ...
- idea运行javadoc生成文档以及 报错编码gbk的不可映射字符坑
将项目类信息生成文档 idea整合了javadoc的操作,可以一键生成doc文档 方法: 选中你要生成文档的项目 点击上方tools->Generate JavaDoc 运行即可 注意这里有一个 ...
- 执行文件异常报错:ImportError: attempted relative import with no known parent package
这个问题困扰了我很久了,网上的解决方法都很一致,找来找去都是一样的解决方法,在导入包的文件和执行文件加入 1 print('__file__={0:<35} | __name__={1:< ...
- SAP 调用RFC 的时候记录异常报错方式
DATA: lv_error TYPE char100. CALL FUNCTION 'ZRFC_WM_ZEL001' DESTINATION lv_desc EXPORTING process_fl ...
随机推荐
- VBS教程
Vbs是一种Windows脚本,它的全称是:Microsoft Visual Basic Script Editon.(微软公司可视化BASIC脚本版),VBS是Visual Basic的的一个抽象子 ...
- 解读vscode断点调试配置文件【待续】
一.参考链接 https://code.visualstudio.com/Docs/editor/debugging https://code.visualstudio.com/docs/nodejs ...
- NEO-Karl-Python1
第一个程序: print("NEO-Karl welcome to the new world")
- PeopleSoft如何查找jar包冲突
PeopleSoft要查找jar包冲突问题,不像maven可以打印出所有依赖,但既然是在JVM上运行,就可以启用JVM参数 路经:%ps_cfg_home%\appserv\Domain 文件名:ps ...
- Mac_IntelliJ IDEA For Mac 快捷键
Mac键盘符号和修饰键说明 ⌘ Command ⇧ Shift ⌥ Option ⌃ Control ↩︎ Return/Enter ⌫ Delete ⌦ 向前删除键(Fn+Delete) ↑ 上箭头 ...
- 分布式mongodb分片集群
本博客先简单介绍mongodb入门以及单实例以及mongodb的主从(主从官网是不提倡用的,原因后续介绍),副本集,分片. 第一:nosql介绍: 数据库分为关系型数据库与非关系型数据库,及具代表性的 ...
- Docker ElK安装部署使用教程
一.简介 1.核心组成 ELK由Elasticsearch.Logstash和Kibana三部分组件组成: Elasticsearch是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引 ...
- java线程的学习
接口 Runable 属性:target 方法:void run() 类 Thread 方法:void start()用来启动一个线程 void run() 线程启动后执行的方法 Sting getN ...
- jquery 实现tab切换
大家都知道 使用QQ的时候需要输入账号和密码 这个时候一个TAB键盘就可以实现切换到下一个输入框里 具体是怎么实现的呢 请看代码 <!DOCTYPE html> <html lang ...
- Cassandra最小化安装
Cassandra最小化安装 环境 CentOS 7.2 64位 IP_address:172.27.0.8 安装包装备 [root@master ~]# ll /usr/local/src tota ...