用glew,glfw实现opengl-学习笔记3着色器

代码实现了一个简单的三角形,并且使用着色器给三角形着色,参考这篇教程书写的点击打开链接   这个教程中的源代码链接不好的话到它的英文版找源码连接

shader.h代码

#ifndef SHADER_H
#define SHADER_H
#include<string>
#include<fstream>
#include<sstream>
#include<iostream>
#include<GL/glew.h>
using namespace std;
class Shader
{
public:
	//程序的ID
	GLuint Program;
	//读取渲染程序并创建Shader
	Shader(const GLchar * vertexSourcePath,const GLchar *fragmentSource);
	{
		//1.从文件路径获得vertex/fragment源码
		string vertexCode;
		string fragmentCode;
		try{
			//打开文件Open files
			ifstream vShaderFile(vertexPath);
			ifstream fShaderFile(fragmentPath);

			stringstream vShaderStream,fShaderStream;
			//读取文件缓冲到流、
			vShaderStream<<vShaderFile.rdbuf();
			fShaderStream<<fShaderFile.rdbuf();

			//关闭文件句柄
			vShaderFile.close();
			fShaderFile.close();
			//将流转为GLchar数组
			 vertexCode = vShaderStream.str(); 
        fragmentCode = fShaderStream.str(); 
		}
		catch(std::exception e) 
    { 
        std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;  
    }
		const GLchar* vShaderCode = vertexCode.c_str();
        const GLchar * fShaderCode = fragmentCode.c_str();
        // 2.编译着色器
        GLuint vertex, fragment;
        GLint success;
        GLchar infoLog[512];
        // 顶点着色器
        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);
            std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
        }
        // 片段着色器
        fragment = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragment, 1, &fShaderCode, NULL);
        glCompileShader(fragment);
        // 打印是否有任何错误
        glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(fragment, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
        }
        // 着色器程序
        this->Program = glCreateProgram();
        glAttachShader(this->Program, vertex);
        glAttachShader(this->Program, fragment);
        glLinkProgram(this->Program);
        // 打印是否有错误
        glGetProgramiv(this->Program, GL_LINK_STATUS, &success);
        if (!success)
        {
            glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
        }
        // 删除着色器程序
        glDeleteShader(vertex);
        glDeleteShader(fragment);
	}
	//使用Program
	void Use();
	{
glUseProgram(this->Program);
	}
}
#endif
shader.cpp代码

#include<iostream>
//GLew
#define GLEW_STATIC
#include<GL/glew.h>
#include<FreeImage.h>
//GLFW
#include<GLFW/glfw3.h>
//着色器头文件
#include<shader.h>
using namespace std;
//函数原型
void key_callback(GLFWwindow* window,int key,int scancode,int action,int mode);
//窗口尺寸
const GLuint WIDTH=800,HEIGHT=600;
//主函数
int main()
{
	//I初始化GLFW
	glfwInit();
	//设置全部GLFW要求的设置
	 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
	

	//创造一个GLFWwindow 项目 我们可以使用GLFW的功能
	GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);
    glfwMakeContextCurrent(window);
	//设置回调函数的注册
	glfwSetKeyCallback(window, key_callback);

	//glew设置为true  让glew知道使用现在的方法去恢复指针和扩展
	glewExperimental = GL_TRUE;
	//初始化glew 去设置opengl功能指针
	 glewInit();
	//定义和编译我们的着色器程序
	 Shader ourShader("D:/C语言/openglflew/shader/shader.vs", "D:/C语言/openglflew/shader/shader.frag");
	 //设置顶点数据(和缓冲)和属性指针
	 GLfloat vertices[] = {
        // 顶点颜色        // 颜色
        0.5f, -0.5f, 0.0f,   1.0f, 0.0f, 0.0f,  // 右下方
       -0.5f, -0.5f, 0.0f,   0.0f, 1.0f, 0.0f,  // 左下方
        0.0f,  0.5f, 0.0f,   0.0f, 0.0f, 1.0f   // 上面顶点
	 };
	 //获取ID
	 GLuint VBO, VAO;
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
	//首先绑定顶点数组对象,然后绑定和设置顶点缓存和属性指针
	glBindVertexArray(VAO);
	 glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

	//位置属性
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
	 glEnableVertexAttribArray(0);//启动
	//颜色属性
	 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1);
	 glBindVertexArray(0);//解绑VAo
	 //循环
	 while (!glfwWindowShouldClose(window))
    {
      
		//检查任何事件 有活动(按键和移动鼠标等等)并且调用当前响应的功能
        glfwPollEvents();

        // 渲染
        // 清楚颜色缓存
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        // 画三角形
        ourShader.Use();
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glBindVertexArray(0);

        // 释放屏幕的缓存
        glfwSwapBuffers(window);
    }
 glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    // Terminate GLFW, clearing any resources allocated by GLFW.
    glfwTerminate();
    return 0;
}
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}
像素着色器shader.frag代码(后缀frag可以随便通常是frag,在记事本中直接把代码书写完后更改文件后缀就可以)

#version 330 core 
in vec3 ourColor; 
out vec4 color; 
void main() 
{ 
    color = vec4(ourColor, 1.0f); 
}

顶点着色器shader.vs代码

#version 330 core 
layout (location = 0) in vec3 position; // 位置变量的属性position为 0 
layout (location = 1) in vec3 color; // 颜色变量的属性position为 1 
 
out vec3 ourColor; // 向fragment shader输出一个颜色 
 
void main() 
{ 
    gl_Position = vec4(position, 1.0); 
    ourColor = color; // 把ourColor设置为我们从顶点数据那里得到的输入颜色
}

运行的效果图




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值