1 // sous mac 
  2 // g++ -I/usr/local/include/ -lglfw -lGLEW main2.cpp -framework OpenGL  -omain2 
  3 // ./main2
  4 
  5 // sous linux   
  6 // g++ -I/usr/local/include/ -I/public/ig/glm/ -c main2.cpp  -omain2.o
  7 // g++ -I/usr/local main2.o -lglfw  -lGLEW  -lGL  -omain2
  8 // ./main2
  9 
 10 // Inclut les en-têtes standards
 11 #include <stdio.h>
 12 #include <string>
 13 #include <vector>
 14 #include <iostream>
 15 #include <fstream>
 16 #include <algorithm>
 17 using namespace std;
 18 
 19 #include <stdlib.h>
 20 #include <string.h>
 21 
 22 #include <GL/glew.h>
 23 #include <GLFW/glfw3.h>
 24 #include <glm/glm.hpp>
 25 #ifdef __APPLE__
 26 #include <OpenGL/gl.h>
 27 #else
 28 #include <GL/gl.h>
 29 #endif
 30 using namespace glm;
 31 
 32 static const GLfloat g_vertex_buffer_data[] = {
 33    -0.8f, -0.8f, 0.0f,
 34    0.8f, -0.8f, 0.0f,
 35    -0.8f,  0.8f, 0.0f,
 36 
 37    0.8f, 0.8f, 0.0f,
 38    0.8f, -0.8f, 0.0f,
 39    -0.8f,  0.8f, 0.0f,
 40 
 41 };
 42 
 43 static const GLfloat g_vertex_color_data[] = {
 44    1.0f, 0.0f, 0.0f,
 45    0.0f, 1.0f, 0.0f,
 46    0.0f, 0.0f, 1.0f,
 47 
 48    1.0f, 0.0f, 0.0f,
 49    0.0f, 1.0f, 0.0f,
 50    0.0f, 0.0f, 1.0f,
 51 };
 52 
 53 GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){
 54 
 55   // Create the shaders
 56   GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
 57   GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
 58 
 59   // Read the Vertex Shader code from the file
 60   std::string VertexShaderCode;
 61   std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
 62   if(VertexShaderStream.is_open()){
 63     std::string Line = "";
 64     while(getline(VertexShaderStream, Line))
 65       VertexShaderCode += "\n" + Line;
 66     VertexShaderStream.close();
 67   }else{
 68     printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
 69     getchar();
 70     return 0;
 71   }
 72 
 73   // Read the Fragment Shader code from the file
 74   std::string FragmentShaderCode;
 75   std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
 76   if(FragmentShaderStream.is_open()){
 77     std::string Line = "";
 78     while(getline(FragmentShaderStream, Line))
 79       FragmentShaderCode += "\n" + Line;
 80     FragmentShaderStream.close();
 81   }
 82 
 83   GLint Result = GL_FALSE;
 84   int InfoLogLength;
 85 
 86 
 87   // Compile Vertex Shader
 88   printf("Compiling shader : %s\n", vertex_file_path);
 89   char const * VertexSourcePointer = VertexShaderCode.c_str();
 90   glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
 91   glCompileShader(VertexShaderID);
 92 
 93   // Check Vertex Shader
 94   glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
 95   glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
 96   if ( InfoLogLength > 0 ){
 97     std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
 98     glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
 99     printf("%s\n", &VertexShaderErrorMessage[0]);
100   }
101 
102 
103 
104   // Compile Fragment Shader
105   printf("Compiling shader : %s\n", fragment_file_path);
106   char const * FragmentSourcePointer = FragmentShaderCode.c_str();
107   glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
108   glCompileShader(FragmentShaderID);
109 
110   // Check Fragment Shader
111   glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
112   glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
113   if ( InfoLogLength > 0 ){
114     std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
115     glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
116     printf("%s\n", &FragmentShaderErrorMessage[0]);
117   }
118 
119 
120 
121   // Link the program
122   printf("Linking program\n");
123   GLuint ProgramID = glCreateProgram();
124   glAttachShader(ProgramID, VertexShaderID);
125   glAttachShader(ProgramID, FragmentShaderID);
126   glLinkProgram(ProgramID);
127 
128   // Check the program
129   glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
130   glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
131   if ( InfoLogLength > 0 ){
132     std::vector<char> ProgramErrorMessage(InfoLogLength+1);
133     glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
134     printf("%s\n", &ProgramErrorMessage[0]);
135   }
136 
137   
138   glDetachShader(ProgramID, VertexShaderID);
139   glDetachShader(ProgramID, FragmentShaderID);
140   
141   glDeleteShader(VertexShaderID);
142   glDeleteShader(FragmentShaderID);
143 
144   return ProgramID;
145 }
146 
147 
148 
149 int main(){
150     // Initialise GLFW
151   if( !glfwInit() )
152   {
153       fprintf( stderr, "Failed to initialize GLFW\n" );
154       return -1;
155   }
156 
157   glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
158   glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // On veut OpenGL 3.3
159   glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
160   glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Pour rendre MacOS heureux ; ne devrait pas être nécessaire
161   glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // On ne veut pas l'ancien OpenGL
162 
163   // Ouvre une fenêtre et crée son contexte OpenGl
164   GLFWwindow* window; // (Dans le code source qui accompagne, cette variable est globale)
165   window = glfwCreateWindow( 1024, 768, "Main 02", NULL, NULL);
166   if( window == NULL ){
167       fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
168       glfwTerminate();
169       return -1;
170   }
171 
172   glfwMakeContextCurrent(window); // Initialise GLEW
173   glewExperimental=true; // Nécessaire dans le profil de base
174   if (glewInit() != GLEW_OK) {
175       fprintf(stderr, "Failed to initialize GLEW\n");
176       return -1;
177   }
178 
179   // modern OpenGL do not have a default VAO anymore. Even if we don't want to use it
180   // we have a create and bind one before playing with buffers ! 
181   GLuint VertexArrayID;
182   glGenVertexArrays(1, &VertexArrayID);
183   glBindVertexArray(VertexArrayID);
184 
185   // This will identify our vertex buffer
186   GLuint vertexbuffer;
187   // Generate 1 buffer, put the resulting identifier in vertexbuffer
188   glGenBuffers(1, &vertexbuffer);
189 
190   // The following commands will talk about our 'vertexbuffer' buffer
191   glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
192 
193     // Only allocate memory. Do not send yet our vertices to OpenGL.
194     glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data)+sizeof(g_vertex_color_data), 0, GL_STATIC_DRAW);
195 
196       // send vertices in the first part of the buffer
197     glBufferSubData(GL_ARRAY_BUFFER, 0,                            sizeof(g_vertex_buffer_data), g_vertex_buffer_data);
198 
199     // send colors in the second part of the buffer
200     glBufferSubData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), sizeof(g_vertex_color_data), g_vertex_color_data);
201   
202   glBindBuffer(GL_ARRAY_BUFFER, 0);
203 
204 
205   // Assure que l'on peut capturer la touche d'échappement enfoncée ci-dessous
206   glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
207 
208   GLuint programID = LoadShaders( "SimpleVertexShader2.vertexshader", "SimpleFragmentShader2.fragmentshader" );
209 
210   do{
211         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
212 
213         // Use our shader
214     glUseProgram(programID); 
215 
216       // 1rst attribute buffer : vertices
217     glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
218     glVertexAttribPointer(
219        0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
220        3,                  // size
221        GL_FLOAT,           // type
222        GL_FALSE,           // normalized?
223        0,                  // stride
224        (void*)0            // array buffer offset
225     );
226     glEnableVertexAttribArray(0);
227 
228         glVertexAttribPointer(
229           1, 
230           3, 
231           GL_FLOAT, 
232           GL_FALSE, 
233           0, 
234           (void*)sizeof(g_vertex_buffer_data));
235     glEnableVertexAttribArray(1);
236 
237         // Draw the triangles !
238     glDrawArrays(GL_TRIANGLES, 0, sizeof(g_vertex_buffer_data)/(3*sizeof(float))); // Starting from vertex 0; 6 vertices total -> 2 triangles
239     glDisableVertexAttribArray(0);
240     glDisableVertexAttribArray(1);
241 
242       // Swap buffers
243       glfwSwapBuffers(window);
244       glfwPollEvents();
245 
246   } // Vérifie si on a appuyé sur la touche échap (ESC) ou si la fenêtre a été fermée
247   while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
248   glfwWindowShouldClose(window) == 0 );
249 }