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

我的操作系統是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);   

//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