OpenGL总结

最近2D转向3D,也从固定管线转到了可编程管线,有些细节的东西记录一下。

Geometry Shader

Geometry Shader从Vertex Shader中获取数据,向Fragment Shader输出数据。

Geometry Shader的布局限定符:

layout (a1) in;
layout (a2,max_vertices = 3) out;

a1表示输入图元类型,可以使lines、triangles等值,这个值的所有取值可以查表,此值需要和API中Drawcall的传入的绘制类型兼容,如果这里填写lines,那么DrawCall就必须是GL_LINES或者兼容的类型,具体的兼容类型可以查表。

a2表示输出图元类型,这个类型指定了GS所有EmitVertex产生的点的链接方式,如果是triangle_strip,那么就是输出三角扇,多余的点会被自动移除。后面的max_vertices执行一次shader允许产生的最大顶点数。这个东西我在开始的时候忽略了,所以在一个图元遍历的时候,总是无法产生出3个以上的顶点。

GS的in/out/uniform和其他vs和fs一样,API创建方式也一样,只要更改类型就行了,但是GS的in如果在输入图元是多个顶点的话应该是相同名字的数组,这一点如果没加我用的A卡编译器当前版本驱动是会指出来的。其他就不知道了。

GS产生顶点使用EmitVertex()函数,产生的位置就是当前gl_Position的位置,也就是当前位置。在GS处理顶点的时候,必须要手动生成原顶点,否则下一阶段将会没有这些顶点输出。也就是如果写一个空的GS,这意味着丢弃了所有顶点。

EndPrimitive()用于中断一个图元带。这个函数的调用意味着,前面生成的所有顶点将会按照a2的指定方式生成图元带。如果剩余的点不足以生成一个图元,那些点将会被丢弃。想要生成单个的带,可以在生成一个完整的图元后就调用这个函数。比如a2=line_strip,那就可以在产生两个顶点后就中断,如此就可以产生一根直线了。

关于坐标变换,我使用GS来可视化一个模型的发现,以确保这些发现是正确的。于是我在传入这个GS的法线和顶点都是只转换到view空间的,计算完成后再统一做透视处理。

#version 410 core

layout (triangles) in;
layout (triangle_strip,max_vertices = 3) out;
uniform mat4 mv_matrix;
uniform mat4 proj_matrix;
uniform int vn;
in vec3 onormal[];
in vec3 normal[];
out vec3 normalo;
void main()
{
    vec4 position;
    int i;

    for(i=0;i<gl_in.length();i++)
    {
        if(vn==0)
        {
            vec3 n = normal[i];
            normalo = n;
            gl_Position = proj_matrix*gl_in[i].gl_Position;
            EmitVertex();
        }
        else
        {
            vec3 on = onormal[i];
            vec3 n = normal[i];
            normalo = n;
            gl_Position = proj_matrix*gl_in[i].gl_Position;
            EmitVertex();
            EmitVertex();
            position = gl_in[i].gl_Position + 6*vec4(n,0.f);
            gl_Position = proj_matrix*position;
            EmitVertex();
            EndPrimitive();
        }
    }
    EndPrimitive();

}

还有GS的输入,gl_in数组是默认输入,这个输入跟随输入类型而变化长度,这个数组的元素是顶点结构体,它的隐式声明是:

in gl_PerVertex
{
    vec4 gl_Position;
    float gl_PointSize;
    float gl_ClipDistance[];
} gl_in[];

关于API:

多个物体想要正确的呈现必须开启深度测试,否则就什么也看不见了,开启深度测试必须先要位深度缓存赋初始值,一般赋值为:

glClearDepth(1);

开启深度测试:

glEnable(GL_DEPTH_TEST);

没帧清理深度缓存:

glClear(GL_DEPTH_BUFFER_BIT);

另外可以设置深度测试的测试等式,这个都好说。

另外,背面剔除和设置多边形渲染模式(可以渲染成线框)

glEnable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK   ,GL_LINE   );
时间: 2025-01-07 08:28:57

OpenGL总结的相关文章

OpenGL编程 基础篇(五)世界窗口和视口

一.基本定义 世界窗口:在世界坐标系中定义一个对齐的矩形(aligned rectangle,即矩阵的边与坐标轴平行)的窗口,这个世界窗口外的部分被裁减并不被绘制.OpenGL会自动地做剪裁. 视口:在显示器的屏幕窗口上定义一个对齐的矩形的视口,OpenGL会自动建立世界窗口和视口的变换(包括缩放和平移).当世界窗口中所有对象都被绘制时,对象在世界窗 口中的部分会被自动地映射到视口中----换句话说,被映射到屏幕坐标中,即像素在显示器上的坐标. 二.相关函数介绍 1.对于二维绘图来说,世界窗口由

转:openGL入门(2)

本次课程所要讲的是绘制简单的几何图形,在实际绘制之前,让我们先熟悉一些概念. 一.点.直线和多边形 我们知道数学(具体的说,是几何学)中有点.直线和多边形的概念,但这些概念在计算机中会有所不同. 数学上的点,只有位置,没有大小.但在计算机中,无论计算精度如何提高,始终不能表示一个无穷小的点.另一方面,无论图形输出设备(例如,显示器)如何精确,始终不能输出一个无穷小的点.一般情况下,OpenGL中的点将被画成单个的像素(像素的概念,请自己搜索之~),虽然它可能足够小,但并不会是无穷小.同一像素上,

android opengl es 源码

[转自:http://blog.csdn.net/happyhell/article/details/6086973] The entire OpenGL ES API on Android is implemented in three libraries, located under /system/lib (for more information about OpenGL ES visit the official Khronos page): * libEGL.so: implemen

【OpenGL】第二篇 Hello OpenGL

------------------------------------------------------------------------------------------------------------------------------- 就像学习其他编程语言一样,为了顺利写下第一个OpenGL程序 我们必须不辞辛苦的先铺好砖块,搭建好环境…… 所以接下来让我先把所需要的库的环境安置好,再开始coding. ------------------------------------

OpenGL蓝宝书第六章代码疑虑:为什么使用了GL_TEXTURE_1D??纹理和顶点间的映射是如何实现?

遇到一个大问题,明明加载纹理绑定的是GL_TEXTURE_2D glUniform1i(locCloudTex, 1); //明明默认为0,参数却不是0. 可是原书中代码确是 glGenTextures(1, &uiTexture); glBindTexture(GL_TEXTURE_1D, uiTexture); // LoadTGATexture("Clouds.tga", GL_LINEAR, GL_LINEAR, GL_CLAMP_TO_EDGE); glUniform

OpenGL - obj文件的导入

http://blog.csdn.net/silangquan/article/details/9707347 Obj文件简介 OBJ文件是Alias|Wavefront公司为它的一套基于工作站的3D建模和动画软件"Advanced Visualizer"开发的一种标准3D模型文件格式,很适合用于3D软件模型之间的互导,也可以通过Maya读写.比如你在3dsMax或LightWave中建了一个模型,想把它调到Maya里面渲染或动画,导出OBJ文件就是一种很好的选择.目前几乎所有知名的3

OpenGL学习系列第二篇

在这个教程里,我们一起来玩第一个OpenGL程序.它将显示一个空的OpenGL窗口,可以在窗口和全屏模式下切换,按ESC退出.它是我们以后应用程序的框架. 在CodeBlock里创建一个新的GLUT Win32程序(不是console控制台程序)后,我们还需要链接OpenGL库文件. 代码的前4行包括了我们使用的每个库文件的头文件.如下所示: #include <windows.h>// Windows的头文件 #include <glew.h>       // 包含最新的gl.

Android OpenGL ES

1.Android OpenGL ES 简明开发教程3D 坐标变换: http://www.linuxidc.com/Linux/2011-10/45756p4.htm

VC++6.0中OpenGL应用程序开发

1. Win32控制台方式 建立Win32 控制台程序,在头文件中加入 #include <windows.h>  #include <wingdi.h>  #include <GL/gl.h>  #include <GL/glu.h >   #include <GL/glaux.h> 2. MFC方式 (1)采用VC AppWizard向导创建空的MFC(EXE)工程框架,整个过程总共6步,值得指出的是一般情况下在向导的第1步选择创建工程的模式

OpenGL ES编程入门资源集合

OpenGL ES 2.0中文手册:http://www.dreamingwish.com/articlelist/category/opengl-es-api 里边讲解了部分API的功能,作为基本的参考. OpenGL ES2.0 渲染管线:http://codingnow.cn/opengles/1504.html OpenGL ES2.0 绘制三角形:http://codingnow.cn/opengles/1514.html 一个OpenGL ES2.0的例子:http://blog.c