【Cherno的OpenGL视频】Uniforms in OpenGL
1、现在我们得到蓝色方块的方式是通过硬编码一个颜色:color = vec4(0.2, 0.3, 0.8, 1.0); 。
通过使用uniform,我们也能在CPU端定义这些颜色数据,也就是C++代码中定义,这样就可以在需要的时候更新这些数据。(还有一种方式就是vertex buffer)
Uniforms VS Attributes: uniforms are set for per draw, attributes are set for per vertex.
2、使用uniform。
3、改完之后,代码运行最终效果:
4、Now let’s do something for fun.
代码实现:
#include <GL/glew.h>// 放在glfw3.h之前,或者任何OpenGL之前。
#include <GLFW/glfw3.h>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>// Dealing with errors in OpenGL.
#define ASSERT(x) if(!(x)) __debugbreak();
#define GLCall(x) GLClearError();\x;\ASSERT(GLLogCall(#x, __FILE__, __LINE__))
static void GLClearError()
{while (glGetError() != GL_NO_ERROR);// or while (!glGetError());
}
static bool GLLogCall(const char* function, const char* file, int line)
{while (GLenum error = glGetError()){std::cout << "[OpenGL Error] (" << error << ")" << std::endl;std::cout << "[FUNCTION]:" << function << ", [FILE]:" << file << ", [LINE]:" << line << std::endl;return false;}return true;
}struct ShaderProgramSource
{std::string VertexSource;std::string FragmentSource;
};static ShaderProgramSource ParseShader(const std::string& filepath)
{enum class ShaderType{NONE = -1, VERTEX = 0, FRAGMENT = 1};std::ifstream stream(filepath);std::string line;std::stringstream ss[2];ShaderType type = ShaderType::NONE;// go through the file line-by-line.while (getline(stream, line)){if (line.find("#shader") != std::string::npos){if (line.find("vertex") != std::string::npos){// set mode to vertex.type = ShaderType::VERTEX;}else if (line.find("fragment") != std::string::npos){// set mode to fragment.type = ShaderType::FRAGMENT;}}else{ss[(int)type] << line << '\n';}}return { ss[0].str(), ss[1].str() };
}static unsigned int CompileShader(unsigned int type, const std::string& source)
{unsigned int id = glCreateShader(type);const char* src = source.c_str();glShaderSource(id, 1, &src, nullptr);glCompileShader(id);// error handling.int result;glGetShaderiv(id, GL_COMPILE_STATUS, &result);if (result == GL_FALSE){int length;glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);char* message = (char*)alloca(length * sizeof(char));glGetShaderInfoLog(id, length, &length, message);std::cout << "CompileShader() Failed, " << (type == GL_VERTEX_SHADER ? "vertex" : "fragment") << " shader!" << std::endl;std::cout << message << std::endl;glDeleteShader(id);return 0;}return id;
}// Creat a shader.
static unsigned int CreateShader(const std::string& vertexShader, const std::string& fragmentShader)
{unsigned int program = glCreateProgram();// create our true shader objects.unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);// link vs and fs.glAttachShader(program, vs);glAttachShader(program, fs);// link the program.glLinkProgram(program);glValidateProgram(program);// delete it after linked.glDeleteShader(vs);glDeleteShader(fs);return program;
}int main(void)
{GLFWwindow* window;/* Initialize the library */if (!glfwInit())return -1;/* Create a windowed mode window and its OpenGL context */window = glfwCreateWindow(640, 640, "I am Groot", NULL, NULL);if (!window){glfwTerminate();return -1;}/* Make the window's context current */glfwMakeContextCurrent(window);glfwSwapInterval(1);// after glfwMakeContextCurrent() -> Testing GLEW.if (glewInit() != GLEW_OK){std::cout << "glewInit() error" << std::endl;}std::cout << glGetString(GL_VERSION) << std::endl;// Testing GLEW.// on the CPU.float positions[] = {-0.5f, -0.5f, //index00.5f, -0.5f, //index10.5f, 0.5f, //index2-0.5f, 0.5f, //index3};// on the CPU.unsigned int indices[] = {0, 1, 2,//index0 1 22, 3, 0 //index2 3 0};// Define a vertex buffer: send positions to GPU.unsigned int buffer;GLCall(glGenBuffers(1, &buffer));// 1 is the id for our vertex buffer object.GLCall(glBindBuffer(GL_ARRAY_BUFFER, buffer));// "select this buffer".GLCall(glBufferData(GL_ARRAY_BUFFER, 6 * 2 * sizeof(float), positions, GL_STATIC_DRAW));// copying these positions into this actual buffer.// enable or disable a generic vertex attribute array and tell OpenGL what layout of our buffer.GLCall(glEnableVertexAttribArray(0));GLCall(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0));// Define a index buffer: send indices to GPU.unsigned int ibo;GLCall(glGenBuffers(1, &ibo));GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo));GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), indices, GL_STATIC_DRAW));ShaderProgramSource source = ParseShader("res/shaders/Basic.shader");// Use our shader.unsigned int shader = CreateShader(source.VertexSource, source.FragmentSource);GLCall(glUseProgram(shader));// 在我们的shader里,每个uniform都会被分配一个ID。GLCall(int location = glGetUniformLocation(shader, "u_Color"));ASSERT(location != -1);// -1 说明找不到u_Color。// after our shader is binded, set u_Color for fragment shader.GLCall(glUniform4f(location, 0.8f, 0.3f, 0.8f, 1.0f));// sth for fun.float r = 0.0f;float increment = 0.05;// sth for fun./* Loop until the user closes the window */while (!glfwWindowShouldClose(window)){/* Render here */GLCall(glClear(GL_COLOR_BUFFER_BIT));GLCall(glUniform4f(location, r, 0.3f, 0.8f, 1.0f));GLCall(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr));if (r > 1.0f){increment = -0.05f;} else if(r < 0.0f){increment = 0.05f;}r += increment;/* Swap front and back buffers */glfwSwapBuffers(window);/* Poll for and process events */glfwPollEvents();}// Clean up shader once you're done.glDeleteProgram(shader);//should not be glDeleteShader(shader);glfwTerminate();return 0;
}
5、运行效果:
Something Fun
6、Uniforms are set for per draw.
在我们的代码中:
GLCall(glUniform4f(location, r, 0.3f, 0.8f, 1.0f));
GLCall(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr));
如果想要实现组成正方形的2个三角形的颜色不同,需要通过vertex attributes去实现。
【Cherno的OpenGL视频】Uniforms in OpenGL相关推荐
- 【Cherno的OpenGL视频】Welcome to OpenGL
Let's talk about OpenGL, in this video we're basically just going to cover what OpenGL actual is? Ho ...
- 【OpenGL】计算机图形学OpenGL基础
前面几节是跟着B站视频学习的OpenGL基础操作,算是熟悉了一下环境,下面进入学习opengl中文教程网站,开始真正进入OpenGL的大门. 下面开始学习计算机图形编程,收获自己做出很酷的东西的喜悦. ...
- 【OpenGL】傅老师OpenGL学习
[OpenGL]傅老师OpenGL学习 https://www.bilibili.com/video/av24353839?p=1 https://learnopengl-cn.readthedocs ...
- OpenGL模板 Mac Cmake OpenGL(Glut) Template
自己经常使用的一些功能做一个模板,有灯光效果,你可以用鼠标放大,围绕所述旋转坐标系的原点 Main.cpp #include <GLUT/glut.h> #include <cstd ...
- 【OpenGL】十一、OpenGL 绘制多个点 ( 绘制单个点 | 绘制多个点 )
文章目录 一.绘制单个点 二.绘制多个点 三.相关资源 在上一篇博客 [OpenGL]十.OpenGL 绘制点 ( 初始化 OpenGL 矩阵 | 设置投影矩阵 | 设置模型视图矩阵 | 绘制点 | ...
- 【OpenGL】十、OpenGL 绘制点 ( 初始化 OpenGL 矩阵 | 设置投影矩阵 | 设置模型视图矩阵 | 绘制点 | 清除缓冲区 | 设置当前颜色值 | 设置点大小 | 绘制点 )
文章目录 一.初始化 OpenGL 矩阵 1.设置投影矩阵 2.设置模型视图矩阵 二.绘制点 1.清除缓冲区 2.设置当前颜色值 3.设置绘制点的大小 4.绘制点 5.将缓冲区绘制到前台 三.部分代码 ...
- 【OpenGL】九、OpenGL 绘制基础 ( OpenGL 状态机概念 | OpenGL 矩阵概念 )
文章目录 一.OpenGL 状态机概念 二.OpenGL 矩阵概念 上一篇博客 [OpenGL]八.初始化 OpenGL 渲染环境 ( 导入 OpenGL 头文件 | 链接 OpenGL 库 | 将窗 ...
- 【OpenGL】八、初始化 OpenGL 渲染环境 ( 导入 OpenGL 头文件 | 链接 OpenGL 库 | 将窗口设置为 OpenGL 窗口 | 设置像素格式描述符 | 渲染绘制 ) ★
文章目录 一.导入 OpenGL 的两个头文件 二.链接 OpenGL 库 三.将 Windows 桌面窗口改成 OpenGL 窗口 四.获取窗口设备 五.设置像素格式描述符 六.设置像素格式 七.创 ...
- 【OpenGL ES】 Android OpenGL ES -- 透视投影 和 正交投影
博客地址 : http://blog.csdn.net/shulianghan/article/details/46680803 源码下载 : http://download.csdn.net/det ...
- Learn OpenGL(七)——OpenGL中使用着色器的基本步骤及GLSL渲染简单示例
OpenGL着色语言(OpenGL Shading Language,GLSL)是用来在OpenGL中着色编程的语言,是一种具有C/C++风格的高级过程语言,同样也以main函数开始,只不过执行过程是 ...
最新文章
- 高科技领域零的突破永不嫌多 --- 我看嫦娥四号成功登陆月球背面
- UnicodeEncodeError: ‘gbk’ codec can’t encode character u’\u200e’ in position 43: illegal multib...
- 数组中只出现一次的(一个数、两个数、三个数)
- InstallShield2013 error 6109
- Mysql:事务管理——未完待续
- 北京/苏州内推 | 微软STCA搜索广告算法团队招聘NLP算法工程师
- python 数组赋值_LeetCode基础算法题第182篇:一维数组的运行总和
- metro风格后台管理效果
- Mysql平滑迁移(重构后的数据平滑迁移)
- struts中采用注解配置Action
- matlabstrcmpi_matlab.学习命令中文版.doc
- 被奉为经典的「金字塔原理」,教给我们哪些PPT写作技巧?
- Windows 95, 98, Me 的界面对比(图集)(原文于2016-03-26发布于贴吧)
- 【数学建模】——1992~2019国赛优秀论文
- latex表格内容上下居中_Latex-表格内容垂直居中
- 让电脑假装蓝屏的C语言,【技术天地】一句命令让你的电脑蓝屏~(有强迫症的童鞋试试~~)...
- 笔记——c51的led点阵流动字幕
- phpmywind目录结构
- Machine Learning - A/B Test
- 0 嵌入式-ARM简介
热门文章
- 体育馆预约系统java_基于JAVA WEB的高校体育场地预约管理系统(计算机毕业设计)...
- 微信小程序生成小程序码的方法
- Redis的三种启动方式
- 工作中遇到的问题之android客户端自动生成带logo的二维码
- Python_一元线性回归及回归显著性
- 知识图谱从入门到应用——知识图谱推理:基于表示学习的知识图谱推理-[嵌入学习]
- oracle instr函数(oracle 用instr 来代替 like)
- 附件统一处理starter,含附件客户端和附件服务端
- mt6765和骁龙665哪个好_联发科MT6750和骁龙450哪个好 高通骁龙450与联发科MT6750区别对比评测...
- 计算机课师生互动过多,课堂师生互动存在问题及途径分析