OpenGL 编程指南 (8)

1、细分着色器(Tessellation shader)有两个阶段来生成几何图元的模型网格。

1)在顶点着色阶段,需要设置所有线段、三角形构成处理的网格,使用有序顶点列表生成新的目标图元,。

2)将新生成的图元顶点放置到指定的位置上后进入下一阶段。

2、tessellation shader 处理一种叫 面片(patch) 的新图元,它是一个保证了期望顺序的顶点列表。面片的的顶点数量需要自行设置,同一个绘制命令处理的面片大小是相同的。

void glPathcParameteri(GLenum pname, GLint value)//pname必须为GL_PATCH_VERTICES,value的自己需要介于0与GL_MAX_PATCH_VERTICES之间

面片的顶点数量默认为3,小于这个值那么将忽略处理不产生任何几何图元。如果要设置一个面片,绘制命令的输入类型设置为GL_PATCHES,下面是个例子:

float vertices[][2] = {{-0.75, 0.25}, {0.5, 0.5}, {0.55, 0.53}, {-0.5, 0.55}};

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0 nullptr);

glEnableVertexAttribArray(0);

glPatchParameteri(GL_PATCH_VERTICES, 4);

glDrawArrays(GL_PATCHES, 0, 4);

tessellation shader中使用gl_in获得顶点数据,gl_PatchVerticesIn可以获得gl_in的长度,gl_PatchVerticesOut是输出面片的顶点数目。

3、细分控制着色器(可选的步骤)

1)生成细分输出面片的顶点保存在gl_out并传递到细分计算着色器,同时更新所有顶点面片的属性值

2)设置细分层次因数,以控制生成图元的操作,gl_TessLevelInner 与 gl_TessLevelOuter是隐式声明

4、通过布局限定符设置输出面片顶点的数量,gl_InvocationID表示当前是输出的第几个顶点,也就是gl_out的索引。

layout (vertices = 4) out;//设置面片输出点顶数目为4同时代表了着色器的执行次数(每输出一个顶点执行一次)

#version 420 core

layout (vertices = 4) out;

void main()

{

gl_TessLevelOuter[0] = 2.0;

gl_TessLevelOuter[1] = 3.0;

gl_TessLevelOuter[2] = 2.0;

gl_TessLevelOuter[3] = 5.0;

gl_TessLevelInner[0] = 3.0;

gl_TessLevelInner[1] = 4.0;

gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;

//......

}

5、细分总量由 内侧(gl_TessLevelInner,2个元素长度的数组,负责控制内部细分方式) 与 外侧(gl_TessLevelOuter,4个元素长度的数组,负责控制细分区域的周长) 共同决定。它们的值可以是在细分控制着色器中写入如上面的例子中也可以在应用程序中写入,当所设置的值小于1或者是NaN的时候,这个面片将会被丢弃不做处理。

void glPatchParameterfv(GLenum pname, const GLfloat* values)//pname对应为GL_PATCH_DEFAULT_OUTER_LEVEL,GL_PATCH_DEFAULT_INNER_LEVEL,values为对应设置数值的数组

6、三种对线段分段的方式

1)equal_spacing

2)fractional_even_spacing

3)fractional_odd_spacing

7、OpenGL细分支持三种细分域:四边形、三角形、等值线集合。

1)四边形细分域:使用了gl_TessLevelOuter 与 gl_TessLevelInner 的所有值,面片内的细分坐标使用的是(u, v)2维坐标。根据 4 中参数细分后书中给出的图例是如下:

但是我自己画出来的是下面这个样子的(上面标注的gl_TessLevelInner[0]与gl_TessLevelInner[1]应该互换位置)

2)等值线细分域:使用了gl_TessLevelOuter 前二个值。考虑到两个面片共享一条边的情况,第一条线是不予显示的。

3)三角形细分域:使用了gl_TessLevelOuter 前三个值 与 gl_TessLevelInner 第一个值。细分坐标系使用的是重心坐标系(x, y, z)表示,各个分量值域为[0.0, 1.0]同时z+y+x = 1.0。

8、细分计算着色器:细分生成的顶点都要执行一次细分计算着色器将细分坐标转换为下文能够识别的屏幕坐标。细分计算着色器首先设置图元生成器,通过layout设置细分域、图元类型(quads、triangles、isolines)、图元面朝向(cw、ccw)、生成方式,然后根据前面的参数计算出需要的坐标等信息。

layout (quads, equal_spacing, ccw, points) out;//这些参数的顺序不是严格的

#version 420 core

layout (quads, equal_spacing, ccw) in;

void main()

{

float u = gl_TessCoord.x;

float v = gl_TessCoord.y;

float mu = 1.0 - u;

float mv = 1.0 - v;

gl_Position = mu*mv*gl_in[0].gl_Position + u*mv*gl_in[1].gl_Position + u*v*gl_in[2].gl_Position + mu*v*gl_in[3].gl_Position;

}

10、https://www.khronos.org/opengl/wiki/Tessellation

原文地址:https://www.cnblogs.com/haihuahuang/p/12423868.html

时间: 2024-08-11 05:54:12

OpenGL 编程指南 (8)的相关文章

在Win7(64位)使用VS2015运行《OpenGL编程指南》第八版第一章程序的方法

前言:笔者第一次用vs2015来实现<OpenGL编程指南>第八版第一个程序时确实花费了不少时间,按照网上教程,尝试了各种方法,最终花费了两个上午加一个下午的时间, 成功运行了程序,花了这么多时间,确实让人懊恼,现在把运行程序的步骤记录下来,以便查阅. 1.第一步,下载oglpg-8th-edith. 如果去书本上的官网下载,下载的是第九版的,而不是第八版的源码. 去其他网站下载,下载的这个包里面没有第一章的源码,可以网上黏贴其他人的代码,建议下第八版源码,下载网址:链接:http://pan

编译opengl编程指南第八版示例代码通过

最近在编译opengl编程指南第八版的示例代码,如下 1 #include <iostream> 2 #include "vgl.h" 3 #include "LoadShaders.h" 4 5 using namespace std; 6 7 8 enum VAO_IDs { Triangles, NumVAOs }; 9 enum Buffer_IDs { ArrayBuffer, NumBuffers }; 10 enum Attrib_IDs

VS15 openGL 编程指南 配置库 triangle例子

最近去图书馆借了一本书<OpenGL编程指南(原书第八版)>,今天倒腾了一天才把第一个例子运行出来. 所以,给大家分享一下,希望能快速解决配置问题. 一.下载需要的库文件 首先,我们需要去该书的网站中下载相关的配置文件,书中给的是"红宝书"的官方网址:http://www.opengl-redbook.com/ 但现在已经更新至第九版,里面的库不是很完整,不适宜用于此书示例. 所以我们要找一个第八版的资源:http://pan.baidu.com/s/1kVpv1MR 下载

Visual Studio 2017上配置OpenGL编程指南第8版开发环境

一直想学习一下OpenGL,买了红宝书第8版,却因为工作原因一直没有时间看,最近利用周末尝试了一下配置开发环境,遇到了一些坑点,现在记录下来备用. 第一步:打开Visual Studio 2017,建立一个空的C++工程 第二步:新建triangles.cpp文件,并写入书本例子中的代码 /////////////////////////////////////////////////////////////////////// // // triangles.cpp // //////////

《OpenGL编程指南第七版》学习——编译时提示“error C2381: “exit” : 重定义;__declspec(noreturn) 不同”错误的解决办法

解决办法一. #if defined(_WIN32) # ifndef GLUT_BUILDING_LIBextern _CRTIMP void __cdecl exit(int); 上面是glut.h中对exit的使用,意思是如果没有定义宏?GLUT_BUILDING_LIB,就使用它的exit,那我们就在项目的属性--预处理器 里定义这个宏,这样就不执行glut.h中的exit了,而只执行stdlib.h中的exit.这样也就不会冲突了.对了,还要在附加依赖项里手动加上?glut32.lib

OpenGL 编程指南 (3.1)

1.OpenGL使用的是RGB颜色空间,例如三个颜色分量各占8位,那么就说这个颜色值色深24,能够表示2^24中颜色. 2.多重采样是基于采样的抗锯齿技术,有OGAA(ordered grid anti-sliasing).SGAA(sparse grid anti-aliasing).MSAA(multi-sampling anti-aliasing).CSAA(coverage sampling anti-aliasing)等众多实现方式.fragment shader中有gl_Sample

OpenGL 编程指南 (3.2)

1.帧缓冲对象 帧缓冲对象对于离屏渲染.纹理贴图更新.缓存乒乓技术(buffer ping-pongqing,GPGPU的一种数据传输方式)的实现意义非凡,它减少了大量的数据拷贝工作. 建立帧缓冲需要负责建立帧缓冲使用的其它缓冲内容,也就是说,新建的帧缓冲只是一个空壳,具体的渲染缓冲对象被称之为帧缓冲附件.下面是一个简单的可用帧缓冲建立示例: 帧缓冲是比较消耗内存的,所以OpenGL提供了可以将帧缓冲一部分或者全部无效化从而立即释放内存的操作 void glInvalidFramebuffer(

如何将OpenGL编程指南中的带main的源码改写成可以在MFC单文档编程中可以运行的程序

paradise.ezla.com.tw/files/article/html/220/220964/6363794.htmlparadise.ezla.com.tw/files/article/html/220/220964/6363866.htmlparadise.ezla.com.tw/files/article/html/220/220964/6363918.htmlparadise.ezla.com.tw/files/article/html/220/220964/6363984.ht

opengl编程指南 第七版 源码有bug Page35 lines.c 红宝书

问题1:当我照着源码敲进去的时候发现,运行的结果不对.哪里不对?源码中没有glPushAttrib(GL_LINE_STIPPLE) glPopAttrib().所以会出现每次更新点画线时在下一次绘制时会以最后一次设置的信息重绘而覆盖掉之前已绘制好的点线.所以要进行状态压栈处理和谈栈处理,这样子在刷帧重绘才不会影响其他帧的绘制结果.(原因是什么目前我也不清楚,估计是状态机的管理问题.要了解内部的绘制机制才行.)但是每次手动添加压栈和弹栈太麻烦了,所以我处理C_style的宏定义形式去实现 问题2