步骤1:VERTEX SHADER
处理顶点,专门对顶点进行操作
步骤2: SHAPE ASSEMBLY
将图1输进来的顶点组成线、面,哪些点连成线,哪些点连成面,哪些点单独存在
步骤3:GEOMETRY SHADER
在图2的基础上可以插入点,补点进去
步骤4:RASTERIZATION
光栅化:(矢量转栅格)
步骤5:FRAGMENT SHADER
着色:给格子上色
步骤6:TESTS AND BLENDING
深度测试和混合
画三角形
#define GLEW_STATIC //glew32s.lib
#include<GL\glew.h>
#include<GLFW\glfw3.h>
#include<iostream>
#include<vector>
//键盘回调函数原型声明
void processInput(GLFWwindow* window);
//定义程序常量
const int WINDOW_WIDTH = 800, WINDOW_HEIGHT = 600;
int main(int argc, char** argv)
{
// 开启OpenGL 3.3 core profile
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); //主版本号
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); //次版本号
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//create OpenGL GLFW Window
GLFWwindow *window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "OpenglWindow", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window!" << std::endl;
glfwTerminate(); //终止glfw
return -1;
}
glfwMakeContextCurrent(window); // 创建的窗口的context指定为当前context
// 初始化GLEW 获取OpenGL函数
glewExperimental = true; // 让glew获取所有拓展函数
if (glewInit() != GLEW_OK)
{
std::cout << "Failed to Init GLEW" << std::endl;
glfwTerminate();
return -1;
}
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); //设置视口参数
//glEnable(GL_CULL_FACE); //剔除面
//glCullFace(GL_BACK); //剔除背面
//glCullFace(GL_FRONT); //剔除正面
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); //使用线框模式绘制图形
//section1:准备顶点数据
// 指定顶点属性数据 顶点位置
GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f, //0
0.5f, -0.5f, 0.0f, //1
0.0f, 0.5f, 0.0f, //2
//0.5f, -0.5f, 0.0f,
//0.0f, 0.5f, 0.0f,
//0.8f,0.8f,0.0f //3
};
//0,1,2是第一个三角形; 2,1,3是第二个三角形
//创建缓存对象
GLuint VAO, VBO;
//step1:创建并绑定VAO对象(VAO:vertex array object)
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
//step2:创建并绑定VBO对象 (VBO:vertex buffer object)
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
//step3:分配空间,将数据传送到GPU中
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//step4:指定解析方式,并启用顶点属性
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (GLvoid*)0);
glEnableVertexAttribArray(0);
///解除绑定(暂时解除绑定,能够防止后续操作干扰到了当前VAO和VBO)
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
//section2:准备着色器程序
//step1:准备着色器 源程序
const GLchar *vertexShaderSource =
"#version 330 core \n" //指定GLSL版本3.3
"layout(location = 0) in vec3 aPos; \n" //顶点属性索引
"void main() { \n"
"gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);} \n"; //输出顶点
const GLchar *fragmentShaderSource =
"#version 330 core \n"
"out vec4 FragColor; \n" //输出片元颜色
"void main() { \n"
"FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);} \n";
//step2:创建shader object
//顶点着色器
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
//错误处理
GLint compileStatus = 0;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compileStatus);//检查编译状态
if (compileStatus == GL_FALSE) //获取错误报告
{
GLint maxLength = 0;
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> errLog(maxLength);
glGetShaderInfoLog(vertexShader, maxLength, &maxLength, &errLog[0]);
std::cout << "Error::shader vertex shader compile failed," << &errLog[0] << std::endl;
}
// 片元着色器
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
//错误处理
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compileStatus);
if (compileStatus == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> errLog(maxLength);
glGetShaderInfoLog(fragmentShader, maxLength, &maxLength, &errLog[0]);
std::cout << "Error::shader fragment shader compile failed," << &errLog[0] << std::endl;
}
// Step3 链接形成 shader program object
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
//链接错误处理
GLint linkStatus;
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &linkStatus);
if (linkStatus == GL_FALSE)
{
GLint maxLength = 0;
glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> errLog(maxLength);
glGetProgramInfoLog(shaderProgram, maxLength, &maxLength, &errLog[0]);
std::cout << "Error::shader link failed," << &errLog[0] << std::endl;
}
/// 链接完成后detach
glDetachShader(shaderProgram, vertexShader);
glDetachShader(shaderProgram, fragmentShader);
/// 不需要连接到其他程序时 释放空间
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// 开始游戏主循环
while (!glfwWindowShouldClose(window))
{
glfwPollEvents(); // 处理例如鼠标 键盘等事件
// 清除颜色缓冲区 重置为指定颜色
glClearColor(0.18f, 0.04f, 0.14f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// 这里填写场景绘制代码
glBindVertexArray(VAO); //使用VAO信息
glUseProgram(shaderProgram); //使用着色器
glDrawArrays(GL_TRIANGLES, 0, 3); //使用VBO数据绘制物体
glBindVertexArray(0);
glUseProgram(0);
glfwSwapBuffers(window); // 交换缓存
glfwPollEvents();
}
// 释放资源
glDeleteProgram(shaderProgram);
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return 0;
}
void processInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, true);
}
}
程序运行结果: