**************************************** **************************************** *********************************
This is a tutorial from lightthouse3d. The poor translation here is to help you better understand the situation. If you accidentally see it, please correct the error. This is not a sentence-by-sentence translation. The translator only tries to replace the original sentence with statements that are easier to understand.**************************************** **************************************** ***************************
Glsl Tutorial example
Helloworld in glsl
This is the helloworld of glsl (Note: I still remember that when we first learned programming, many first-class examples were named helloworld). A minimum coloring tool is used to complete the most basic tasks: vertices are converted and rendered with a single color. Here we will introduce vertices and cell pasters.
Vertex shader
The Vertex coloring tool is used to convert vertices. The following shows how to perform vertex conversion through fixed pipeline equations, in the fixed pipeline state, the vertex transformation uses the Model View matrix and projection matrix to convert through the following equations.
Vtrans = projection * modelview * incomingvertex
To perform such conversions in glsl, you must access the OpenGL State to obtain the two matrices. As mentioned above, some OpenGL states can be easily obtained in glsl, for example, the two matrices mentioned above are declared through the predefined uniform type variables, as follows:
Uniform mat4 gl_modelviewmatrix;
Uniform mat4 gl_projectionmatrix;
Another thing that must be done: access the vertex of the input. These vertices are passed to the vertex coloring machine one by one through predefined attribute variables:
Attribute vec4 gl_vertex;
To output converted vertices, the shader also defines the pre-defined variable gl_position of vec4.
Based on the above, we can write a simple shader. Nothing except the conversion vertex is done, which means that no other function is done, such as illumination computing.
The vertex shader code is as follows:
Void main ()
{
Gl_position = gl_projectionmatrix * gl_modelviewmatrix * gl_vertex;
}
In the code above, it is a waste to multiply the projection matrix of each vertex by the model view matrix, because these matrices do not change every vertex. glsl provides a derivative matrix calledGl_modelviewprojectionmatrixIs the result of the product of the above two matrices. Therefore, the code of the shader is changed:
Void main ()
{
Gl_position =Gl_modelviewprojectionmatrix* Gl_vertex;
}
The two results are the same. Can this be the same as a fixed pipeline? Theoretically. However, some vertices may be different in some special changes, for example, some graphics card high optimization operations and some special functions use vertex conversion, another reason may be limited data accuracy. When the computation is completed under different commands, different computation results may be obtained due to limited data accuracy. Therefore, glsl provides the same method as fixed functions:
Void main ()
{
Gl_position = ftransform ();
}
Chip coloring er
The Cell Coloring tool also has a predefined variable to represent the color:
Void main ()
{
Gl_fragcolor = vec4 (0.4, 0.4, 0.8, 1.0 );
}
Source code: opengl2.0
/
# Include <stdio. h>
# Include <stdlib. h>
# Include <Gl/glew. h>
# Include <Gl/glut. h>
# Include "textfile. H" // class for reading vertex and fragment coloring er code
Gluint V, F, F2, P;
Float LPOS [4] = {1, 0.5 };
Void changesize (int w, int h ){
// Prevent a divide by zero, when window is too short
// (You cant make a window of zero width ).
If (H = 0)
H = 1;
Float ratio = 1.0 * w/h;
// Reset the coordinate system before modifying
Glmatrixmode (gl_projection );
Glloadidentity ();
// Set the viewport to be the entire window
Glviewport (0, 0, W, H );
// Set the correct perspective.
Gluperspective (45, ratio, 1,1000 );
Glmatrixmode (gl_modelview );
}
Float a = 0;
Void renderscene (void ){
Glclear (gl_color_buffer_bit | gl_depth_buffer_bit );
Glloadidentity ();
Glulookat (0.0, 0.0, 5.0,
0.0, 0.0,-1.0,
0.0f, 1.0f, 0.0f );
Gllightfv (gl_light0, gl_position, LPOS );
Glrotatef (A, 0, 1 );
Fig (1 );
A ++ = 0.1;
Gluswapbuffers ();
}
Void processnormalkeys (unsigned char key, int X, int y ){
If (Key = 27)
Exit (0 );
}
# Define printopenglerror () printoglerror (_ file __, _ line __)
Int printoglerror (char * file, int line)
{
//
// Returns 1 if an OpenGL error occurred, 0 otherwise.
//
Glenum glerr;
Int retcode = 0;
Glerr = glgeterror ();
While (glerr! = Gl_no_error)
{
Printf ("glerror in file % s @ line % d: % s/n", file, line, gluerrorstring (glerr ));
Retcode = 1;
Glerr = glgeterror ();
}
Return retcode;
}
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 );
}
}
Void setshaders (){
Char * Vs = NULL, * FS = NULL, * fs2 = NULL;
V = glcreateshader (gl_vertex_shader );
F = glcreateshader (gl_fragment_shader );
F2 = glcreateshader (gl_fragment_shader );
Vs = textfileread ("minimal. vert ");
FS = textfileread ("minimal. Frag ");
Const char * VV =;
Const char * FF = FS;
Glshadersource (V, 1, & VV, null );
Glshadersource (F, 1, & ff, null );
Free (VS); free (FS );
Glcompileshader (v );
Glcompileshader (f );
Printshaderinfolog (v );
Printshaderinfolog (f );
Printshaderinfolog (F2 );
P = glcreateprogram ();
Glattachshader (p, V );
Glattachshader (p, F );
Gllinkprogram (P );
Printprograminfolog (P );
Gluseprogram (P );
}
Int main (INT argc, char ** argv ){
Gluinit (& argc, argv );
Fig );
Gluinitwindowposition (100,100 );
Gluinitwindowsize (320,320 );
Valley createwindow ("mm 2004-05 ");
Gludisplayfunc (renderscene );
Glutidlefunc (renderscene );
Glureshapefunc (changesize );
Glukeyboardfunc (processnormalkeys );
Glenable (gl_depth_test );
Glclearcolor (1.0, 1.0, 1.0, 1.0 );
Glable (gl_cull_face );
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 ();
Glumainloop ();
Return 0;
}