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