GLSL着色器

1|0uniform

顶点着色器的输出out和片段着色器的输入in变量名一样的话可以由链接器将他们连接起来。
uniform是全局的,变量名必须独一无二,它允许cpu向gpu传数据,要先useShaderProgram才能更改uniform的值,在更改之前要获得位置,获得位置可以在useprogram之前。

2|0顶点包含多个属性

在顶点加颜色值,顶点pointer那里的初始地址、size、偏移都需要改,激活顶点的位置为1

#include<glad/glad.h> #include<GLFW/glfw3.h> #include<iostream> const char *vertexShaderSource = "#version 330 core\n" "layout (location = 0) in vec3 aPos;\n" "layout (location = 1) in vec3 aColor;\n" "out vec4 color;" "void main()\n" "{\n" " color = vec4(aColor, 1.0);\n" " gl_Position = vec4(aPos, 1.0);\n" "}\0"; const char *fragmentShaderSource = "#version 330 core\n" "out vec4 FragColor;" "in vec4 color;" "void main()\n" "{\n" " FragColor = color;" "}\0"; void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } void processInput(GLFWwindow* window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); } int main() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //创建窗口对象 GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL); if (window == NULL) { std::cout << "Failed to create" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); //初始化GLAD管理指针,加载系统OpenGL函数指针 if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout << "Failed to init GLAD" << std::endl; return -1; } glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); //shader unsigned int vertexShader; vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); glCompileShader(vertexShader); unsigned int fragmentShader; fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); glCompileShader(fragmentShader); unsigned int shaderProgram; shaderProgram = glCreateProgram(); glAttachShader(shaderProgram, vertexShader); glAttachShader(shaderProgram, fragmentShader); glLinkProgram(shaderProgram); glDeleteShader(vertexShader); glDeleteShader(fragmentShader); float 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.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f,//左上 -0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f,//左下 }; int indice[] = { 0, 1, 2, 2, 3, 1 }; unsigned int VBO, VAO, EBO; glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glGenVertexArrays(1, &VAO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //第一个是类型,第二个是大小,第三个是数据 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indice), indice, GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); while (!glfwWindowShouldClose(window)) { processInput(window); glClearColor(0.0f, 0.5f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shaderProgram); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glfwSwapBuffers(window); glfwPollEvents(); } glDeleteBuffers(1, &VBO); glDeleteProgram(shaderProgram); //关闭窗口 glfwTerminate(); return 0; }

3|0分开文件

先把VS中include的范围加入项目目录
把顶点着色器命名为shader.vs,像素着色器命名为shader.fs
在Shader里面,构造函数用流加载两个shader,注意要写调试信息,然后再实例化use函数,再main函数里面好用
main里面就可以用Shader类直接加载

shader.vs

#version 330 core layout (location=0) in vec3 aPos; layout (location=1) in vec3 aColor; out vec4 color; void main() { gl_Position = vec4(aPos, 1.0f); color = vec4(aColor, 1.0f); }

shader.fs

#version 330 core in vec4 color; out vec4 fragColor; void main() { fragColor = color; }

shader.cpp

#ifndef SHADER_H #endif SHADER_H #include<glad/glad.h> #include<string> #include<fstream> #include<sstream> #include<iostream> class Shader { public: unsigned int ID; Shader(const char* vertexPath, const char* fragmentPath) { using namespace std; string vertexCode; string fragmentCode; ifstream vShaderFile; ifstream fShaderFile; vShaderFile.exceptions(ifstream::failbit | ifstream::badbit); fShaderFile.exceptions(ifstream::failbit | ifstream::badbit); try { vShaderFile.open(vertexPath); fShaderFile.open(fragmentPath); stringstream vShaderStream, fShaderStream; vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf(); vShaderFile.close(); fShaderFile.close(); vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); } catch (ifstream::failure e) { cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ" << endl; } const char* vShaderCode = vertexCode.c_str(); const char* fShaderCode = fragmentCode.c_str(); unsigned int vertexShader, fragmentShader; vertexShader = glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader, 1, &vShaderCode, NULL); glCompileShader(vertexShader); int success; char infolog[512]; glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(vertexShader, 512, NULL, infolog); cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infolog << endl; } fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader, 1, &fShaderCode, NULL); glCompileShader(fragmentShader); glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(fragmentShader, 512, NULL, infolog); cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infolog << endl; } ID = glCreateProgram(); glAttachShader(ID, vertexShader); glAttachShader(ID, fragmentShader); glLinkProgram(ID); glGetProgramiv(ID, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(ID, 512, NULL, infolog); cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infolog << endl; } glDeleteShader(vertexShader); glDeleteShader(fragmentShader); } void use() { glUseProgram(ID); } };

main.cpp

#include<glad/glad.h> #include<GLFW/glfw3.h> #include<iostream> #include<Shader.cpp> void framebuffer_size_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); } void processInput(GLFWwindow* window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); } int main() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //创建窗口对象 GLFWwindow* window = glfwCreateWindow(800, 600, "LJHyyds", NULL, NULL); if (window == NULL) { std::cout << "Failed to create" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); //初始化GLAD管理指针,加载系统OpenGL函数指针 if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout << "Failed to init GLAD" << std::endl; return -1; } glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); Shader myshader("shader.vs", "shader.fs"); float 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.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f,//左上 }; unsigned int VBO, VAO; glGenBuffers(1, &VBO); glGenVertexArrays(1, &VAO); 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(float), (void*)0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); while (!glfwWindowShouldClose(window)) { processInput(window); glClearColor(0.0f, 0.5f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); myshader.use(); glDrawArrays(GL_TRIANGLES, 0, 3); glfwSwapBuffers(window); glfwPollEvents(); } glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); //关闭窗口 glfwTerminate(); return 0; }

4|0纪念

终于做到了梦想中的写shader,太高兴了



如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

__EOF__

本文作者Liujiahang
本文链接https://www.cnblogs.com/IamIron-Man/p/16601916.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   IamIron-Man  阅读(791)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示