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相关推荐

  1. 【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 ...

  2. 【OpenGL】计算机图形学OpenGL基础

    前面几节是跟着B站视频学习的OpenGL基础操作,算是熟悉了一下环境,下面进入学习opengl中文教程网站,开始真正进入OpenGL的大门. 下面开始学习计算机图形编程,收获自己做出很酷的东西的喜悦. ...

  3. 【OpenGL】傅老师OpenGL学习

    [OpenGL]傅老师OpenGL学习 https://www.bilibili.com/video/av24353839?p=1 https://learnopengl-cn.readthedocs ...

  4. OpenGL模板 Mac Cmake OpenGL(Glut) Template

    自己经常使用的一些功能做一个模板,有灯光效果,你可以用鼠标放大,围绕所述旋转坐标系的原点 Main.cpp #include <GLUT/glut.h> #include <cstd ...

  5. 【OpenGL】十一、OpenGL 绘制多个点 ( 绘制单个点 | 绘制多个点 )

    文章目录 一.绘制单个点 二.绘制多个点 三.相关资源 在上一篇博客 [OpenGL]十.OpenGL 绘制点 ( 初始化 OpenGL 矩阵 | 设置投影矩阵 | 设置模型视图矩阵 | 绘制点 | ...

  6. 【OpenGL】十、OpenGL 绘制点 ( 初始化 OpenGL 矩阵 | 设置投影矩阵 | 设置模型视图矩阵 | 绘制点 | 清除缓冲区 | 设置当前颜色值 | 设置点大小 | 绘制点 )

    文章目录 一.初始化 OpenGL 矩阵 1.设置投影矩阵 2.设置模型视图矩阵 二.绘制点 1.清除缓冲区 2.设置当前颜色值 3.设置绘制点的大小 4.绘制点 5.将缓冲区绘制到前台 三.部分代码 ...

  7. 【OpenGL】九、OpenGL 绘制基础 ( OpenGL 状态机概念 | OpenGL 矩阵概念 )

    文章目录 一.OpenGL 状态机概念 二.OpenGL 矩阵概念 上一篇博客 [OpenGL]八.初始化 OpenGL 渲染环境 ( 导入 OpenGL 头文件 | 链接 OpenGL 库 | 将窗 ...

  8. 【OpenGL】八、初始化 OpenGL 渲染环境 ( 导入 OpenGL 头文件 | 链接 OpenGL 库 | 将窗口设置为 OpenGL 窗口 | 设置像素格式描述符 | 渲染绘制 ) ★

    文章目录 一.导入 OpenGL 的两个头文件 二.链接 OpenGL 库 三.将 Windows 桌面窗口改成 OpenGL 窗口 四.获取窗口设备 五.设置像素格式描述符 六.设置像素格式 七.创 ...

  9. 【OpenGL ES】 Android OpenGL ES -- 透视投影 和 正交投影

    博客地址 : http://blog.csdn.net/shulianghan/article/details/46680803 源码下载 : http://download.csdn.net/det ...

  10. Learn OpenGL(七)——OpenGL中使用着色器的基本步骤及GLSL渲染简单示例

    OpenGL着色语言(OpenGL Shading Language,GLSL)是用来在OpenGL中着色编程的语言,是一种具有C/C++风格的高级过程语言,同样也以main函数开始,只不过执行过程是 ...

最新文章

  1. 高科技领域零的突破永不嫌多 --- 我看嫦娥四号成功登陆月球背面
  2. UnicodeEncodeError: ‘gbk’ codec can’t encode character u’\u200e’ in position 43: illegal multib...
  3. 数组中只出现一次的(一个数、两个数、三个数)
  4. InstallShield2013 error 6109
  5. Mysql:事务管理——未完待续
  6. 北京/苏州内推 | 微软STCA搜索广告算法团队招聘NLP算法工程师
  7. python 数组赋值_LeetCode基础算法题第182篇:一维数组的运行总和
  8. metro风格后台管理效果
  9. Mysql平滑迁移(重构后的数据平滑迁移)
  10. struts中采用注解配置Action
  11. matlabstrcmpi_matlab.学习命令中文版.doc
  12. 被奉为经典的「金字塔原理」,教给我们哪些PPT写作技巧?
  13. Windows 95, 98, Me 的界面对比(图集)(原文于2016-03-26发布于贴吧)
  14. 【数学建模】——1992~2019国赛优秀论文
  15. latex表格内容上下居中_Latex-表格内容垂直居中
  16. 让电脑假装蓝屏的C语言,【技术天地】一句命令让你的电脑蓝屏~(有强迫症的童鞋试试~~)...
  17. 笔记——c51的led点阵流动字幕
  18. phpmywind目录结构
  19. Machine Learning - A/B Test
  20. 0 嵌入式-ARM简介

热门文章

  1. 体育馆预约系统java_基于JAVA WEB的高校体育场地预约管理系统(计算机毕业设计)...
  2. 微信小程序生成小程序码的方法
  3. Redis的三种启动方式
  4. 工作中遇到的问题之android客户端自动生成带logo的二维码
  5. Python_一元线性回归及回归显著性
  6. 知识图谱从入门到应用——知识图谱推理:基于表示学习的知识图谱推理-[嵌入学习]
  7. oracle instr函数(oracle 用instr 来代替 like)
  8. 附件统一处理starter,含附件客户端和附件服务端
  9. mt6765和骁龙665哪个好_联发科MT6750和骁龙450哪个好 高通骁龙450与联发科MT6750区别对比评测...
  10. 计算机课师生互动过多,课堂师生互动存在问题及途径分析