精华内容
下载资源
问答
  • glsl-sphere-tracing:使用“球面跟踪”算法使用GLSL跟踪隐式曲面
  • GLSL 在OpenGL中使用GLSL

    2013-11-17 17:40:05
    设置GLSL 这一节讲述在OpenGL中配置GLSL,假设你已经写好了顶点shader和像素shader。如果你还没有准备好,可以从如下网址获得相关内容: http://www.3dshaders.com/home/ ...
    设置GLSL

    这一节讲述在OpenGL中配置GLSL,假设你已经写好了顶点shader和像素shader。如果你还没有准备好,可以从如下网址获得相关内容:

    http://www.3dshaders.com/home/

    http://www.opengl.org/sdk/tools/ShaderDesigner/

    http://developer.amd.com/archive/gpu/rendermonkey/pages/default.aspx

    在OpenGL中,GLSL的shader使用的流程与C语言相似,每个shader类似一个C模块,首先需要单独编译(compile),然后一组编译好的shader连接(link)成一个完整程序。

    这里将忽略ARB扩展,只列举OpenGL2.0的代码。建议使用GLEW库:

    http://glew.sourceforge.net/

    下面的代码检查OpenGL 2.0是否可用:

    #include <GL/glew.h>
    #include <GL/glut.h>

    void main(int argc, char **argv)
    {
    glutInit(&argc, argv);
    ...
    glewInit();

    if (glewIsSupported("GL_VERSION_2_0"))
    printf("Ready for OpenGL 2.0\n");
    else
    {
    printf("OpenGL 2.0 not supported\n");
    exit(1);
    }
    setShaders();

    glutMainLoop();
    }

    下图显示了创建shader的必要步骤,函数的具体使用方法将在下面各小结描述:



    创建shader

    下图显示了创建shader的步骤:


    首先创建一个对象作为shader的容器,这个创建函数将返回容器的句柄。

    GLuint glCreateShader(GLenum shaderType);
    参数:
    ·shaderType – GL_VERTEX_SHADER or GL_FRAGMENT_SHADER.

    你可以创建许多shader,但记住所有的顶点shader只能有一个main函数,所有像素shader也一样。

    下一步将添加源代码。shader的源代码是一个字符串数组,添加的语法如下:

    void glShaderSource(GLuint shader, int numOfStrings, const char **strings, int *lenOfStrings);
    参数:
    ·shader – the handler to the shader.
    ·numOfStrings – the number of strings in the array.
    ·strings – the array of strings.
    ·lenOfStrings – an array with the length of each string, or NULL, meaning that the strings are NULL terminated.

    最后编译shader:

    void glCompileShader(GLuint shader);
    参数:
    •shader – the handler to the shader.

    创建程序

    下图显示了获得一个可以运行的shader程序的步骤:


    首先创建一个对象,作为程序的容器。此函数返回容器的句柄。

    GLuint glCreateProgram(void);

    你可以创建任意多个程序,在渲染时,可以在不同程序中切换,甚至在某帧返回固定功能流水线。比如你想用折射和反射shader绘制一个茶杯,然后回到固定功能生成立方体环境贴图(cube map)显示背景。

    下面将把上一节编译的shader附加到刚刚创建的程序中。方法如下:

    void glAttachShader(GLuint program, GLuint shader);
    参数:
    ·program – the handler to the program.
    ·shader – the handler to the shader you want to attach.

    如果同时有顶点shader和片断shader,你需要把它们都附加到程序中。你可以把多个相同类型(顶点或像素)的shader附加到一个程序中,如同一个C程序可以有多个模块一样,但它们只能有一个main函数。

    你也可以把一个shader附加到多个程序,比如你想在不同程序中使用某个相同的shader。

    最后一步是连接程序。方法如下:

    void glLinkProgram(GLuint program);
    参数:
    ·program – the handler to the program.

    在连接操作之后,shader的源代码可以被修改并重编译,并不会影响到整个程序。

    程序连接后,可以调用glUseProgram来使用程序。每个程序都分配了一个句柄,你可以事先连接多个程序以备使用。

    void glUseProgram(GLuint prog);
    参数:
    ·prog – the handler to the program you want to use, or zero to return to fixed functionality.

    当一个程序被使用后,如果被再次连接,它将被自动替换并投入使用,所以没有必要再次调用上面这个函数。如果使用的参数为0,表示将使用固定功能流水线。

    例子

    下面的代码包含了上面描述的所有步骤,参数p,f,v是全局的GLuint型变量。

    void setShaders()
    {
    char *vs,*fs;

    v = glCreateShader(GL_VERTEX_SHADER);
    f = glCreateShader(GL_FRAGMENT_SHADER);

    vs = textFileRead("toon.vert");
    fs = textFileRead("toon.frag");

    const char *vv = vs;
    const char *ff = fs;

    glShaderSource(v, 1, &vv, NULL);
    glShaderSource(f, 1, &ff, NULL);

    free(vs);free(fs);

    glCompileShader(v);
    glCompileShader(f);

    p = glCreateProgram();

    glAttachShader(p, v);
    glAttachShader(p, f);

    glLinkProgram(p);
    glUseProgram(p);
    }

    错误处理

    调试shader是很困难的。目前还没有像printf这样的东西,虽然未来可能出现有调试功能的开发工具。

    编译阶段的状态可以用如下函数获得:

    void glGetShaderiv(GLuint object, GLenum type, int *param);
    参数:
    ·object – the handler to the object. Either a shader or a program
    ·type – GL_COMPILE_STATUS.
    ·param – the return value, GL_TRUE if OK, GL_FALSE otherwise.

    连接阶段的状态可以用如下函数获得:

    void glGetProgramiv(GLuint object, GLenum type, int *param);
    参数:
    ·object – the handler to the object. Either a shader or a program
    ·type – GL_LINK_STATUS.
    ·param – the return value, GL_TRUE if OK, GL_FALSE otherwise.

    如果发生错误,就需要从InfoLog中找到更多的信息。这个日志保存了最后一次操作的信息,比如编译时的警告、错误,连接时发生的各种问题。这个日志甚至可以告诉你硬件是否支持你的shader。不幸的是InfoLog没有一个规范,所以不同的驱动/硬件可能产生不同的日志信息。

    为了获得特定shader或程序的日志,可以使用如下程序:

    void glGetShaderInfoLog(GLuint object, int maxLen, int *len, char *log);
    void glGetProgramInfoLog(GLuint object, int maxLen, int *len, char *log);
    参数:
    ·object – the handler to the object. Either a shader or a program
    ·maxLen – The maximum number of chars to retrieve from the InfoLog.
    ·len – returns the actual length of the retrieved InfoLog.
    ·log – The log itself.

    GLSL规范有必要在这里进行一些改进:你必须知道接收InfoLog的长度。为了找到这个准确的值,使用下面的函数:

    void glGetShaderiv(GLuint object, GLenum type, int *param);
    void glGetProgramiv(GLuint object, GLenum type, int *param);
    参数:
    ·object – the handler to the object. Either a shader or a program
    ·type – GL_INFO_LOG_LENGTH.
    ·param – the return value, the length of the InfoLog.

    下面的函数可以用来打印InfoLog的内容:

    void printShaderInfoLog(GLuint obj)
    {
    int infologLength = 0;
    int charsWritten = 0;
    char *infoLog;

    glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infologLength);

    if (infologLength > 0)
    {
    infoLog = (char *)malloc(infologLength);
    glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);
    printf("%s\n",infoLog);
    free(infoLog);
    }
    }

    void printProgramInfoLog(GLuint obj)
    {
    int infologLength = 0;
    int charsWritten = 0;
    char *infoLog;

    glGetProgramiv(obj, GL_INFO_LOG_LENGTH,&infologLength);

    if (infologLength > 0)
    {
    infoLog = (char *)malloc(infologLength);
    glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog);
    printf("%s\n",infoLog);
    free(infoLog);
    }
    }

    清理

    前面的小节讲到了附加一个shader到一个程序中,这里的调用是将shader从程序中分离:

    void glDetachShader(GLuint program, GLuint shader);
    参数:
    ·program – The program to detach from.
    ·shader – The shader to detach.

    注意,只有没有附加到任何程序的shader可以被删除,删除shader和程序的调用如下:

    void glDeleteShader(GLuint id);
    void glDeleteProgram(GLuint id);
    参数:
    ·id – The hanuler of the shader or program to delete.

    如果一个shader还附加在某个程序中,这个shader并不能真正删除,只能标记为删除。当这个shader从所有程序中分离之后,才会被最终删除。

    展开全文
  • OSG使用GLSL各个版本例子

    千次阅读 2018-09-06 16:19:34
    GLSL版本以opengl3.3为分界线,opengl3.3及以上使用的是高版本着色器,以下则是低版本着色器。OSG是兼容OpenGL的所以着色器语言既能用OGL低版本也可以用高版本的。如下使用的两个例子 1.使用OpenGL高版本着色器...

    GLSL版本以opengl3.3为分界线,opengl3.3及以上使用的是高版本着色器,以下则是低版本着色器。OSG是兼容OpenGL的所以着色器语言既能用OGL低版本也可以用高版本的。如下使用的两个例子


    1.使用OpenGL高版本着色器(OpenGL4.3)
    2.使用OpenGL低级版本着色器(OpenGL2.X)


    使用OpenGL高版本着色器(OpenGL4.3)

    #include <dtABC/application.h>
    #include <dtUtil/nodeprintout.h>
    
    #include <dtCore/object.h>
    #include <dtCore/orbitmotionmodel.h>
    
    #include <osg/shader>
    #include <osg/Node>
    #include <osgDB/ReadFile>
    #include <osgDB/fileutils>
    #include <osg/Geometry>
    #include <osgViewer/viewer>
    
    static char * vertexShader= {
            "#version 430 \n"
            "layout (location=0) in vec3 VertexPosition;\n"
            "layout (location=1) in vec4 VertexColor;\n"
            "uniform mat4 MVP;"
            "out vec4 Color;\n"
            "void main()\n"
            "{\n"
                "   Color = VertexColor;\n"
                "   gl_Position = MVP * vec4(VertexPosition,1.0);\n"
        "   }\n"
    };
    
    static char * fragShader ={
            "#version 430 \n"
            "in vec4 Color;\n"
            "layout (location=0) out vec4 FragColor;\n"
            "void main() {\n"
            "   FragColor = Color;//vec4(0.5,0.5,0.5,0.4);\n"
            "}\n"
    };
    osg::Node *  CreateNode()
    {
            osg::Geode * geode = new osg::Geode;
             osg::Geometry* polyGeom = new osg::Geometry();
            osg::Vec3Array* vertices = new osg::Vec3Array();
            vertices->push_back(osg::Vec3(-5,0,0));
            vertices->push_back(osg::Vec3(5,0,0));
            vertices->push_back(osg::Vec3(0,0,5));
            //polyGeom->setVertexArray(vertices);
    
    
            osg::ref_ptr<osg::Vec4Array> colorsArray = new osg::Vec4Array;
            colorsArray->push_back(osg::Vec4(1.0f,0.0f,0.0f,1.0f));
            colorsArray->push_back(osg::Vec4(0.0f,0.0f,1.0f,1.0f));
            colorsArray->push_back(osg::Vec4(0.0f,1.0f,0.0f,1.0f));
        //  polyGeom->setColorArray(colorsArray.get());
            //polyGeom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
    
            polyGeom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,0,3));
    
            /*
            The osg::Geometry class uses the setVertexAttribArray() and
            setVertexAttribBinding() methods to bind vertex attributes to shaders. They should
            be provided per vertex. GLSL's built-in vertex attributes include the gl_Position, gl_
            Normal, and gl_MultiTexCoord* variables. However, you may still specify your own
            vertex attributes, such as tangents or vertex weights.
            Try declaring an attribute in the vertex shader and make use of the osg::Geometry's vertex
            attribute arrays. Another important task that you need to perform is to bind the external
            attribute array and the GLSL attribute, with the help of the addBindAttribLocation()
            method of osg::Program. It has a name and an index parameter, the first of which
            indicates the attribute name in the shader source code, and the second should correspond
            to the input index value of setVertexAttribArray().
            */
            polyGeom->setVertexAttribArray(0,vertices);
            polyGeom->setVertexAttribBinding(0, osg::Geometry::BIND_PER_VERTEX);
            polyGeom->setVertexAttribArray(1,colorsArray.get());    
            polyGeom->setVertexAttribBinding(1, osg::Geometry::BIND_PER_VERTEX);
    
            geode->addDrawable(polyGeom);
            return geode; 
    }
    
    class MVPCallback: public osg::Uniform::Callback
    {
    public:
            MVPCallback(osg::Camera * camera):mCamera(camera){
            }
             virtual void operator()( osg::Uniform* uniform, osg::NodeVisitor* nv){
                     osg::Matrix modelView = mCamera->getViewMatrix();
                     osg::Matrix projectM = mCamera->getProjectionMatrix();
                     uniform->set(modelView * projectM);
             }
    
    private:
            osg::Camera * mCamera;
    };
    int main(int argc, char *argv[]) {   
    
            osgViewer::Viewer viewer;
    
            osg::Group * root = new osg::Group;
            osg::ref_ptr<osg::Node>node = CreateNode();
    
            osg::StateSet * ss = node->getOrCreateStateSet();
            osg::Program * program = new osg::Program;
            program->addBindFragDataLocation("VertexPosition",0);
            program->addBindFragDataLocation("VertexColor",1);
    
            osg::Shader * vS = new osg::Shader(osg::Shader::FRAGMENT,fragShader); 
            osg::Shader * fS = new osg::Shader(osg::Shader::VERTEX,vertexShader); 
            osg::Uniform* MVPUniform = new osg::Uniform( "MVP",osg::Matrix());
            MVPUniform->setUpdateCallback(new MVPCallback(viewer.getCamera()));
            ss->addUniform(MVPUniform);//对应的Program和Uniform要加到同一个Node下的StateSet中
            program->addShader(vS);
            program->addShader(fS);
            ss->setAttributeAndModes(program,osg::StateAttribute::ON);
    
            root->addChild(node); 
            viewer.setSceneData(root);
    
            viewer.run();
    
            return 0;
    }
    

    使用OpenGL低级版本着色器(OpenGL2.X)

    
    #include <osg/Node>
    #include <osgViewer/Viewer>
    #include <osg/Program>
    #include <osgDB/ReadFile>
    #include <osg/Shader>
    #include <osgViewer/ViewerEventHandlers>
    
    
    static char * vertexShader = {
        "varying vec4 color;\n"
        "void main(void ){\n"
            "color = gl_Vertex;\n"
            "gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;\n"
        "}\n"
    };
    static char * fragShader = {
        "varying vec4 color;\n"
        "void main(void){\n"
        "   gl_FragColor = clamp(color,0.0,1.0);\n"
        "}\n"
    };
    int main()
    {
        osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
        osg::ref_ptr<osg::Node>node = osgDB::readNodeFile("glider.osg");
    
    
        osg::StateSet * ss = node->getOrCreateStateSet();
        osg::Program * program = new osg::Program;
        program->addShader(new osg::Shader(osg::Shader::FRAGMENT,fragShader));
        program->addShader(new osg::Shader(osg::Shader::VERTEX,vertexShader));
        ss->setAttributeAndModes(program,osg::StateAttribute::ON);
    
        viewer->addEventHandler(new osgViewer:: WindowSizeHandler);
        viewer->setSceneData(node.get());
        return viewer->run();
    }
    展开全文
  • OpenGL中使用GLSL着色器

    千次阅读 2014-12-15 17:37:24
    OpenGL中使用GLSL着色器步骤  GLSL既适用于顶点着色器,也适用于片段着色器。 使用着色器对象的步骤: 1、创建着色器对象:  GLuint glCreateShader(GLenum type); //创建一个着色器...


    OpenGL中使用GLSL着色器步骤


        GLSL既适用于顶点着色器,也适用于片段着色器。


    使用着色器对象的步骤:

    1、创建着色器对象:
       GLuint glCreateShader(GLenum type);
    //创建一个着色器对象,type值必须是GL_VERTEX_SHADER或GL_FRAGMENT_SHADER。error返回0
    2、把着色器的源码与着色器对象相关联:
        glShaderSource(GLuint shader, GLsizei count, const GLChar** string, const GLint* length);
    3、编译着色器对象的源码:
        void glCompileShader(GLuint shader);
       glGetShaderiv(GL_CIMPILE_STATUS);  //查询编译结果
       glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, char* infoLog);
    4、创建一个空的着色器程序:
       Gluint glCreateProgram();   //if error, return 0;
    5、把着色器对象连接到着色器程序:
       glAttachShader(GLuint program, GLuint shader);   //glDetachShader(program, shader);
    6、把连接到着色器程序中的对象链接成一个可执行程序:
       voi glLinkProgram(GLuint program);
       glGetProgramiv(GL_LINK_STATUS);    //查询链接结果, GL_TRUE represent success
       glGetProgramInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, char* infoLog);
    7、启动顶点或片段着色器程序:
       void glUseProgram(GLuint program);   //使用程序的对象句柄作为参数
    eg:

    GLuint shader,program;
    GLuint compiled, linked;
    const GLchar* shaderSrc[] = {
        "void main(){"
        "   gl_Position = gl_ModelViewProjectionMatrix *gl_Vertex;"
        "}"
    };
    
    shader = glCreateShader(GL_VERTEX_SHADER);
    
    glShaderSource(shader, 1, shaderSrc, NULL);
    glCompileShader(shader);
    
    glGetShaderInfoLog(shader, GL_COMPILE_STATUS, &compiled);
    if(!compiled){
        GLint length;
        GLchar* log;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
        log = (GLchar*)malloc(length);
        glGetShaderInfoLog(shader, length, &length, log);
        fprintf(stderr, "compile log = '%s '\n", log);
        free(log);
    }
    
    program =glCreateProgram();
    
    glAttachShader(program, shader);
    glLinkProgram(program);
    
    glGetProgramiv(program, GL_LINK_STATUS, &linked);
    
    if(linker){
        glUseProgram(program);
    }else{
        GLint length;
        GLchar* log;
        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
    
        log = (GLchar*)malloc(length);
        glGetProgramInfoLog(program, length, &length, log);
        fprintf(stderr, "link log = '%s ' \n", log);
        free(log);
    }
    

    删除着色器:

        void glDeleteShader(GLuint shader); //若正在被使用,标记为删除,使用完后删除
    判断是否是否是有效的着色器程序名:
        GLboolean glIsProgram(GLuint program);  //GL_TRUE
    验证一个着色器是否可在当前的OpenGL状态下执行:
        void glValidateProgram(GLuint program);

    //若验证通过,GL_VALIDATE_STATUS被设置为GL_TRUE, 调用glGetProgramiv()查询GL_VALIDATE_STATUS的值。



    展开全文
  • 在OpenGL中使用GLSL

    2018-04-11 16:47:24
    原文是一个GLSL入门教程系列设置GLSL这一节讲述在OpenGL中配置GLSL,假设你已经写好了顶点shader和像素shader。如果你还没有准备好,可以从如下网址获得相关内容:...

    原文是一个GLSL入门教程系列


    设置GLSL

    这一节讲述在OpenGL中配置GLSL,假设你已经写好了顶点shader和像素shader。如果你还没有准备好,可以从如下网址获得相关内容:

    http://www.3dshaders.com/home/

    http://www.opengl.org/sdk/tools/ShaderDesigner/

    http://developer.amd.com/archive/gpu/rendermonkey/pages/default.aspx

    在OpenGL中,GLSL的shader使用的流程与C语言相似,每个shader类似一个C模块,首先需要单独编译(compile),然后一组编译好的shader连接(link)成一个完整程序。

    这里将忽略ARB扩展,只列举OpenGL2.0的代码。建议使用GLEW库:

    http://glew.sourceforge.net/

    下面的代码检查OpenGL 2.0是否可用:

    1. #include <GL/glew.h>  
    2. #include <GL/glut.h>  
    3.   
    4. void main(int argc, char **argv)  
    5. {  
    6.     glutInit(&argc, argv);  
    7.     ...  
    8.     glewInit();  
    9.   
    10.     if (glewIsSupported("GL_VERSION_2_0"))  
    11.         printf("Ready for OpenGL 2.0\n");  
    12.     else  
    13.     {  
    14.         printf("OpenGL 2.0 not supported\n");  
    15.         exit(1);  
    16.     }  
    17.     setShaders();  
    18.   
    19.     glutMainLoop();  
    20. }  

    下图显示了创建shader的必要步骤,函数的具体使用方法将在下面各小结描述:


    创建shader

    下图显示了创建shader的步骤:


    首先创建一个对象作为shader的容器,这个创建函数将返回容器的句柄。

    1. GLuint glCreateShader(GLenum shaderType);  
    2. 参数:  
    3. ·shaderType – GL_VERTEX_SHADER or GL_FRAGMENT_SHADER.  
    你可以创建许多shader,但记住所有的顶点shader只能有一个main函数,所有像素shader也一样。

    下一步将添加源代码。shader的源代码是一个字符串数组,添加的语法如下:

    1. void glShaderSource(GLuint shader, int numOfStrings, const char **strings, int *lenOfStrings);  
    2. 参数:  
    3. ·shader – the handler to the shader.  
    4. ·numOfStrings – the number of strings in the array.  
    5. ·strings – the array of strings.  
    6. ·lenOfStrings – an array with the length of each string, or NULL, meaning that the strings are NULL terminated.  
    最后编译shader:

    1. void glCompileShader(GLuint shader);  
    2. 参数:  
    3. •shader – the handler to the shader.  


    创建程序

    下图显示了获得一个可以运行的shader程序的步骤:


    首先创建一个对象,作为程序的容器。此函数返回容器的句柄。

    1. GLuint glCreateProgram(void);  

    你可以创建任意多个程序,在渲染时,可以在不同程序中切换,甚至在某帧返回固定功能流水线。比如你想用折射和反射shader绘制一个茶杯,然后回到固定功能生成立方体环境贴图(cube map)显示背景。

    下面将把上一节编译的shader附加到刚刚创建的程序中。方法如下:

    1. void glAttachShader(GLuint program, GLuint shader);  
    2. 参数:  
    3. ·program – the handler to the program.  
    4. ·shader – the handler to the shader you want to attach.  
    如果同时有顶点shader和片断shader,你需要把它们都附加到程序中。你可以把多个相同类型(顶点或像素)的shader附加到一个程序中,如同一个C程序可以有多个模块一样,但它们只能有一个main函数。

    你也可以把一个shader附加到多个程序,比如你想在不同程序中使用某个相同的shader。

    最后一步是连接程序。方法如下:

    1. void glLinkProgram(GLuint program);  
    2. 参数:  
    3. ·program – the handler to the program.  
    在连接操作之后,shader的源代码可以被修改并重编译,并不会影响到整个程序。

    程序连接后,可以调用glUseProgram来使用程序。每个程序都分配了一个句柄,你可以事先连接多个程序以备使用。

    1. void glUseProgram(GLuint prog);  
    2. 参数:  
    3. ·prog – the handler to the program you want to use, or zero to return to fixed functionality.  
    当一个程序被使用后,如果被再次连接,它将被自动替换并投入使用,所以没有必要再次调用上面这个函数。如果使用的参数为0,表示将使用固定功能流水线。

     例子

    下面的代码包含了上面描述的所有步骤,参数p,f,v是全局的GLuint型变量。

    1. void setShaders()  
    2. {  
    3.     char *vs,*fs;  
    4.   
    5.     v = glCreateShader(GL_VERTEX_SHADER);  
    6.     f = glCreateShader(GL_FRAGMENT_SHADER);    
    7.   
    8.     vs = textFileRead("toon.vert");  
    9.     fs = textFileRead("toon.frag");  
    10.   
    11.     const char *vv = vs;  
    12.     const char *ff = fs;  
    13.   
    14.     glShaderSource(v, 1, &vv, NULL);  
    15.     glShaderSource(f, 1, &ff, NULL);  
    16.   
    17.     free(vs);free(fs);  
    18.   
    19.     glCompileShader(v);  
    20.     glCompileShader(f);  
    21.   
    22.     p = glCreateProgram();  
    23.   
    24.     glAttachShader(p, v);  
    25.     glAttachShader(p, f);  
    26.   
    27.     glLinkProgram(p);  
    28.     glUseProgram(p);  
    29. }  
    GLUT版的完整例子如下:

    http://lighthouse3d.com/wptest/wp-content/uploads/2011/03/glutglsl_2.0.zip

    完整例子中包含了shader代码及文本文件读入程序。

     

    错误处理

    调试shader是很困难的。目前还没有像printf这样的东西,虽然未来可能出现有调试功能的开发工具。

    编译阶段的状态可以用如下函数获得:

    1. void glGetShaderiv(GLuint object, GLenum type, int *param);  
    2. 参数:  
    3. ·object – the handler to the object. Either a shader or a program  
    4. ·type – GL_COMPILE_STATUS.  
    5. ·param – the return value, GL_TRUE if OK, GL_FALSE otherwise.  
    连接阶段的状态可以用如下函数获得:

    1. void glGetProgramiv(GLuint object, GLenum type, int *param);  
    2. 参数:  
    3. ·object – the handler to the object. Either a shader or a program  
    4. ·type – GL_LINK_STATUS.  
    5. ·param – the return value, GL_TRUE if OK, GL_FALSE otherwise.  
    如果发生错误,就需要从InfoLog中找到更多的信息。这个日志保存了最后一次操作的信息,比如编译时的警告、错误,连接时发生的各种问题。这个日志甚至可以告诉你硬件是否支持你的shader。不幸的是InfoLog没有一个规范,所以不同的驱动/硬件可能产生不同的日志信息。

    为了获得特定shader或程序的日志,可以使用如下程序:

    1. void glGetShaderInfoLog(GLuint object, int maxLen, int *len, char *log);  
    2. void glGetProgramInfoLog(GLuint object, int maxLen, int *len, char *log);  
    3. 参数:  
    4. ·object – the handler to the object. Either a shader or a program  
    5. ·maxLen – The maximum number of chars to retrieve from the InfoLog.  
    6. ·len – returns the actual length of the retrieved InfoLog.  
    7. ·log – The log itself.  
    GLSL规范有必要在这里进行一些改进:你必须知道接收InfoLog的长度。为了找到这个准确的值,使用下面的函数:

    1. void glGetShaderiv(GLuint object, GLenum type, int *param);  
    2. void glGetProgramiv(GLuint object, GLenum type, int *param);  
    3. 参数:  
    4. ·object – the handler to the object. Either a shader or a program  
    5. ·type – GL_INFO_LOG_LENGTH.  
    6. ·param – the return value, the length of the InfoLog.  

    下面的函数可以用来打印InfoLog的内容:

    1. void printShaderInfoLog(GLuint obj)  
    2. {  
    3.     int infologLength = 0;  
    4.     int charsWritten  = 0;  
    5.     char *infoLog;  
    6.    
    7.     glGetShaderiv(obj, GL_INFO_LOG_LENGTH,&infologLength);  
    8.    
    9.     if (infologLength > 0)  
    10.     {  
    11.         infoLog = (char *)malloc(infologLength);  
    12.         glGetShaderInfoLog(obj, infologLength, &charsWritten, infoLog);  
    13.         printf("%s\n",infoLog);  
    14.         free(infoLog);  
    15.     }  
    16. }   
    17.   
    18. void printProgramInfoLog(GLuint obj)  
    19. {  
    20.     int infologLength = 0;  
    21.     int charsWritten  = 0;  
    22.     char *infoLog;  
    23.    
    24.     glGetProgramiv(obj, GL_INFO_LOG_LENGTH,&infologLength);  
    25.    
    26.     if (infologLength > 0)  
    27.     {  
    28.         infoLog = (char *)malloc(infologLength);  
    29.         glGetProgramInfoLog(obj, infologLength, &charsWritten, infoLog);  
    30.         printf("%s\n",infoLog);  
    31.         free(infoLog);  
    32.     }  
    33. }  

    清理

    前面的小节讲到了附加一个shader到一个程序中,这里的调用是将shader从程序中分离:

    1. void glDetachShader(GLuint program, GLuint shader);  
    2. 参数:  
    3. ·program – The program to detach from.  
    4. ·shader – The shader to detach.  
    注意,只有没有附加到任何程序的shader可以被删除,删除shader和程序的调用如下:

    1. void glDeleteShader(GLuint id);  
    2. void glDeleteProgram(GLuint id);  
    3. 参数:  
    4. ·id – The hanuler of the shader or program to delete.  

    如果一个shader还附加在某个程序中,这个shader并不能真正删除,只能标记为删除。当这个shader从所有程序中分离之后,才会被最终删除。

    转载地址: https://blog.csdn.net/racehorse/article/details/6616256

    参考:



    展开全文
  • 这是一个Qt下开发GLSL程序的简单demo,我的博客里面有关于这个的介绍~~
  • 设置GLSL 这一节讲述在OpenGL中配置GLSL,假设你已经写好了顶点shader和像素shader。如果你还没有准备好,可以从如下网址获得相关内容: http://www.3dshaders.com/home/ ... ...
  • 这个插件使用 GLSL 进行去隔行处理。 GLSL 代码参考下面的讨论主题。 如何使用 您只需将视频纹理引用发送到 setup() 函数中的插件即可。 video.loadMovie("1080i.mov"); video.play(); deinterlace = new ...
  • 在Unity,我们将转移到其他着色器编译管道,其中不使用glsl-optimizer。 因此,就我而言,将不会进行大量工作。 :warning_selector: 一个采用GLSL着色器的C ++库,对它们进行一些独立于GPU的优化,然后输出GLSL或...
  • 像素缩放 使用GLSL中的hqx滤镜进行像素缩放 (使用方法)
  • GLSL

    2019-08-19 18:44:57
    GLSL 文章目录GLSL@[toc]修饰符:内置变量顶点着色器可用的内置变量:片段着色器的内置变量:操作符关于矩阵discard函数类型转换 最近星音写了一款能够在AE中支持写shader的插件PixelsWorld,就着他在群里给的测试...
  • 这是一个在Qt下利用GLSL制作的一个变色小球。利用uniform从opengl主程序向shader传递当前时间,影响小球颜色。可以参考我写的一个Qt和GLSL的教程:http://blog.csdn.net/mahabharata_/article/details/70337908
  • GLSL中的Raymarching实验。 程序树,仅在片段着色器中渲染。 在查看详细信息。
  • Visual Studio设置shader(CG 、GLSL)语法提示及高亮和显示行号 使用GLSL language ...使用GLSL language integration插件,目前支持vs2017和vs2019,vs2015支持 打开vs2017,选择工具->扩展和更新,输入 GLS
  • 使用GLSL实现雾化的效果

    千次阅读 2016-04-12 14:51:18
    1 为什么需要在GLSL中实现雾的效果?  D3D10已经不再支持固定管线的绘制了,所有的绘制都得使用着色器语言。OpenGL虽说仍然支持固定管线,但以后难说。因为趋势如此,所以学习没有坏处。 另外,我的场景使用...
  • grimoire:跨平台实时编码工具,可使用GLSL着色器进行创意编码
  • GLSL-游乐场 用于直接在 GPU 上生成程序地形的 GLSL 着色器。 最近,我对程序化景观生成产生了浓厚的兴趣,尤其是您可以使用着色器直接在现代 GPU 上执行的操作。 我的目标是仅使用最小的纹理集并在任何可能的地方...
  • 使用 GLSL 着色器的各种有用的东西。 GLSL-doxygen 过滤器 用于处理 GLSL 着色器的过滤器,解释用法。 一个例子可以在看到。 您还可以在 doxygen/doxytest 子文件夹中运行doxygen以生成最小示例的文档。 tl;博士 将...
  • GLSL 工具包是 Blender 的附加组件,可帮助简化使用内置 GLSL 实时渲染引擎进行哑光绘画和基本合成的过程。 安装 以 zip 格式下载插件 在 Blender 中,转到用户首选项,然后单击从文件安装 导航到 .zip 的位置并安装...
  • 一个插件,用于使用GLSL的模块系统处理GLSL代码。 例子 在 import glsl from 'glslify' ; const frag = glsl ` #pragma glslify: random = require(glsl-random) void main () { float brightness = random(gl_...
  • cocos2dx 使用glsl

    千次阅读 2015-02-26 00:18:32
    class ShaderNode : public Node { public: static ShaderNode* shaderNodeWithVertex(const std::string &vert, const std::string &frag); virtual void update(float dt); virtual void draw(Re

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,882
精华内容 6,352
关键字:

不使用glsl