歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

OpenGL的GLSL編程初探

先發個截圖:當然看到這個界面大家肯定覺得這不就是個三角形,這不是我想說的,重點在後邊。

先附上代碼,首先是main.cpp文件:

  1. #include "GL\glew.h"  
  2. #include "GL\glut.h"  
  3. #include <gl\GL.h>  
  4. #include <gl\GLU.h>  
  5.  
  6. #include <Windows.h>  
  7. #include <stdio.h>  
  8.  
  9. GLuint program; 
  10.  
  11. GLint attribute_coord2d; 
  12.  
  13. char* file_read(const char* filename) 
  14. { 
  15.   FILE* input = fopen(filename, "rb"); 
  16.   if(input == NULL) return NULL; 
  17.    
  18.   if(fseek(input, 0, SEEK_END) == -1) return NULL; 
  19.   long size = ftell(input); 
  20.   if(size == -1) return NULL; 
  21.   if(fseek(input, 0, SEEK_SET) == -1) return NULL; 
  22.    
  23.   /*if using c-compiler: dont cast malloc's return value*/ 
  24.   char *content = (char*) malloc( (size_t) size +1  );   
  25.   if(content == NULL) return NULL; 
  26.    
  27.   fread(content, 1, (size_t)size, input); 
  28.   if(ferror(input)) { 
  29.     free(content); 
  30.     return NULL; 
  31.   } 
  32.    
  33.   fclose(input); 
  34.   content[size] = '\0'; 
  35.   return content; 
  36. } 
  37.  
  38. /** 
  39.  * Display compilation errors from the OpenGL shader compiler 
  40.  */ 
  41. void print_log(GLuint object) 
  42. { 
  43.   GLint log_length = 0; 
  44.   if (glIsShader(object)) 
  45.     glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length); 
  46.   else if (glIsProgram(object)) 
  47.     glGetProgramiv(object, GL_INFO_LOG_LENGTH, &log_length); 
  48.   else { 
  49.     fprintf(stderr, "printlog: Not a shader or a program\n"); 
  50.     return; 
  51.   } 
  52.    
  53.   char* log = (char*)malloc(log_length); 
  54.    
  55.   if (glIsShader(object)) 
  56.     glGetShaderInfoLog(object, log_length, NULL, log); 
  57.   else if (glIsProgram(object)) 
  58.     glGetProgramInfoLog(object, log_length, NULL, log); 
  59.    
  60.   fprintf(stderr, "%s", log); 
  61.   free(log); 
  62. } 
  63.  
  64. /** 
  65.  * Compile the shader from file 'filename', with error handling 
  66.  */ 
  67. GLuint create_shader(const char* filename, GLenum type) 
  68. { 
  69.   const GLchar* source = file_read(filename); 
  70.   if (source == NULL) { 
  71.     fprintf(stderr, "Error opening %s: ", filename); perror(""); 
  72.     return 0; 
  73.   } 
  74.   GLuint res = glCreateShader(type); 
  75.   const GLchar* sources[2] = { 
  76. #ifdef GL_ES_VERSION_2_0  
  77.     "#version 100\n" 
  78.     "#define GLES2\n", 
  79. #else  
  80.     "#version 120\n", 
  81. #endif  
  82.     source }; 
  83.   glShaderSource(res, 2, sources, NULL); 
  84.   free((void*)source); 
  85.    
  86.   glCompileShader(res); 
  87.   GLint compile_ok = GL_FALSE; 
  88.   glGetShaderiv(res, GL_COMPILE_STATUS, &compile_ok); 
  89.   if (compile_ok == GL_FALSE) { 
  90.     fprintf(stderr, "%s:", filename); 
  91.     print_log(res); 
  92.     glDeleteShader(res); 
  93.     return 0; 
  94.   } 
  95.    
  96.   return res; 
  97. } 
  98.  
  99.  
  100. int init_resources(void) 
  101. { 
  102.   /* FILLED IN LATER */ 
  103.     GLint compile_ok = GL_FALSE, link_ok = GL_FALSE; 
  104.    
  105.     GLuint vs, fs; 
  106.   if ((vs = create_shader("triangle.v.glsl", GL_VERTEX_SHADER))   == 0) return 0; 
  107.   if ((fs = create_shader("triangle.f.glsl", GL_FRAGMENT_SHADER)) == 0) return 0; 
  108.    program = glCreateProgram(); 
  109.   glAttachShader(program, vs); 
  110.   glAttachShader(program, fs); 
  111.   glLinkProgram(program); 
  112.   glGetProgramiv(program, GL_LINK_STATUS, &link_ok); 
  113.    if (!link_ok) { 
  114.     fprintf(stderr, "glLinkProgram:"); 
  115.     print_log(program); 
  116.    } 
  117.   return 0; 
  118. } 
  119.    
  120. void onDisplay() 
  121. { 
  122.   /* Clear the background as white */ 
  123.   glClearColor(1.0, 1.0, 1.0, 1.0); 
  124.   glClear(GL_COLOR_BUFFER_BIT); 
  125.    
  126.   glUseProgram(program); 
  127.   glEnableVertexAttribArray(attribute_coord2d); 
  128.   GLfloat triangle_vertices[] = { 
  129.      0.0,  0.8, 
  130.     -0.8, -0.8, 
  131.      0.8, -0.8, 
  132.   }; 
  133.   /* Describe our vertices array to OpenGL (it can't guess its format automatically) */ 
  134.   glVertexAttribPointer( 
  135.     attribute_coord2d, // attribute  
  136.     2,                 // number of elements per vertex, here (x,y)  
  137.     GL_FLOAT,          // the type of each element  
  138.     GL_FALSE,          // take our values as-is  
  139.     0,                 // no extra data between each position  
  140.     triangle_vertices  // pointer to the C array  
  141.   ); 
  142.    
  143.   /* Push each element in buffer_vertices to the vertex shader */ 
  144.   glDrawArrays(GL_TRIANGLES, 0, 3); 
  145.   glDisableVertexAttribArray(attribute_coord2d); 
  146.    
  147.   /* Display the result */ 
  148.   glutSwapBuffers(); 
  149. } 
  150.  
  151. void free_resources() 
  152. { 
  153.   glDeleteProgram(program); 
  154. } 
  155.    
  156. int main(int argc, char* argv[]) 
  157. { 
  158.     /* Glut-related initialising functions */ 
  159.     glutInit(&argc, argv); 
  160.     glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); 
  161.     glEnable(GL_BLEND); 
  162.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
  163.     glutInitWindowSize(640, 480); 
  164.     glutCreateWindow("My First Triangle"); 
  165.    
  166.  
  167.  
  168.     /* Extension wrangler initialising */ 
  169.     GLenum glew_status = glewInit(); 
  170.     if (glew_status != GLEW_OK) 
  171.     { 
  172.         fprintf(stderr, "Error: %s\n", glewGetErrorString(glew_status)); 
  173.         return EXIT_FAILURE; 
  174.     } 
  175.    
  176.     /* When all init functions runs without errors, 
  177.     the program can initialise the resources */ 
  178.     if (0 == init_resources()) 
  179.     { 
  180.         /* We can display it if everything goes OK */ 
  181.         glutDisplayFunc(onDisplay); 
  182.         glutMainLoop(); 
  183.     } 
  184.    
  185.     /* If the program exits in the usual way, 
  186.     free resources and exit with a success */ 
  187.     free_resources(); 
  188.     return EXIT_SUCCESS; 
  189. } 

我的操作系統是win7 x64位,采用了glew 和freeglut庫,這些庫可以從相應的網站上下載,這裡就不說了,主要看一個函數create_shader這個函數,裡面負責從文件中讀取GLSL的代碼,然後將其編譯,後面將其連接然後進行執行。將三個文件放在同一目錄下即可編譯通過,那些繁瑣的理論知識這裡就不廢話了。

接下來來看這兩個文件吧(triangle.v.glsl和triangle.f.glsl):

//triangle.v.glsl

  1. attribute vec2 coord2d;                   
  2. void main(void)   
  3. {                         
  4.     gl_Position = vec4(coord2d, 0.0, 1.0);   
  5. } 

//triangle.f.glsl

  1. void main(void)   
  2. {         
  3.     gl_FragColor[0] = gl_FragCoord.x/640.0; 
  4.     gl_FragColor[1] = gl_FragCoord.y/480.0; 
  5.     gl_FragColor[2] = 0.5; 
  6.     gl_FragColor[3] = floor(mod(gl_FragCoord.y, 2.0)); 
  7. }; 
Copyright © Linux教程網 All Rights Reserved