您当前的位置: 首页 > 

惊鸿一博

暂无认证

  • 2浏览

    0关注

    535博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

OpenGL学习笔记_图形渲染管线及典型渲染流程(绘制一个三角形)

惊鸿一博 发布时间:2020-01-06 20:20:29 ,浏览量:2

草稿:

基本概念 图元

为了让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             
关注
打赏
1663399408
查看更多评论
0.0377s