[Glsl tutorial] (2) use glsl in OpenGL

Source: Internet
Author: User

Set glsl

This section describes how to configure glsl in OpenGL. Assume that you have written vertex shader and pixel shader. If you are not ready, you can obtain the relevant content from the following URL:

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

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

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

In OpenGL, the shader of glsl uses a process similar to the C language. Each shader is similar to a C Module. First, you need to compile it separately (compile), and then a set of compiled shader connections (link) into a complete program.

The ARB extension will be ignored here and only the opengl2.0 code will be listed. We recommend that you use the glew Library:

Http://glew.sourceforge.net/

The following code checks OpenGL 2.0 for availability:

#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();}

The necessary steps for creating a shader are displayed. The detailed usage of the function is described below:

Create a shader

The steps for creating a shader are shown:

First, create an object as the shader container. This creation function will return the Container Handle.

Gluint glcreateshader (glenum shadertype); parameter: · shadertype-gl_vertex_shader or gl_fragment_shader.

You can create many shader, but remember that all vertex shader can only have one main function, and the shader of all pixels is the same.

Next, add the source code. The source code of the shader is a string array. The syntax is as follows:

Void glshadersource (gluint shader, int numofstrings, const char ** strings, int * lenofstrings); parameter: · 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.

Finally, compile the shader:

Void glcompileshader (gluint shader); parameter: • shader-the handler to the shader.

Create a program

Shows the steps to obtain a shader program that can be run:

First, create an object as the program container. This function returns the Container Handle.

GLuint glCreateProgram(void);

You can create any number of programs. During rendering, you can switch between different programs, or even return a fixed function pipeline at a frame. For example, you want to use the shader to draw a cup and then return to the fixed function to generate a cube environment map to display the background.

The shader compiled in the previous section will be appended to the created program. The method is as follows:

Void glattachshader (gluint program, gluint shader); parameter: · Program-the handler to the program. · shader-the handler to the shader you want to attach.

If there are vertex shader and segment shader at the same time, you need to append them to the program. You can append multiple shader of the same type (vertex or pixel) to a program, just as a C program can have multiple modules, but they can only have one main function.

You can also append a shader to multiple programs. For example, you want to use the same shader in different programs.

The last step is to connect the program. The method is as follows:

Void gllinkprogram (gluint program); parameter: · Program-the handler to the program.

After the connection operation, the source code of shader can be modified and re-compiled without affecting the entire program.

After the program is connected, you can call gluseprogram to use the program. Each program is assigned a handle. You can connect multiple programs for use in advance.

Void gluseprogram (gluint prog); parameter: · prog-the handler to the program you want to use, or zero to return to fixed functionality.

When a program is used, if it is connected again, it will be automatically replaced and put into use, so there is no need to call the above function again. If the parameter is 0, a fixed function pipeline is used.

Example

The following code contains all the steps described above. The parameters P, f, and V are global gluint variables.

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);}

The complete example of glut is as follows:

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

The complete example contains the shader code and text file reader.

 

Error Handling

Debugging shader is very difficult. There is no such thing as printf at present, although there may be development tools with debugging functions in the future.

The status of the compilation phase can be obtained using the following functions:

Void glgetshaderiv (gluint object, glenum type, int * PARAM); parameter: · 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.

The connection status can be obtained using the following functions:

Void glgetprogramiv (gluint object, glenum type, int * PARAM); parameter: · 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.

If an error occurs, you need to find more information from infolog. This log stores information about the last operation, such as warnings and errors during compilation and various problems that occur during connection. This log even tells you whether the hardware supports your shader. Unfortunately, infolog does not have a specification, so different drivers/hardware may generate different log information.

To obtain logs of a specific shader or program, you can use the following program:

Void glgetshaderinfolog (gluint object, int maxlen, int * Len, char * log); void glgetprograminfolog (gluint object, int maxlen, int * Len, char * log); parameter: · 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.

The glsl specification must be improved here: you must know the length of the received infolog. To find the exact value, use the following function:

Void glgetshaderiv (gluint object, glenum type, int * PARAM); void glgetprogramiv (gluint object, glenum type, int * PARAM); parameter: · 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.

The following functions can be used to print infolog content:

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);    }}

Clear

The preceding section describes how to append a shader to a program. The call here is to separate the shader from the program:

Void gldetachshader (gluint program, gluint shader); parameter: · Program-the Program to detach from. · shader-the shader to detach.

Note: Only the shader that has not been attached to any program can be deleted. The call to delete shader and program is as follows:

Void gldeleteshader (gluint ID); void gldeleteprogram (gluint ID); parameter: · ID-The handid of the shader or program to delete.

If a shader is attached to a program, the shader cannot be deleted and can only be marked as deleted. After the shader is separated from all programs, it will be finally deleted.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.