Created
January 23, 2012 15:11
-
-
Save ambethia/1663601 to your computer and use it in GitHub Desktop.
Chapter 2 from http://duriansoftware.com/joe ported from GLUT to GLFW
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <GL/glew.h> | |
| #include <GL/glfw.h> | |
| #include <math.h> | |
| #include <stdlib.h> | |
| #include <stdio.h> | |
| #include "util.h" | |
| static struct | |
| { | |
| GLuint vertex_buffer, element_buffer; | |
| GLuint textures[2]; | |
| GLuint vertex_shader, fragment_shader, program; | |
| struct | |
| { | |
| GLint fade_factor; | |
| GLint textures[2]; | |
| } uniforms; | |
| struct | |
| { | |
| GLint position; | |
| } attributes; | |
| GLfloat fade_factor; | |
| } g_resources; | |
| static const GLfloat g_vertex_buffer_data[] = { | |
| -1.0f, -1.0f, | |
| 1.0f, -1.0f, | |
| -1.0f, 1.0f, | |
| 1.0f, 1.0f | |
| }; | |
| static const GLushort g_element_buffer_data[] = { 0, 1, 2, 3 }; | |
| static int make_resources(void) | |
| { | |
| g_resources.vertex_buffer = make_buffer( | |
| GL_ARRAY_BUFFER, | |
| g_vertex_buffer_data, | |
| sizeof(g_vertex_buffer_data) | |
| ); | |
| g_resources.element_buffer = make_buffer( | |
| GL_ELEMENT_ARRAY_BUFFER, | |
| g_element_buffer_data, | |
| sizeof(g_element_buffer_data) | |
| ); | |
| g_resources.textures[0] = make_texture("hello1.tga"); | |
| g_resources.textures[1] = make_texture("hello2.tga"); | |
| if (g_resources.textures[0] == 0 || g_resources.textures[1] == 0) | |
| return 0; | |
| g_resources.vertex_shader = make_shader( | |
| GL_VERTEX_SHADER, | |
| "hello-gl.v.glsl" | |
| ); | |
| if (g_resources.vertex_shader == 0) | |
| return 0; | |
| g_resources.fragment_shader = make_shader( | |
| GL_FRAGMENT_SHADER, | |
| "hello-gl.f.glsl" | |
| ); | |
| if (g_resources.fragment_shader == 0) | |
| return 0; | |
| g_resources.program = make_program(2, | |
| g_resources.vertex_shader, | |
| g_resources.fragment_shader | |
| ); | |
| if (g_resources.program == 0) | |
| return 0; | |
| g_resources.uniforms.fade_factor | |
| = glGetUniformLocation(g_resources.program, "fade_factor"); | |
| g_resources.uniforms.textures[0] | |
| = glGetUniformLocation(g_resources.program, "textures[0]"); | |
| g_resources.uniforms.textures[1] | |
| = glGetUniformLocation(g_resources.program, "textures[1]"); | |
| g_resources.attributes.position | |
| = glGetAttribLocation(g_resources.program, "position"); | |
| return 1; | |
| } | |
| static void render(void) | |
| { | |
| glUseProgram(g_resources.program); | |
| glUniform1f(g_resources.uniforms.fade_factor, g_resources.fade_factor); | |
| glActiveTexture(GL_TEXTURE0); | |
| glBindTexture(GL_TEXTURE_2D, g_resources.textures[0]); | |
| glUniform1i(g_resources.uniforms.textures[0], 0); | |
| glActiveTexture(GL_TEXTURE1); | |
| glBindTexture(GL_TEXTURE_2D, g_resources.textures[1]); | |
| glUniform1i(g_resources.uniforms.textures[1], 1); | |
| glBindBuffer(GL_ARRAY_BUFFER, g_resources.vertex_buffer); | |
| glVertexAttribPointer( | |
| g_resources.attributes.position, /* attribute */ | |
| 2, /* size */ | |
| GL_FLOAT, /* type */ | |
| GL_FALSE, /* normalized? */ | |
| sizeof(GLfloat)*2, /* stride */ | |
| (void*)0 /* array buffer offset */ | |
| ); | |
| glEnableVertexAttribArray(g_resources.attributes.position); | |
| glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_resources.element_buffer); | |
| glDrawElements( | |
| GL_TRIANGLE_STRIP, /* mode */ | |
| 4, /* count */ | |
| GL_UNSIGNED_SHORT, /* type */ | |
| (void*)0 /* element array buffer offset */ | |
| ); | |
| glDisableVertexAttribArray(g_resources.attributes.position); | |
| glfwSwapBuffers(); | |
| } | |
| int main (int argc, char const *argv[]) | |
| { | |
| int running = GL_TRUE; | |
| if (!glfwInit()) | |
| exit(EXIT_FAILURE); | |
| // Open an OpenGL window | |
| if(!glfwOpenWindow(400, 300, 0, 0, 0, 0, 0, 0, GLFW_WINDOW)) | |
| { | |
| glfwTerminate(); | |
| exit(EXIT_FAILURE); | |
| } | |
| glfwSetWindowTitle( "Hello, World!" ); | |
| glewInit(); | |
| if (!GLEW_VERSION_2_0) | |
| { | |
| fprintf(stderr, "OpenGL 2.0 not available\n"); | |
| return 1; | |
| } | |
| if (!make_resources()) | |
| { | |
| fprintf(stderr, "Failed to load resources\n"); | |
| exit(EXIT_FAILURE); | |
| } | |
| double last_update, this_update; | |
| double delta = 0; | |
| last_update = glfwGetTime(); | |
| g_resources.fade_factor = 0; | |
| // Main loop | |
| while (running) | |
| { | |
| this_update = glfwGetTime(); | |
| delta = this_update - last_update; | |
| if(delta >= 0.02) | |
| { | |
| last_update = this_update; | |
| g_resources.fade_factor = sinf((float)this_update * 1.0f) * 0.5f + 0.5f; | |
| printf("%f\n", g_resources.fade_factor); | |
| render(); | |
| } | |
| // Check if ESC key was pressed or window was closed | |
| running = !glfwGetKey(GLFW_KEY_ESC) && | |
| glfwGetWindowParam(GLFW_OPENED); | |
| } | |
| glfwTerminate(); | |
| exit(EXIT_SUCCESS); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <GL/glew.h> | |
| #include <GL/glfw.h> | |
| #include <math.h> | |
| #include <stdarg.h> | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| void *file_contents(const char *filename, GLint *length) | |
| { | |
| FILE *f = fopen(filename, "r"); | |
| void *buffer; | |
| if (!f) { | |
| fprintf(stderr, "Unable to open %s for reading\n", filename); | |
| return NULL; | |
| } | |
| fseek(f, 0, SEEK_END); | |
| *length = ftell(f); | |
| fseek(f, 0, SEEK_SET); | |
| buffer = malloc(*length+1); | |
| *length = fread(buffer, 1, *length, f); | |
| fclose(f); | |
| ((char*)buffer)[*length] = '\0'; | |
| return buffer; | |
| } | |
| void show_info_log( | |
| GLuint object, | |
| PFNGLGETSHADERIVPROC glGet__iv, | |
| PFNGLGETSHADERINFOLOGPROC glGet__InfoLog | |
| ) | |
| { | |
| GLint log_length; | |
| char *log; | |
| glGet__iv(object, GL_INFO_LOG_LENGTH, &log_length); | |
| log = malloc(log_length); | |
| glGet__InfoLog(object, log_length, NULL, log); | |
| fprintf(stderr, "%s", log); | |
| free(log); | |
| } | |
| GLuint make_buffer(GLenum target, const void *data, GLsizei size) | |
| { | |
| GLuint buffer; | |
| glGenBuffers(1, &buffer); | |
| glBindBuffer(target, buffer); | |
| glBufferData(target, size, data, GL_STATIC_DRAW); | |
| return buffer; | |
| } | |
| GLuint make_texture(const char *filename) | |
| { | |
| GLuint texture; | |
| glGenTextures(1, &texture); | |
| glBindTexture(GL_TEXTURE_2D, texture); | |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| glfwLoadTexture2D(filename, GLFW_BUILD_MIPMAPS_BIT); | |
| return texture; | |
| } | |
| GLuint make_shader(GLenum type, const char *filename) | |
| { | |
| GLint length; | |
| GLchar *source = file_contents(filename, &length); | |
| GLuint shader; | |
| GLint shader_ok; | |
| if (!source) | |
| return 0; | |
| shader = glCreateShader(type); | |
| glShaderSource(shader, 1, (const GLchar**)&source, &length); | |
| free(source); | |
| glCompileShader(shader); | |
| glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok); | |
| if (!shader_ok) { | |
| fprintf(stderr, "Failed to compile %s:\n", filename); | |
| show_info_log(shader, glGetShaderiv, glGetShaderInfoLog); | |
| glDeleteShader(shader); | |
| return 0; | |
| } | |
| return shader; | |
| } | |
| // make_program(1, shader) | |
| // make_program(2, shader1, shader2) | |
| GLuint make_program(int n, ...) | |
| { | |
| GLint program_ok; | |
| GLuint program = glCreateProgram(); | |
| va_list argp; | |
| va_start(argp, n); | |
| for (; n; n--) | |
| glAttachShader(program, va_arg(argp, GLuint)); | |
| va_end(argp); | |
| glLinkProgram(program); | |
| glGetProgramiv(program, GL_LINK_STATUS, &program_ok); | |
| if (!program_ok) { | |
| fprintf(stderr, "Failed to link shader program:\n"); | |
| show_info_log(program, glGetProgramiv, glGetProgramInfoLog); | |
| glDeleteProgram(program); | |
| return 0; | |
| } | |
| return program; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| void *file_contents(const char *filename, GLint *length); | |
| void show_info_log( | |
| GLuint object, | |
| PFNGLGETSHADERIVPROC glGet__iv, | |
| PFNGLGETSHADERINFOLOGPROC glGet__InfoLog | |
| ); | |
| GLuint make_buffer(GLenum target, const void *data, GLsizei size); | |
| GLuint make_texture(const char *filename); | |
| GLuint make_shader(GLenum type, const char *filename); | |
| GLuint make_program(int n, ...); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment