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 }