赞
踩
—— 2024-07-14 上午
bilibili赵新政老师的教程看后笔记
code review!
vs代码
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
uniform float time;
out vec3 color;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
color = aColor * (sin(time) + 1.0) / 2.0;
}
fs代码
#version 330 core
out vec4 FragColor;
in vec3 color;
void main()
{
FragColor = vec4(color, 1.0f);
}
vs代码
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
out vec3 color;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
color = aColor;
}
fs代码
#version 330 core
out vec4 FragColor;
uniform float time;
in vec3 color;
void main()
{
FragColor = vec4(color * (sin(time) + 1.0) / 2.0, 1.0);
}
vs代码
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
out vec3 color;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
color = aColor;
}
fs代码
#version 330 core
out vec4 FragColor;
uniform float time;
in vec3 color;
void main()
{
float intensity = (sin(time) + 1.0) / 2.0;
FragColor = vec4(vec3(intensity), 1.0f);
}
vs代码
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
uniform float time;
out vec3 color;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
color = aColor * (cos(time) + 1.0) / 2.0;
}
fs代码
#version 330 core
out vec4 FragColor;
uniform float time;
in vec3 color;
void main()
{
float intensity = (sin(time) + 1.0) / 2.0;
FragColor = vec4(vec3(intensity) + color, 1.0f);
}
代码
#pragma once #include "core.h" #include<string> class Shader { public: Shader(const char* vertexPath, const char* fragmentPath); ~Shader(); void begin();//开始使用当前Shader void end();//结束使用当前Shader void setFloat(const std::string& name, float value); private: //shader program //type:COMPILE LINK void checkShaderErrors(GLuint target,std::string type); private: GLuint mProgram{ 0 }; };
代码
#include "shader.h" #include "../wrapper/checkError.h" #include <fstream> #include <iostream> #include <sstream> #include <string> Shader::Shader(const char *vertexPath, const char *fragmentPath) { // 声明装入shader代码字符串的两个string std::string vertexCode; std::string fragmentCode; // 声明用于读取vs跟fs文件的inFileStream std::ifstream vShaderFile; std::ifstream fShaderFile; // 保证ifstream遇到问题的时候可以抛出异常 vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); try { // 1 打开文件 vShaderFile.open(vertexPath); fShaderFile.open(fragmentPath); // 2 将文件输入流当中的字符串输入到stringStream里面 std::stringstream vShaderStream, fShaderStream; vShaderStream << vShaderFile.rdbuf(); fShaderStream << fShaderFile.rdbuf(); // 3 关闭文件 vShaderFile.close(); fShaderFile.close(); // 4 将字符串从stringStream当中读取出来,转化到code String当中 vertexCode = vShaderStream.str(); fragmentCode = fShaderStream.str(); } catch (std::ifstream::failure &e) { std::cout << "ERROR: Shader File Error: " << e.what() << std::endl; } const char *vertexShaderSource = vertexCode.c_str(); const char *fragmentShaderSource = fragmentCode.c_str(); // 1 创建Shader程序(vs、fs) GLuint vertex, fragment; vertex = glCreateShader(GL_VERTEX_SHADER); fragment = glCreateShader(GL_FRAGMENT_SHADER); // 2 为shader程序输入shader代码 glShaderSource(vertex, 1, &vertexShaderSource, NULL); glShaderSource(fragment, 1, &fragmentShaderSource, NULL); // 3 执行shader代码编译 glCompileShader(vertex); // 检查vertex编译结果 checkShaderErrors(vertex, "COMPILE"); glCompileShader(fragment); // 检查fragment编译结果 checkShaderErrors(fragment, "COMPILE"); // 4 创建一个Program壳子 mProgram = glCreateProgram(); // 6 将vs与fs编译好的结果放到program这个壳子里 glAttachShader(mProgram, vertex); glAttachShader(mProgram, fragment); // 7 执行program的链接操作,形成最终可执行shader程序 glLinkProgram(mProgram); // 检查链接错误 checkShaderErrors(mProgram, "LINK"); // 清理 glDeleteShader(vertex); glDeleteShader(fragment); } Shader::~Shader() { } void Shader::begin() { GL_CALL(glUseProgram(mProgram)); } void Shader::end() { GL_CALL(glUseProgram(0)); } void Shader::setFloat(const std::string &name, float value) { // 1 通过名称拿到Uniform变量的位置Location GLint location = GL_CALL(glGetUniformLocation(mProgram, name.c_str())); // 2 通过Location更新Uniform变量的值 GL_CALL(glUniform1f(location, value)); } void Shader::checkShaderErrors(GLuint target, std::string type) { int success = 0; char infoLog[1024]; if (type == "COMPILE") { glGetShaderiv(target, GL_COMPILE_STATUS, &success); if (!success) { glGetShaderInfoLog(target, 1024, NULL, infoLog); std::cout << "Error: SHADER COMPILE ERROR" << "\n" << infoLog << std::endl; } } else if (type == "LINK") { glGetProgramiv(target, GL_LINK_STATUS, &success); if (!success) { glGetProgramInfoLog(target, 1024, NULL, infoLog); std::cout << "Error: SHADER LINK ERROR " << "\n" << infoLog << std::endl; } } else { std::cout << "Error: Check shader errors Type is wrong" << std::endl; } }
代码
#include <iostream> #include "glframework/core.h" #include "glframework/shader.h" #include <string> #include <assert.h>//断言 #include "wrapper/checkError.h" #include "application/Application.h" /* *┌────────────────────────────────────────────────┐ *│ 目 标: Uniform的使用 *│ 讲 师: 赵新政(Carma Zhao) *│ 拆分目标: *│ 1 补充Shader类函数,允许外界更新Uniform变量 *│ 2 更改Shader 实现颜色跟随时间发生变化(忽明忽暗) *│ 3 每一次循环都要获取系统时间,更新到Shader Uniform当中 * **更新Uniform的时候,一定要先UserProgram *│ 4 额外实验:尝试在fs里面根据时间修改color *│ 5 重要: vs与fs内的uniform如果重名,两个都会发生作用,相当于一个 *└────────────────────────────────────────────────┘ */ GLuint vao; Shader* shader = nullptr; void OnResize(int width, int height) { GL_CALL(glViewport(0, 0, width, height)); std::cout << "OnResize" << std::endl; } void OnKey(int key, int action, int mods) { std::cout << key << std::endl; } void prepareVAO() { //1 准备positions colors float positions[] = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f, }; float colors[] = { 1.0f, 0.0f,0.0f, 0.0f, 1.0f,0.0f, 0.0f, 0.0f,1.0f }; unsigned int indices[] = { 0, 1, 2 }; //2 VBO创建 GLuint posVbo, colorVbo; glGenBuffers(1, &posVbo); glBindBuffer(GL_ARRAY_BUFFER, posVbo); glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW); glGenBuffers(1, &colorVbo); glBindBuffer(GL_ARRAY_BUFFER, colorVbo); glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); //3 EBO创建 GLuint ebo; glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); //4 VAO创建 glGenVertexArrays(1, &vao); glBindVertexArray(vao); //5 绑定vbo ebo 加入属性描述信息 //5.1 加入位置属性描述信息 glBindBuffer(GL_ARRAY_BUFFER, posVbo); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0); //5.2 加入颜色属性描述数据 glBindBuffer(GL_ARRAY_BUFFER, colorVbo); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0); //5.3 加入ebo到当前的vao glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBindVertexArray(0); } void prepareShader() { shader = new Shader("assets/shaders/vertex.glsl","assets/shaders/fragment.glsl"); } void render() { //执行opengl画布清理操作 GL_CALL(glClear(GL_COLOR_BUFFER_BIT)); //1 绑定当前的program shader->begin(); shader->setFloat("time", glfwGetTime()); //2 绑定当前的vao GL_CALL(glBindVertexArray(vao)); //3 发出绘制指令 glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0); glBindVertexArray(0); shader->end(); } int main() { if (!app->init(800, 600)) { return -1; } app->setResizeCallback(OnResize); app->setKeyBoardCallback(OnKey); //设置opengl视口以及清理颜色 GL_CALL(glViewport(0, 0, 800, 600)); GL_CALL(glClearColor(0.2f, 0.3f, 0.3f, 1.0f)); prepareShader(); prepareVAO(); while (app->update()) { render(); } app->destroy(); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。