zoukankan      html  css  js  c++  java
  • 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   );
  • 相关阅读:
    [OPENCV]CvMat,Mat和IplImage之间的转化和拷贝
    [计算机视觉]掩膜(mask)
    服务器被黑给我上了一课
    Nginx安装
    lvs fullnat部署手册(一)fullnat内核编译篇
    MySQL小误区:关于set global sql_slave_skip_counter=N 命令的一些点
    mysql主从复制跳过错误
    Nginx+keepalived 脚本安装主从双机热备自动切换解决方案
    This function has none of DETERMINISTIC, NO SQL解决办法
    Ansible 1.9.0发布 来一起看看这个配置管理新贵
  • 原文地址:https://www.cnblogs.com/wubugui/p/4397343.html
Copyright © 2011-2022 走看看