- 新加项Shader.h
#pragma once
#include<string>
class Shader
{
public:
Shader();
Shader(const char * vertexPath, const char * fragmentPath);
//cpu中的string 和 char*
std::string vertexString;
std::string fragmentString;
const char* vertexSource;
const char* fragmentSource;
};
- 新加项Shader.cpp
#include "Shader.h"
#include<iostream>
#include<fstream>
#include<sstream>
using namespace std;
Shader::Shader()
{
}
Shader::Shader(const char* vertexPath, const char* fragmentPath)
{
ifstream vertexFile;
ifstream fragmentFile;
stringstream vertexSStream;
stringstream fragmentSStream;//先是file 然后再转化为String(memory中)
//打开文件,还没有写入内存
vertexFile.open(vertexPath);
fragmentFile.open(fragmentPath);
//异常查询
vertexFile.exceptions(ifstream::failbit || ifstream::badbit);
fragmentFile.exceptions(ifstream::failbit || ifstream::badbit);
try//异常检测机制
{
if (!vertexFile.is_open())
{
throw exception("open file erro");//如果检测到异常则丢出一个open file erro
}
vertexSStream << vertexFile.rdbuf();
fragmentSStream << fragmentFile.rdbuf(); //把内存中的file转为string
vertexString = vertexSStream.str();
fragmentString = fragmentSStream.str();
vertexSource = vertexString.c_str();
fragmentSource = fragmentString.c_str();
//printf(vertexSource);
printf(fragmentSource);
}
catch (const std::exception& ex)
{
printf(ex.what());
}
}
- 加入vertexSource和fragmentSource txt文档
这两个文档就是我们需要读入的着色器
里面写入着色器的内容
vertexSource:
#version 330 core
layout (location = 7) in vec3 aPos;
layout (location = 8) in vec3 aColor;
out vec4 vertexColor;
void main(){
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
vertexColor = vec4(aColor.x,aColor.y,aColor.z,1.0);
}
fragmentSource:
#version 330 core
in vec4 vertexColor;
uniform vec4 ourColor;
out vec4 FragColor;
void main(){
FragColor = vertexColor;
}
具体的流程如下:
文件:
ifstream vertexFile;
ifstream fragmentFile;
string:
stringstream vertexSStream;
stringstream fragmentSStream;//先是file 然后再转化为String(memory中)
memory :从文件到string
vertexSStream << vertexFile.rdbuf();
fragmentSStream << fragmentFile.rdbuf();
CPU:从string(memory)到string(cpu)
vertexString = vertexSStream.str();
fragmentString = fragmentSStream.str();
CPU:从string (CPU)到 char
vertexSource = vertexString.c_str();
fragmentSource = fragmentString.c_str();
如下图所示:
C++
rdbuf() 可以实现一个流对象指向的内容用另一个流对象来输出,比如想把 一个文件的内容输出到显示器上,我们可以两行代码完成:
ifstream infile("test.txt");
cout << infile.rdbuf();
c_str(): 返回const char*类型(可读不可改)的指向字符数组的指针
课程参考:傅老师OpenGL