LearnOpenGL(二) 自己写一个从文件流读取顶点和片段着色器并创建Shader Program的类

头文件(Shader.h)

#ifndef SHADER_H
#define SHADER_H

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <GL/glew.h>

class Shader
{
public:
	// 程序ID
	GLuint Program;
	// 构造器读取并构建着色器
	Shader(const GLchar* vertexPath, const GLchar* fragmentPath);
	// 使用程序
	void Use();
};

#endif

cpp(Shader.cpp)

#include <ShaderDemo.h>
#include <SOIL2.h>
using namespace std;
Shader::Shader (const GLchar* vertexPath, const GLchar* fragmentPath) {
	std::string vertexCode;
	std::string fragmentCode;
	std::ifstream vShaderFile;
	std::ifstream fShaderFile;
	vShaderFile.exceptions(std::ifstream::badbit);
	fShaderFile.exceptions(std::ifstream::badbit);
	cout << vertexPath << endl;
	cout << fragmentPath << endl;
	try {
		vShaderFile.open(vertexPath);
		fShaderFile.open(fragmentPath);
		std::stringstream vShaderStream, fShaderStream;
		//缓冲
		vShaderStream << vShaderFile.rdbuf();
		fShaderStream << fShaderFile.rdbuf();
		 
		vShaderFile.close();
		fShaderFile.close();

		vertexCode = vShaderStream.str();
		fragmentCode = fShaderStream.str();

		cout << vertexCode << endl;
		cout << fragmentCode << endl;
	}
	catch (std::ifstream::failure e)
	{
		std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULIY_RED" << std::endl;
	}
	const GLchar* vShaderCode = vertexCode.c_str();
	const GLchar* fShaderCode = fragmentCode.c_str();

	GLuint vertex, fragment;
	GLchar infoLog[512];
	GLint success;
	vertex = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(vertex, 1, &vShaderCode, NULL);
	glCompileShader(vertex);
	glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
	if (!success) {
		glGetShaderInfoLog(vertex, 512, NULL, infoLog);
		cout << "error::" << infoLog << endl;
	}

	GLint success2;
	fragment = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(fragment, 1, &fShaderCode, NULL);
	glCompileShader(fragment);
	glGetShaderiv(fragment, GL_COMPILE_STATUS, &success2);
		if (!success2) {
			glGetShaderInfoLog(fragment, 512, NULL,infoLog);
			cout << "error:" << infoLog << endl;
	}
		  
	if (success2 && success) {
		this->Program = glCreateProgram();
		glAttachShader(this->Program, vertex);
		glAttachShader(this->Program, fragment);
		glLinkProgram(this->Program);
		glGetProgramiv(this->Program,512, &success);
			if (!success) {
				glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
				cout << "error" << infoLog << endl;
		}
	}
	glDeleteShader(vertex);
	glDeleteShader(fragment);
};

void Shader::Use() {
	glUseProgram(this->Program);
}

顶点着色器文件(shader.vs)

#version 330
layout(location = 0) in vec3 position;
uniform vec3 pos;
uniform float x;
out vec3 outPos;
void main(){
	gl_Position = vec4(position.x + x,position.y,position.z,1.0);
	outPos = vec3(position);
};

片段着色器文件(shader.frag)

#version 330
in vec3 outPos;
uniform vec4 ourColor;
out vec4 color;
void main(){
	color = vec4(outPos,0.1f);
};

如何使用?

// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h> 
#include <iostream>
#include <string>
#include <ShaderDemo.h>
#include <SOIL2.h>
using namespace std;

int main()
{
	glewExperimental = GL_TRUE;
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
	glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
	glfwWindowHint(GLFW_CENTER_CURSOR, GL_TRUE);

	GLFWmonitor* currMonitor = glfwGetPrimaryMonitor();
	const GLFWvidmode *mode = glfwGetVideoMode(currMonitor);
	GLFWwindow* window = glfwCreateWindow(mode->width, mode->height, "LearnOpenGL2", nullptr, nullptr);
	glfwMakeContextCurrent(window);
	glewInit();
	if (window == nullptr)
	{
		//cout << "Failed to create GLFW window" << endl;
		glfwTerminate();
		return -1;
	}
	GLfloat i = 0;
    //使用我们之前创建的类
	Shader  shader = Shader("F:/wh/Glew/FirstGlew/FirstGlew/shader/shader.vs", "F:/wh/Glew/FirstGlew/FirstGlew/shader/shader.frag");
	GLfloat  vertex[] = {
		-0.5f,-0.5f,0.0f,
		0.5f,-0.5f,0.0f,
		0.0f,0.5f,0.0f,
	};

	GLfloat  vertex2[] = {
	0.5f, 0.5f, 0.0f,   // 右上角
	0.5f, -0.5f, 0.0f,  // 右下角
	-0.5f, -0.5f, 0.0f, // 左下角
	-0.5f, 0.5f, 0.0f   // 左上角
	};

	GLuint index[] = {
		0,1,3,
		1,2,3
	};

	GLfloat colours[] = {
	  1.0f, 0.0f,  0.0f,
	  0.0f, 1.0f,  0.0f,
	  0.0f, 0.0f,  1.0f,
	  1.0f, 0.0f,  0.0f,
	  0.0f, 1.0f,  0.0f,
	  0.0f, 0.0f,  1.0f,
	};
	GLuint VAO;//顶点数组对象
	glGenVertexArrays(1, &VAO);
	glBindVertexArray(VAO);//后面的VBO操作会被记录到该顶点数组对象,后面能直接用

	GLuint VBO;
	glGenBuffers(1, &VBO);//创建顶点缓冲对象(空),创建显存空间
	glBindBuffer(GL_ARRAY_BUFFER, VBO);//缓冲对象绑定到缓冲区,一个缓冲区只能有一个缓冲对象, 不然后面写入缓冲区不知道写入哪个对象,但是一个缓冲对象可以绑定多个缓冲区
	glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);//往缓冲区中的对象写入数据c
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);//设置顶点属性指针,使用的是此时绑定到GL_ARRAY_BUFFER的VBO顶点缓冲对象
	glEnableVertexAttribArray(0);//启用顶点属性,参数是顶点属性的位置
	glBindVertexArray(0);//后面的VBO操作会被记录到该顶点数组对象,后面能直接用

	while (!glfwWindowShouldClose(window))
	{
		i += 0.01;
		glClear(GL_COLOR_BUFFER_BIT);
		glUseProgram(shader.Program);
		GLint vertexColorLocation = glGetUniformLocation(shader.Program, "ourColor");
		GLint x = glGetUniformLocation(shader.Program, "x");
		GLint pos = glGetUniformLocation(shader.Program, "pos");
		
		if (vertexColorLocation == 1) {
			cout << "ok" << endl;
		}
		GLfloat time = glfwGetTime();
		GLfloat greenValue = (sin(time) / 2) + 0.5;
		glUniform4f(vertexColorLocation, greenValue, 0.0f, 0.0f, 0.0f);
		glUniform1f(x, i);
		glBindVertexArray(VAO);
		glDrawArrays(GL_TRIANGLES, 0, 3);
		glBindVertexArray(0);
		glfwPollEvents();
		glfwSwapBuffers(window);
	}
	glfwTerminate();
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值