LearnOpenGL学习笔记(三)
1.颜色动态变化的三角形
Uniform是一种从CPU中的应用向GPU中的着色器发送数据的方式,但uniform和顶点属性有些不同。首先,uniform是全局的(Global)。全局意味着uniform变量必须在每个着色器程序对象中都是独一无二的,而且它可以被着色器程序的任意着色器在任意阶段访问。第二,无论你把uniform值设置成什么,uniform会一直保存它们的数据,直到它们被重置或更新。
编写下面这个着色器,可以得到一个uniform变量,通过在程序(这里是在渲染循环)中改变它的值,就可以设置三角形的颜色
#version 330 core
out vec4 FragColor;
uniform vec4 ourColor; // 在OpenGL程序代码中设定这个变量
void main()
{
FragColor = ourColor;
}
下面给出完整的代码与注释:
//
// main.cpp
// Shaders
//
// Created by 游文彦 on 2018/9/26.
// Copyright © 2018 Swallow. All rights reserved.
//
//注意要在包含GLFW的头文件之前包含了GLAD的头文件!
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <cmath>
using namespace std;
//当用户改变窗口的大小的时候,视口也应该被调整,需要一个回调函数
void framebuffer_size_callback(GLFWwindow * window,int width,int height);
//声明一个函数用来检测特定的键是否被按下
void processInput(GLFWwindow * window);
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
//定义一个顶点着色器的源码
const char *vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos, 1.0);\n"
"}\n\0";
//定义一个片段着色器的源码
//在OpenGL程序代码中会设定uniform变量
const char *fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"uniform vec4 ourColor;\n"
"void main()\n"
"{\n"
" FragColor = ourColor;\n"
"}\n\0";
int main(){
//初始化GLFW
glfwInit();
//将OpenGL主版本号(Major)和次版本号(Minor)都设为3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
//使用的是核心模式(Core-profile)
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//如果是macOS系统,则需要下面这行代码才能让配置起作用
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
//创建一个窗口对象
GLFWwindow * window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Hello,shaders", NULL, NULL);
if (window == NULL){
cout << "Failed to create GLFW window" << endl;
glfwTerminate();
return -1;
}
//通知GLFW将我们窗口的上下文设置为当前线程的主上下文
glfwMakeContextCurrent(window);
//注册定义好的回调函数,告诉GLFW每当窗口调整大小的时候调用这个函数
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
//GLAD是用来管理OpenGL的函数指针的,在调用任何OpenGL的函数之前我们需要初始化GLAD
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)){
cout << "Failed to initialize GLAD" << endl;
return -1;
}
/*************** 建立并编译着色器程序 *************/
//1.编译顶点着色器
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
//glShaderSource函数把要编译的着色器对象作为第一个参数。第二参数指定了传递的源码字符串数量,这里只有一个。
//第三个参数是顶点着色器真正的源码,第四个参数我们先设置为NULL
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
//下面这段代码用来检测编译是否成功
int success;
char infoLog[512];
//用glGetShaderiv来检查是否编译成功
glGetShader