用glew,glfw实现opengl-学习笔记3着色器
代码实现了一个简单的三角形,并且使用着色器给三角形着色,参考这篇教程书写的点击打开链接 这个教程中的源代码链接不好的话到它的英文版找源码连接shader.h代码#ifndef SHADER_H#define SHADER_H#include#include#include#include#includeusing namespace std;class Shader{
·
代码实现了一个简单的三角形,并且使用着色器给三角形着色,参考这篇教程书写的点击打开链接 这个教程中的源代码链接不好的话到它的英文版找源码连接
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设置为我们从顶点数据那里得到的输入颜色
}
运行的效果图
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
已为社区贡献1条内容
所有评论(0)