草稿:
基本概念 图元为了让OpenGL知道我们的坐标和颜色值构成的到底是什么,OpenGL需要你去指定这些数据所表示的渲染类型。我们是希望把这些数据渲染成一系列的点?一系列的三角形?还是仅仅是一个长长的线?做出的这些提示叫做图元(Primitive),任何一个绘制指令的调用都将把图元传递给OpenGL。这是其中的几个:GL_POINTS、GL_TRIANGLES、GL_LINE_STRIP。
OpenGL的图形渲染管线按功能划分:
按操作模块划分:
顶点着色器(Vertex Shader):把3D坐标转换为另一种3D坐标,同时对顶点属性进行一些基本处理。
图元装配(Primitive Assembly):将顶点着色器输出的所有顶点作为输入(如果是GL_POINTS,那么就是一个顶点),并所有的点装配成指定图元的形状;本节例子中是一个三角形。
几何着色器(Geometry Shader):把图元形式的一系列顶点的集合作为输入,通过产生新顶点构造出新的(或是其它的)图元来生成其他形状。例子中,它生成了另一个三角形。
光栅化阶段(Rasterization Stage):把图元映射为最终屏幕上相应的像素,生成供片段着色器(Fragment Shader)使用的片段(Fragment)。在片段着色器运行之前会执行裁切(Clipping)。
片段着色器:主要目的是计算一个像素的最终颜色。
Alpha测试和混合(Blending)阶段:检测片段的对应的深度(和模板(Stencil))值,来判断这个像素是其它物体的前面还是后面,决定是否应该丢弃。alpha值定义了一个物体的透明度,并对物体进行混合(Blend)。
一个典型渲染流程:绘制三角形 实现思路 顶点着色器和一个片段着色器:在现代OpenGL中,我们必须定义至少一个顶点着色器和一个片段着色器(因为GPU中没有默认的顶点/片段着色器),所以实现一个图形渲染管线时,主要的工作就包含了顶点着色器和片段着色器的定义。
分工:顶点缓冲对象 VBO (Vertex Buffer Object):管理由顶点着色器,从GPU中分配的内存,来存储顶点数据(管理顶点数据)。
顶点数组对象 VAO (Vertex Array Object):将 顶点数据 和 顶点属性 统一到该对象中进行管理。
顶点着色器:读取数据--处理--输出;负责从GPU上申请内存,将该内存交由VBO(顶点缓冲对象)进行管理,该内存将用来存放待渲染的顶点数据。
VAO 与 VBO:为了便于管理顶点数据和顶点属性,使用VAO,将VBO(顶点数据)+顶点属性统一管理起来,避免每次都去做 顶点数据与顶点属性 的绑定;同时,使在不同顶点数据和属性配置之间切换,变得非常简单,只需要绑定不同的VAO就行了。
代码#include
#include
#include
//定义一个回调函数(Callback Function),
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
//处理所有的输入
void processInput(GLFWwindow *window);
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
//用着色器语言GLSL(OpenGL Shading Language)定义一个顶点着色器
const char *vertexShaderSource =
"#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
//用着色器语言GLSL(OpenGL Shading Language)定义一个片段着色器
const char *fragmentShaderSource =
"#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 1.0f, 0.0f, 1.0f);\n"
"}\n\0";
int main()
{
// 初始化和配置glfw
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
#endif
// 创建glfw窗口
// --------------------
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
std::cout
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?