顶点着色器和片段着色器

  1 #include <GL/glew.h>
  2 #include <GLFW/glfw3.h>
  3 #include <iostream>
  4 
  5 using namespace std;
  6 
  7 const int numVAOs = 1;
  8 GLuint renderingProgram;
  9 GLuint vao[numVAOs];
 10 
 11 
 12 GLuint createShaderProgram()
 13 {
 14     // 定义定点着色器源码
 15     const char* vshaderSource =
 16         // 声明着色器版本,与OpenGL版本同步
 17         "#version 430 \n"    
 18         // 在顶点着色器,给 gl_Position指定out标签不是必需的,因为 gl_Position 是预定义的输出变量
 19         //"out vec4 gl_Position; \n"
 20         // main函数
 21         "void main(void) \n"    
 22         // 用内置变量gl_Position在源码中硬编码一个顶点位置
 23         "{ gl_Position = vec4(0.0, 0.0, 0.0, 1.0);}";   
 24 
 25     // 定义片段着色器源码
 26     const char* fshaderSource =
 27         // 声明着色器版本,与OpenGL版本同步
 28         "#version 430 \n"     
 29         // out 标签表明color变量是输出变量
 30         "out vec4 color; \n"
 31         // main函数
 32         "void main(void) \n"    
 33         // 设置颜色分量(rgba)
 34         "{ color = vec4(0.0, 0.0, 1.0, 1.0);}";         
 35 
 36     // 创建顶点着色器
 37     GLuint vShader = glCreateShader(GL_VERTEX_SHADER);
 38     // 创建片段着色器
 39     GLuint fShader = glCreateShader(GL_FRAGMENT_SHADER);
 40     // 载入顶点着色器源码
 41     glShaderSource(vShader, 1, &vshaderSource, nullptr);
 42     // 载入片段着色器源码
 43     glShaderSource(fShader, 1, &fshaderSource, nullptr);
 44     // 编译顶点着色器
 45     glCompileShader(vShader);
 46     // 编译片段着色器
 47     glCompileShader(fShader);
 48     // 创建程序对象,OpenGL程序对象包含一系列编译过的着色器
 49     GLuint vfProgram = glCreateProgram();
 50     // 加入顶点着色器
 51     glAttachShader(vfProgram, vShader);
 52     // 加入片段着色器
 53     glAttachShader(vfProgram, fShader);
 54     // 链接程序
 55     glLinkProgram(vfProgram);
 56 
 57     return vfProgram;
 58 }
 59 
 60 void init(GLFWwindow* window) {
 61     renderingProgram = createShaderProgram();
 62     // 当准备将数据集发送给管线时,数据集是以缓冲区形式发送的。这些缓冲区最后都会被存入顶点数组对象
 63     // 此案例我们在顶点着色器中硬编码一个点,因此不需要缓存区
 64     // 即使如此,OpenGL依然需要创建一个VAO
 65     glGenVertexArrays(numVAOs, vao);
 66     glBindVertexArray(vao[0]);
 67 }
 68 
 69 void display(GLFWwindow* window, double currentTime)
 70 {
 71     // 指定颜色缓冲区清除后填充的值
 72     glClearColor(1.0, 0.0, 0.0, 1.0);
 73     // 用指定颜色清除(填充)颜色缓存区
 74     glClear(GL_COLOR_BUFFER_BIT);
 75     // 将含有两个已编译着色器的程序载入OpenGL管线阶段,并没有运行着色器
 76     glUseProgram(renderingProgram);
 77     // 设置绘制点的大小,便于观察
 78     glPointSize(5);
 79     // 启动管线处理过程,开始绘制
 80     glDrawArrays(GL_POINTS, 0, 1);
 81 }
 82 
 83 int main(void)
 84 {
 85     // 如果glfw初始化失败则返回
 86     if (!glfwInit()) { exit(EXIT_FAILURE); }
 87     // 设置OpenGL程序的主版本号
 88     glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
 89     // 设置OpenGL程序的副版本号
 90     glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
 91     // 借助GLFW创建一个窗口
 92     GLFWwindow* window = glfwCreateWindow(600, 600, "Graphics Program With OpenGL", nullptr, nullptr);
 93     // 将GLFW创建的窗口与当前OpenGL的上下文关联起来
 94     glfwMakeContextCurrent(window);
 95     // 如果glew初始化失败则返回,glew负责调用OpenGL相关的函数
 96     if (glewInit() != GLEW_OK) { exit(EXIT_FAILURE); }
 97     // 交换间隔指示了直到交换缓冲区前需要等待多少帧,通常被理解为垂直同步。
 98     // 默认情况下,交换间隔为0,意味着缓冲区交换会立即发生。
 99     // 在一些快速的机器上,因为屏幕保持以典型的60 - 75次每秒的速度更新,许多帧会永远看不到,所以这会浪费许多CPU和GPU周期。
100     // 而且,因为缓冲区可能会在屏幕更新的中途被交换,导致画面撕裂。
101     // 因此,应用需要代表性地设置交换间隔为1。
102     glfwSwapInterval(1);
103 
104     init(window);
105 
106     // 当用户点击关闭窗口按钮时会返回true
107     while (!glfwWindowShouldClose(window))
108     {
109         display(window, glfwGetTime()); 
110         // GLFW默认使用了双缓冲技术。这意味着每个窗口会有两个渲染缓冲区,一个前置缓冲区和一个后置缓冲区。
111         // 前置缓冲区会在屏幕上显示而后置缓冲区是你渲染的目标。
112         // 当整个帧已经渲染完毕时,两个缓冲区需要进行交换,所以后置缓冲区会变成前置缓冲区,反之亦然。
113         glfwSwapBuffers(window);
114         // 处理窗口相关事件
115         glfwPollEvents();
116     }
117     // 销毁窗口
118     glfwDestroyWindow(window);
119     // 终止运行
120     glfwTerminate();
121 
122     exit(EXIT_SUCCESS);
123 }

 

posted @ 2024-04-08 13:09  禅元天道  阅读(47)  评论(0)    收藏  举报