// // load a simple vertex shader + fragment shader pair from files // and compile+link it into a new shader program // returns handle to program GLuint link_programme_from_files (const char* vs_file_name, const char* fs_file_name) { char* vs_str = NULL; char* fs_str = NULL; GLuint vs, fs, sp; long vs_sz, fs_sz; int params = -1; // work out size of files vs_sz = get_file_size (vs_file_name); fs_sz = get_file_size (fs_file_name); if (!vs_sz || !fs_sz) { return 0; } vs_str = (char*)malloc (vs_sz + 1); // oddly had to do +1 sometimes fs_str = (char*)malloc (fs_sz + 1); // oddly had to do +1 sometimes // read files intro strings if (!parse_file_into_str (vs_file_name, vs_str)) { return 0; } if (!parse_file_into_str (fs_file_name, fs_str)) { return 0; } // create GPU shaders vs = glCreateShader (GL_VERTEX_SHADER); fs = glCreateShader (GL_FRAGMENT_SHADER); glShaderSource (vs, 1, (const char**)&vs_str, NULL); glShaderSource (fs, 1, (const char**)&fs_str, NULL); free (vs_str); free (fs_str); glCompileShader (vs); // check for compile errors glGetShaderiv (vs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: vertex shader %s did not compile\n", vs_file_name); print_shader_info_log (vs); return 0; // or exit or something } glCompileShader (fs); // check for compile errors glGetShaderiv (fs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: frag shader %s did not compile\n", fs_file_name); print_shader_info_log (fs); return 0; // or exit or something } sp = glCreateProgram (); glAttachShader (sp, vs); glAttachShader (sp, fs); glLinkProgram (sp); return sp; }
int init_shaders(Shader *shader, const char *vertex_shader_loc, const char *fragment_shader_loc) { int params = -1; int length; char vertex_shader_source[1024 * 256]; char fragment_shader_source[1024 * 256]; const GLchar *p; parse_file_into_str(vertex_shader_loc, vertex_shader_source, 1024 * 256); shader->vertexShader = glCreateShader(GL_VERTEX_SHADER); p = (const GLchar *)vertex_shader_source; glShaderSource(shader->vertexShader, 1, &p, NULL); glCompileShader(shader->vertexShader); glGetShaderiv(shader->vertexShader, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf(stderr, "ERROR: GL shader index %i did not compile\n", shader->vertexShader); print_shader_info_log(shader->vertexShader); return 1; } parse_file_into_str(fragment_shader_loc, fragment_shader_source, 1024 * 256); shader->fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); p = (const GLchar *)fragment_shader_source; glShaderSource(shader->fragmentShader, 1, &p, NULL); glCompileShader(shader->fragmentShader); glGetShaderiv(shader->fragmentShader, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf(stderr, "ERROR: GL shader index %i did not compile\n", shader->fragmentShader); print_shader_info_log(shader->fragmentShader); return 1; } shader->program = glCreateProgram(); glAttachShader(shader->program, shader->fragmentShader); glAttachShader(shader->program, shader->vertexShader); glLinkProgram(shader->program); glGetProgramiv(shader->program, GL_LINK_STATUS, ¶ms); if (GL_TRUE != params) { fprintf(stderr, "ERROR: could not link shader programme GL index %i\n",shader->program); print_program_info_log(shader->program); return 1; } shader->projection_matrix_location = glGetUniformLocation(shader->program, "projection"); shader->view_matrix_location = glGetUniformLocation(shader->program, "view"); return 0; }
bool check_shader_errors (GLuint shader) { GLint params = -1; glGetShaderiv (shader, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: shader %u did not compile\n", shader); print_shader_info_log (shader); return false; } return true; }
static inline GLuint compile_shader(GLenum type, const char *source, int len){ GLint status; GLuint shader = glCreateShader(type); #if (defined DEBUG) && !(defined NDEBUG) DEBUG_PRINTF("Compiling %s\n", shader_type_to_string(type)); #endif if(len == 0){ len = strlen(source); } glShaderSource(shader, 1, &source, &len); glCompileShader(shader); glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if(!status){ print_shader_info_log(shader, "Error when compiling shader.\n"); exit(EXIT_FAILURE); } //always print shader info when debbuing is enabled# #if (defined DEBUG) && !(defined NDEBUG) print_shader_info_log(shader, ""); #endif return shader; }
bool create_shader (const char* file_name, GLuint* shader, GLenum type) { gl_log ("creating shader from %s...\n", file_name); char shader_string[MAX_SHADER_LENGTH]; assert (parse_file_into_str (file_name, shader_string, MAX_SHADER_LENGTH)); *shader = glCreateShader (type); const GLchar* p = (const GLchar*)shader_string; glShaderSource (*shader, 1, &p, NULL); glCompileShader (*shader); // check for compile errors int params = -1; glGetShaderiv (*shader, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { gl_log_err ("ERROR: GL shader index %i did not compile\n", *shader); print_shader_info_log (*shader); return false; // or exit or something } gl_log ("shader compiled. index %i\n", *shader); return true; }
/*****************************************************************************\ * read_shader * \*****************************************************************************/ GLuint read_shader(const std::string &vertex_filename, const std::string &fragment_filename) { GLint status; std::string source; const char *cstring; GLuint program; if(access(vertex_filename.data(),F_OK) == -1) { std::cerr<<"Cannot load shader file "<<vertex_filename<<std::endl; std::cerr<<"Wrong path ?"<<std::endl; abort(); } if(access(fragment_filename.data(),F_OK) == -1) { std::cerr<<"Cannot load shader file "<<vertex_filename<<std::endl; std::cerr<<"Wrong path ?"<<std::endl; abort(); } program = glCreateProgram(); PRINT_OPENGL_ERROR(); // Create the vertex shader. if (vertex_filename != "") { GLuint handle = glCreateShader(GL_VERTEX_SHADER); PRINT_OPENGL_ERROR(); source = get_file_content(vertex_filename); cstring = source.c_str(); glShaderSource(handle, 1, &cstring, NULL); PRINT_OPENGL_ERROR(); // Compile the vertex shader, and print out the compiler log file. glCompileShader(handle); PRINT_OPENGL_ERROR(); glGetShaderiv(handle, GL_COMPILE_STATUS, &status); PRINT_OPENGL_ERROR(); print_shader_info_log(handle); glAttachShader(program, handle); PRINT_OPENGL_ERROR(); if (!status) return 0; } // Create the fragment shader if (fragment_filename != "") { GLuint handle = glCreateShader(GL_FRAGMENT_SHADER); PRINT_OPENGL_ERROR(); source = get_file_content(fragment_filename); cstring = source.c_str(); glShaderSource(handle, 1, &cstring, NULL); PRINT_OPENGL_ERROR(); // Compile the fragment shader, and print out the compiler log file. glCompileShader(handle); PRINT_OPENGL_ERROR(); glGetShaderiv(handle, GL_COMPILE_STATUS, &status); PRINT_OPENGL_ERROR(); print_shader_info_log(handle); glAttachShader(program, handle); PRINT_OPENGL_ERROR(); if (!status) return 0; } // Link the program object and print out the info log. glLinkProgram(program); PRINT_OPENGL_ERROR(); glGetProgramiv(program, GL_LINK_STATUS, &status); PRINT_OPENGL_ERROR(); print_program_info_log(program); if (!status) return 0; // Install program object as part of current state. glUseProgram(program); PRINT_OPENGL_ERROR(); return program; }
int main () { assert (restart_gl_log ()); // all the start-up code for GLFW and GLEW is called here assert (start_gl ()); // tell GL to only draw onto a pixel if the shape is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" /* OTHER STUFF GOES HERE NEXT */ GLfloat points[] = { 0.0f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, -0.5f, 0.0f }; GLfloat colours[] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; glm::mat4 mvp = glm::mat4(1.0f); GLuint points_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); // glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), points, GL_STATIC_DRAW); glBufferData (GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data) * sizeof (GLfloat), g_vertex_buffer_data, GL_STATIC_DRAW); /* create a second VBO, containing the array of colours. note that we could also put them both into a single vertex buffer. in this case we would use the pointer and stride parameters of glVertexAttribPointer() to describe the different data layouts */ GLuint colours_vbo; glGenBuffers (1, &colours_vbo); glBindBuffer (GL_ARRAY_BUFFER, colours_vbo); // glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), colours, GL_STATIC_DRAW); glBufferData (GL_ARRAY_BUFFER, sizeof(g_color_buffer_data) * sizeof (GLfloat), g_color_buffer_data, GL_STATIC_DRAW); /* create the VAO. we bind each VBO in turn, and call glVertexAttribPointer() to indicate where the memory should be fetched for vertex shader input variables 0, and 1, respectively. we also have to explicitly enable both 'attribute' variables. 'attribute' is the older name for vertex shader 'in' variables. */ GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glBindBuffer (GL_ARRAY_BUFFER, colours_vbo); glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); glEnableVertexAttribArray (1); char vertex_shader[1024 * 256]; char fragment_shader[1024 * 256]; assert (parse_file_into_str ("test_vs.glsl", vertex_shader, 1024 * 256)); assert (parse_file_into_str ("test_fs.glsl", fragment_shader, 1024 * 256)); GLuint vs = glCreateShader (GL_VERTEX_SHADER); const GLchar* p = (const GLchar*)vertex_shader; glShaderSource (vs, 1, &p, NULL); glCompileShader (vs); // check for compile errors int params = -1; glGetShaderiv (vs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: GL shader index %i did not compile\n", vs); print_shader_info_log (vs); return 1; // or exit or something } GLuint fs = glCreateShader (GL_FRAGMENT_SHADER); p = (const GLchar*)fragment_shader; glShaderSource (fs, 1, &p, NULL); glCompileShader (fs); // check for compile errors glGetShaderiv (fs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: GL shader index %i did not compile\n", fs); print_shader_info_log (fs); return 1; // or exit or something } GLuint shader_programme = glCreateProgram (); glAttachShader (shader_programme, fs); glAttachShader (shader_programme, vs); glBindAttribLocation(shader_programme, 0, "vertex_position"); glBindAttribLocation(shader_programme, 1, "vertex_colour"); glLinkProgram (shader_programme); glGetProgramiv (shader_programme, GL_LINK_STATUS, ¶ms); if (GL_TRUE != params) { fprintf ( stderr, "ERROR: could not link shader programme GL index %i\n", shader_programme ); print_programme_info_log (shader_programme); return false; } //pass uniform GLint u = glGetUniformLocation(shader_programme, "mvp"); assert (u > -1); glUniformMatrix4fv(u, 1, GL_FALSE, &mvp[0][0]); glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CW); // GL_CCW for counter clock-wise while (!glfwWindowShouldClose (g_window)) { _update_fps_counter (g_window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, g_gl_width, g_gl_height); glUseProgram (shader_programme); glBindVertexArray (vao); // draw points 0-3 from the currently bound VAO with current in-use shader glDrawArrays (GL_TRIANGLES, 0, 12* 3); // update other events like input handling glfwPollEvents (); if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (g_window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }
GLuint setup_shader_program(char * sourcefilename) { GLuint retval; GLuint frag_shader, shader_program; char *frag_source; GLchar ** frag_sourcep; frag_shader = glCreateShader(GL_FRAGMENT_SHADER); if (0 == frag_shader) { fprintf(stderr, "Error creating shader\n"); check_error("Error creating fragment shader"); retval = 0; /* error */ } else { /* read the source from sourcefilename into a string */ /* pointed to by frag_source. */ frag_source = textFileRead(sourcefilename); if (NULL == frag_source) { fprintf(stderr, "Error:no file to read the fragment shader from\n"); fprintf(stderr, " can't find file '%s'\n", sourcefilename); retval = 0; /* error */ } frag_sourcep = &frag_source; glShaderSource(frag_shader, 1, (const GLchar **)frag_sourcep,NULL); check_error("after glShaderSource"); /* compile the source we loaded into the fragment shader */ glCompileShader(frag_shader); check_error("after glCompileShader"); shader_program = glCreateProgram(); if (0 == shader_program) { fprintf(stderr, "Error creating shader program with glCreateProgram\n"); check_error("Error creating shader program"); retval = 0; /* error */ } else { glAttachShader(shader_program, frag_shader); check_error("after glAttachShader"); glLinkProgram(shader_program); check_error("after glAttachShader"); /* print out any link-stage warnings or errors */ print_shader_info_log(shader_program); /* make this program part of the opengl state */ glUseProgram(shader_program); check_error("after glUseProgram"); retval = shader_program; } } return(retval); }
int main () { restart_gl_log (); // all the GLFW and GLEW start-up code is moved to here in gl_utils.cpp start_gl (); // tell GL to only draw onto a pixel if the shape is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" /* OTHER STUFF GOES HERE NEXT */ GLfloat points[] = { 0.0f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, -0.5f, 0.0f }; GLfloat colours[] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; GLuint points_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), points, GL_STATIC_DRAW); GLuint colours_vbo; glGenBuffers (1, &colours_vbo); glBindBuffer (GL_ARRAY_BUFFER, colours_vbo); glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), colours, GL_STATIC_DRAW); GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glBindBuffer (GL_ARRAY_BUFFER, colours_vbo); glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); glEnableVertexAttribArray (1); char vertex_shader[1024 * 256]; char fragment_shader[1024 * 256]; parse_file_into_str ("test_vs.glsl", vertex_shader, 1024 * 256); parse_file_into_str ("test_fs.glsl", fragment_shader, 1024 * 256); GLuint vs = glCreateShader (GL_VERTEX_SHADER); const GLchar* p = (const GLchar*)vertex_shader; glShaderSource (vs, 1, &p, NULL); glCompileShader (vs); // check for compile errors int params = -1; glGetShaderiv (vs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: GL shader index %i did not compile\n", vs); print_shader_info_log (vs); return 1; // or exit or something } GLuint fs = glCreateShader (GL_FRAGMENT_SHADER); p = (const GLchar*)fragment_shader; glShaderSource (fs, 1, &p, NULL); glCompileShader (fs); // check for compile errors glGetShaderiv (fs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: GL shader index %i did not compile\n", fs); print_shader_info_log (fs); return 1; // or exit or something } GLuint shader_programme = glCreateProgram (); glAttachShader (shader_programme, fs); glAttachShader (shader_programme, vs); glLinkProgram (shader_programme); glGetProgramiv (shader_programme, GL_LINK_STATUS, ¶ms); if (GL_TRUE != params) { fprintf ( stderr, "ERROR: could not link shader programme GL index %i\n", shader_programme ); print_programme_info_log (shader_programme); return false; } GLfloat matrix[] = { 1.0f, 0.0f, 0.0f, 0.0f, // first column 0.0f, 1.0f, 0.0f, 0.0f, // second column 0.0f, 0.0f, 1.0f, 0.0f, // third column 0.5f, 0.0f, 0.0f, 1.0f // fourth column }; int matrix_location = glGetUniformLocation (shader_programme, "matrix"); glUseProgram (shader_programme); glUniformMatrix4fv (matrix_location, 1, GL_FALSE, matrix); glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CW); // GL_CCW for counter clock-wise float speed = 1.0f; // move at 1 unit per second float last_position = 0.0f; while (!glfwWindowShouldClose (g_window)) { // add a timer for doing animation static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; _update_fps_counter (g_window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, g_gl_width, g_gl_height); // // Note: this call is not necessary, but I like to do it anyway before any // time that I call glDrawArrays() so I never use the wrong shader programme glUseProgram (shader_programme); // update the matrix // - you could simplify this by just using sin(current_seconds) matrix[12] = elapsed_seconds * speed + last_position; last_position = matrix[12]; if (fabs (last_position) > 1.0) { speed = -speed; } // // Note: this call is related to the most recently 'used' shader programme glUniformMatrix4fv (matrix_location, 1, GL_FALSE, matrix); // // Note: this call is not necessary, but I like to do it anyway before any // time that I call glDrawArrays() so I never use the wrong vertex data glBindVertexArray (vao); // draw points 0-3 from the currently bound VAO with current in-use shader glDrawArrays (GL_TRIANGLES, 0, 3); // update other events like input handling glfwPollEvents (); if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (g_window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }
GLuint shaderSetup( const char *vert, const char *frag ) { GLchar *vsrc = NULL, *fsrc = NULL; GLuint vs, fs, prog; GLint flag; // Assume that everything will work shaderErrorCode = E_NO_ERROR; // Create the shader handles vs = glCreateShader( GL_VERTEX_SHADER ); fs = glCreateShader( GL_FRAGMENT_SHADER ); // Read in shader source vsrc = read_text_file( vert ); if( vsrc == NULL ) { fprintf( stderr, "Error reading vertex shader file %s\n", vert); shaderErrorCode = E_VS_LOAD; return( 0 ); } fsrc = read_text_file( frag ); if( fsrc == NULL ) { fprintf( stderr, "Error reading fragment shader file %s\n", frag); shaderErrorCode = E_FS_LOAD; #ifdef __cplusplus delete [] vsrc; #else free( vsrc ); #endif return( 0 ); } // Attach the source to the shaders glShaderSource( vs, 1, (const GLchar **) &vsrc, NULL ); glShaderSource( fs, 1, (const GLchar **) &fsrc, NULL ); // We're done with the source code now #ifdef __cplusplus delete [] vsrc; delete [] fsrc; #else free(vsrc); free(fsrc); #endif // Compile the shaders, and print any relevant message logs glCompileShader( vs ); glGetShaderiv( vs, GL_COMPILE_STATUS, &flag ); print_shader_info_log( vs ); if( flag == GL_FALSE ) { shaderErrorCode = E_VS_COMPILE; return( 0 ); } glCompileShader( fs ); glGetShaderiv( fs, GL_COMPILE_STATUS, &flag ); print_shader_info_log( fs ); if( flag == GL_FALSE ) { shaderErrorCode = E_FS_COMPILE; return( 0 ); } // Create the program and attach the shaders prog = glCreateProgram(); glAttachShader( prog, vs ); glAttachShader( prog, fs ); // Report any message log information print_program_info_log( prog ); // Link the program, and print any message log information glLinkProgram( prog ); glGetProgramiv( prog, GL_LINK_STATUS, &flag ); print_program_info_log( prog ); if( flag == GL_FALSE ) { shaderErrorCode = E_SHADER_LINK; return( 0 ); } return( prog ); }
int main () { assert (restart_gl_log ()); assert (start_gl ()); // tell GL to only draw onto a pixel if the shape is closer to the viewer glEnable (GL_DEPTH_TEST); // enable depth-testing glDepthFunc (GL_LESS); // depth-testing interprets a smaller value as "closer" glClearColor (0.2, 0.2, 0.2, 1.0); GLfloat points[] = { 0.0f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, -0.5f, 0.0f }; GLfloat colours[] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; GLuint points_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), points, GL_STATIC_DRAW); GLuint colours_vbo; glGenBuffers (1, &colours_vbo); glBindBuffer (GL_ARRAY_BUFFER, colours_vbo); glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), colours, GL_STATIC_DRAW); GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glBindBuffer (GL_ARRAY_BUFFER, colours_vbo); glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); glEnableVertexAttribArray (1); char vertex_shader[1024 * 256]; char geometry_shader[1024 * 256]; char fragment_shader[1024 * 256]; assert (parse_file_into_str ("test_vs.glsl", vertex_shader, 1024 * 256)); assert (parse_file_into_str ("test_gs.glsl", geometry_shader, 1024 * 256)); assert (parse_file_into_str ("test_fs.glsl", fragment_shader, 1024 * 256)); GLuint vs = glCreateShader (GL_VERTEX_SHADER); const GLchar* p = (const GLchar*)vertex_shader; glShaderSource (vs, 1, &p, NULL); glCompileShader (vs); // check for compile errors int params = -1; glGetShaderiv (vs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: GL shader index %i did not compile\n", vs); print_shader_info_log (vs); return 1; // or exit or something } // create geometry shader GLuint gs = glCreateShader (GL_GEOMETRY_SHADER); p = (const GLchar*)geometry_shader; glShaderSource (gs, 1, &p, NULL); glCompileShader (gs); // check for compile errors glGetShaderiv (gs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: GL shader index %i did not compile\n", gs); print_shader_info_log (gs); return 1; // or exit or something } GLuint fs = glCreateShader (GL_FRAGMENT_SHADER); p = (const GLchar*)fragment_shader; glShaderSource (fs, 1, &p, NULL); glCompileShader (fs); // check for compile errors glGetShaderiv (fs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: GL shader index %i did not compile\n", fs); print_shader_info_log (fs); return 1; // or exit or something } GLuint shader_programme = glCreateProgram (); glAttachShader (shader_programme, fs); // attach geometry shader too glAttachShader (shader_programme, gs); glAttachShader (shader_programme, vs); glLinkProgram (shader_programme); glGetProgramiv (shader_programme, GL_LINK_STATUS, ¶ms); if (GL_TRUE != params) { fprintf ( stderr, "ERROR: could not link shader programme GL index %i\n", shader_programme ); print_programme_info_log (shader_programme); return false; } assert (is_programme_valid (shader_programme)); glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CW); // GL_CCW for counter clock-wise while (!glfwWindowShouldClose (g_window)) { _update_fps_counter (g_window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, g_gl_width, g_gl_height); glUseProgram (shader_programme); glBindVertexArray (vao); // points drawing mode glDrawArrays (GL_POINTS, 0, 3); // update other events like input handling glfwPollEvents (); if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (g_window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }
int main () { assert (restart_gl_log ()); /*------------------------------start GL context------------------------------*/ assert (start_gl ()); /*------------------------------create geometry-------------------------------*/ GLfloat points[] = { 0.0f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, -0.5f, 0.0f }; GLfloat colours[] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; GLuint points_vbo; glGenBuffers (1, &points_vbo); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), points, GL_STATIC_DRAW); GLuint colours_vbo; glGenBuffers (1, &colours_vbo); glBindBuffer (GL_ARRAY_BUFFER, colours_vbo); glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), colours, GL_STATIC_DRAW); GLuint vao; glGenVertexArrays (1, &vao); glBindVertexArray (vao); glBindBuffer (GL_ARRAY_BUFFER, points_vbo); glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL); glBindBuffer (GL_ARRAY_BUFFER, colours_vbo); glVertexAttribPointer (1, 3, GL_FLOAT, GL_FALSE, 0, NULL); glEnableVertexAttribArray (0); glEnableVertexAttribArray (1); /*------------------------------create shaders--------------------------------*/ char vertex_shader[1024 * 256]; char fragment_shader[1024 * 256]; assert (parse_file_into_str ("Shaders/test_vs.glsl", vertex_shader, 1024 * 256)); assert (parse_file_into_str ("Shaders/test_fs.glsl", fragment_shader, 1024 * 256)); GLuint vs = glCreateShader (GL_VERTEX_SHADER); const GLchar* p = (const GLchar*)vertex_shader; glShaderSource (vs, 1, &p, NULL); glCompileShader (vs); // check for compile errors int params = -1; glGetShaderiv (vs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: GL shader index %i did not compile\n", vs); print_shader_info_log (vs); return 1; // or exit or something } GLuint fs = glCreateShader (GL_FRAGMENT_SHADER); p = (const GLchar*)fragment_shader; glShaderSource (fs, 1, &p, NULL); glCompileShader (fs); // check for compile errors glGetShaderiv (fs, GL_COMPILE_STATUS, ¶ms); if (GL_TRUE != params) { fprintf (stderr, "ERROR: GL shader index %i did not compile\n", fs); print_shader_info_log (fs); return 1; // or exit or something } GLuint shader_programme = glCreateProgram (); glAttachShader (shader_programme, fs); glAttachShader (shader_programme, vs); glLinkProgram (shader_programme); glGetProgramiv (shader_programme, GL_LINK_STATUS, ¶ms); if (GL_TRUE != params) { fprintf ( stderr, "ERROR: could not link shader programme GL index %i\n", shader_programme ); print_programme_info_log (shader_programme); return false; } /*--------------------------create camera matrices----------------------------*/ /* create PROJECTION MATRIX */ #define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444 // input variables float near = 0.1f; // clipping plane float far = 100.0f; // clipping plane float fov = 67.0f * ONE_DEG_IN_RAD; // convert 67 degrees to radians float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio // matrix components float range = tan (fov * 0.5f) * near; float Sx = (2.0f * near) / (range * aspect + range * aspect); float Sy = near / range; float Sz = -(far + near) / (far - near); float Pz = -(2.0f * far * near) / (far - near); GLfloat proj_mat[] = { Sx, 0.0f, 0.0f, 0.0f, 0.0f, Sy, 0.0f, 0.0f, 0.0f, 0.0f, Sz, -1.0f, 0.0f, 0.0f, Pz, 0.0f }; /* create VIEW MATRIX */ float cam_speed = 1.0f; // 1 unit per second float cam_yaw_speed = 10.0f; // 10 degrees per second float cam_pos[] = {0.0f, 0.0f, 2.0f}; // don't start at zero, or we will be too close float cam_yaw = 0.0f; // y-rotation in degrees mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); mat4 view_mat = R * T; /* get location numbers of matrices in shader programme */ GLint view_mat_location = glGetUniformLocation (shader_programme, "view"); GLint proj_mat_location = glGetUniformLocation (shader_programme, "proj"); /* use program (make current in state machine) and set default matrix values*/ glUseProgram (shader_programme); glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); glUniformMatrix4fv (proj_mat_location, 1, GL_FALSE, proj_mat); /*------------------------------rendering loop--------------------------------*/ /* some rendering defaults */ glEnable (GL_CULL_FACE); // cull face glCullFace (GL_BACK); // cull back face glFrontFace (GL_CW); // GL_CCW for counter clock-wise while (!glfwWindowShouldClose (g_window)) { static double previous_seconds = glfwGetTime (); double current_seconds = glfwGetTime (); double elapsed_seconds = current_seconds - previous_seconds; previous_seconds = current_seconds; _update_fps_counter (g_window); // wipe the drawing surface clear glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport (0, 0, g_gl_width, g_gl_height); glUseProgram (shader_programme); glBindVertexArray (vao); // draw points 0-3 from the currently bound VAO with current in-use shader glDrawArrays (GL_TRIANGLES, 0, 3); // update other events like input handling glfwPollEvents (); /*-----------------------------move camera here-------------------------------*/ // control keys bool cam_moved = false; if (glfwGetKey (g_window, GLFW_KEY_A)) { cam_pos[0] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_D)) { cam_pos[0] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_UP)) { cam_pos[1] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_PAGE_DOWN)) { cam_pos[1] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_W)) { cam_pos[2] -= cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_S)) { cam_pos[2] += cam_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_LEFT)) { cam_yaw += cam_yaw_speed * elapsed_seconds; cam_moved = true; } if (glfwGetKey (g_window, GLFW_KEY_RIGHT)) { cam_yaw -= cam_yaw_speed * elapsed_seconds; cam_moved = true; } /* update view matrix */ if (cam_moved) { mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); // cam translation mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); // mat4 view_mat = R * T; glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m); } if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) { glfwSetWindowShouldClose (g_window, 1); } // put the stuff we've been drawing onto the display glfwSwapBuffers (g_window); } // close GL context and any other GLFW resources glfwTerminate(); return 0; }