zoukankan      html  css  js  c++  java
  • OPENGL学习笔记整理(五):着色语言

    有些事情本身就是十分奇怪的。在传统上,图形硬件的设计目的是用于快速执行相同的硬编译指令集。不同的计算步骤可以被跳过,参数可以被调整,但计算本身确实固定不变的。然而,随着技术的发展,却越来越变得可以编程了。着色语言,都有些OUT了,CUDA、OPENCL什么的越来越大行其道了。当然,在这里,主要还是介绍着色语言。有些东西很新,但是却不成熟。有些东西很旧,很老土,却仍然很好用,就连OPENGL不带着色语言,现在仍然能做出很好的效果,这也是毋庸置疑的。

    传统的或称是旧式的OPENGL渲染管线的操作过程如下,(顶点和它们相关的属性)->(转换)->(光照)->(纹理坐标生成和转换)->(裁剪)->(点、直线、多边形、位图和像素矩阵的光栅化:包括平滑的、宽阔的、剔除和深度偏移的图元)->【片段和它们相关的属性】->(纹理)->(颜色求和)->(雾)->(抗锯齿)->(基于片段的操作:像素拥有权、裁剪测试、alpha测试、模板测试、混合、抖动、逻辑操作和帧缓冲区写入)。

    着色语言,是把整个图形管线的中的某些部分独立出来,变成可以编程的,即顶点着色器和片元着色器。(转换)->(光照)->(纹理坐标生成和转换)->(裁剪)的功能交给顶点着色器,纹理)->(颜色求和)->(雾)->(抗锯齿)的功能交给片段着色器。

    图形管线的问题,我也是搞了很久之后才有这个概念的,其实也就是这么几个步骤。如果你了解GPU历史的话,或许理解起来会更轻松一些,GPU最初的出现和T&L是紧密联系在一起的,这里的T就是tranform或者translate,具体是哪个单词,我现在忘了,功能就是空间变换,L则显然是LIGHTING了,光照。那么顶点着色器的作用,就是完成T&L中T的所有工作及L的所有空间坐标相关的工作,而片元着色器则是做颜色合成的工作。原先,顶点着色器和片元着色器在硬件上是分开的,现在大家都统一了。

    如果你会普通的OPENGL编程,那么你只要稍微修改下自己的思路其实就OK了。你可以想象下,你现在不再是活在三维笛卡尔空间里面的人了,你是活在极坐标当中的,可以活在自己设定的某种规则的空间当中,光照效果也不再是那么固定的了,你可以自己改变。还是看看具体的程序或者会比较容易理解。

    下面相关的代码来自 OpenGL SuperBible, Chapter 16, Demonstrates vertex blending,该程序只用到了顶点着色器,vertex shader。

    int main(int argc, char* argv[])
    {
        GLint i;
    
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
        glutInitWindowSize(windowWidth, windowHeight);
        glutCreateWindow("Vertex Shaders Demo");
        glutReshapeFunc(ChangeSize);
        glutKeyboardFunc(KeyPressFunc);
        glutSpecialFunc(SpecialKeys);
        glutDisplayFunc(RenderScene);
    
        SetupRC();
    
        // Create the menus
        shaderMenu = glutCreateMenu(ProcessMenu);
        for (i = 0; i < TOTAL_SHADERS; i++)
        {
            char menuEntry[128];
            sprintf(menuEntry, ""%s"", shaderNames[i]);
            glutAddMenuEntry(menuEntry, 1+i);
        }
    
        mainMenu = glutCreateMenu(ProcessMenu);
        {
            char menuEntry[128];
            sprintf(menuEntry, "Choose vertex shader (currently "%s")", shaderNames[0]);
            glutAddSubMenu(menuEntry, shaderMenu);
        }
        glutAttachMenu(GLUT_RIGHT_BUTTON);
    
        glutMainLoop();
    
        if (glDeleteShader && glDeleteProgram)
        {
            for (i = 0; i < TOTAL_SHADERS; i++)
            {
                glDeleteProgram(progObj[i]);
                glDeleteShader(vShader[i]);
            }
        }
    
        return 0;
    }
    
  • 相关阅读:
    读jQuery之十六(事件代理)
    双向列表(JS)
    单向链表(JS)
    子程序(过程、函数、方法)
    jQuery(1.6.3) 中css方法对浮动的实现缺陷
    操作class属性的新APIclassList
    ajax后退解决方案(四)
    设置元素浮动的几种方式
    各浏览器中使用getAttribute获取checkbox/radio的checked值不同
    IE6/7不支持hashchange事件
  • 原文地址:https://www.cnblogs.com/unsigned/p/2054746.html
Copyright © 2011-2022 走看看