int main(void) { GLint shader_program; GLint transform_location; GLuint vbo; GLuint vao; GLFWwindow* window; double time; glfwInit(); window = glfwCreateWindow(WIDTH, HEIGHT, __FILE__, NULL, NULL); glfwMakeContextCurrent(window); glewExperimental = GL_TRUE; glewInit(); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glViewport(0, 0, WIDTH, HEIGHT); shader_program = common_get_shader_program(vertex_shader_source, fragment_shader_source); glGenVertexArrays(1, &vao); glGenBuffers(1, &vbo); glBindVertexArray(vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); /* Position attribute */ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); /* Color attribute */ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glBindVertexArray(0); while (!glfwWindowShouldClose(window)) { glfwPollEvents(); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shader_program); transform_location = glGetUniformLocation(shader_program, "transform"); /* To do serious things, we'd need a math library like glm here. */ GLfloat transform[] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, }; time = glfwGetTime(); transform[0] = 2.0f * sin(time); transform[5] = 2.0f * cos(time); glUniformMatrix4fv(transform_location, 1, GL_FALSE, transform); glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, 3); glBindVertexArray(0); glfwSwapBuffers(window); } glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); glfwTerminate(); return EXIT_SUCCESS; }
int main(void) { GLuint shader_program, vbo; GLint pos; GLFWwindow* window; glfwInit(); glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); window = glfwCreateWindow(WIDTH, HEIGHT, __FILE__, NULL, NULL); glfwMakeContextCurrent(window); printf("GL_VERSION : %s\n", glGetString(GL_VERSION) ); printf("GL_RENDERER : %s\n", glGetString(GL_RENDERER) ); shader_program = common_get_shader_program(vertex_shader_source, fragment_shader_source); pos = glGetAttribLocation(shader_program, "position"); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glViewport(0, 0, WIDTH, HEIGHT); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); glEnableVertexAttribArray(pos); glBindBuffer(GL_ARRAY_BUFFER, 0); while (!glfwWindowShouldClose(window)) { glfwPollEvents(); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shader_program); glDrawArrays(GL_TRIANGLES, 0, 3); glfwSwapBuffers(window); } glDeleteBuffers(1, &vbo); glfwTerminate(); return EXIT_SUCCESS; }
int main(void) { /* SDL variables. */ SDL_Event event; SDL_Window *window; SDL_GLContext gl_context; const unsigned int WINDOW_WIDTH = 500, WINDOW_HEIGHT = WINDOW_WIDTH; double dt, initial_time; /* OpenGL variables. */ GLint attribute_coord2d, ibo_size, width_location, height_location, time_location, periods_x_location, periods_y_location, pi2_location, program ; GLuint ibo, vbo; const char *attribute_name = "coord2d"; const float periods_x = 10.0, periods_y = 10.0, pi2 = 2.0 * acos(-1.0) ; /* SDL init. */ SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO); window = SDL_CreateWindow(__FILE__, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_OPENGL); gl_context = SDL_GL_CreateContext(window); glewInit(); /* OpenGL init. */ { program = common_get_shader_program(vertex_shader_source, fragment_shader_source); attribute_coord2d = glGetAttribLocation(program, attribute_name); if (attribute_coord2d == -1) { fprintf(stderr, "error: attribute_coord2d: %s\n", attribute_name); return EXIT_FAILURE; } height_location = glGetUniformLocation(program, "height"); periods_x_location = glGetUniformLocation(program, "periods_x"); periods_y_location = glGetUniformLocation(program, "periods_y"); pi2_location = glGetUniformLocation(program, "pi2"); time_location = glGetUniformLocation(program, "time"); width_location = glGetUniformLocation(program, "width"); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glUseProgram(program); glViewport(0, 0, WIDTH, HEIGHT); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glGenBuffers(1, &ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexes), indexes, GL_STATIC_DRAW); glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &ibo_size); glUniform1f(pi2_location, pi2); glUniform1f(width_location, WIDTH); glUniform1f(height_location, HEIGHT); glUniform1f(periods_x_location, periods_x); glUniform1f(periods_y_location, periods_y); } initial_time = common_get_secs(); common_fps_init(); while (1) { dt = common_get_secs() - initial_time; /* OpenGL draw. */ glClear(GL_COLOR_BUFFER_BIT); glEnableVertexAttribArray(attribute_coord2d); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glUniform1f(time_location, dt); glDrawElements(GL_TRIANGLES, ibo_size / sizeof(indexes[0]), GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(attribute_coord2d); common_fps_update_and_print(); SDL_GL_SwapWindow(window); if (SDL_PollEvent(&event) && event.type == SDL_QUIT) break; } /* OpenGL cleanup. */ glDeleteBuffers(1, &ibo); glDeleteBuffers(1, &vbo); glDeleteProgram(program); /* SDL cleanup. */ SDL_GL_DeleteContext(gl_context); SDL_DestroyWindow(window); SDL_Quit(); return EXIT_SUCCESS; }
int main(int argc, char **argv) { GLFWwindow *window; GLfloat *temperatures = NULL, *temperatures2 = NULL, *temperature_buf = NULL ; GLint coord2d_location, textureSampler_location, vertexUv_location, width_location ; GLuint compute_program, ebo, height, window_height, program, ssbo, texture, width, window_width, work_group_width, vao, vbo ; char *compute_shader_source, *work_group_width_str; double cursor_pos_x = 0.0, cursor_pos_y = 0.0, window_grid_ratio_x = 0.0, window_grid_ratio_y = 0.0 ; int cpu, step = 0, which_boundary; float conduction_coeff; size_t n_temperatures, square_x, square_y, square_width, square_height ; unsigned int steps_per_frame, window_x; /* CLI arguments. */ if (argc > 1) { width = strtol(argv[1], NULL, 10); } else { width = WIDTH; } height = width; if (argc > 2) { window_width = strtol(argv[2], NULL, 10); } else { window_width = WINDOW_WIDTH; } window_height = window_width; if (argc > 3) { work_group_width = strtol(argv[3], NULL, 10); } else { work_group_width = WORK_GROUP_WIDTH; } if (argc > 4) { cpu = (argv[4][0] == '1'); } else { cpu = 0; } /* TODO remove this when we implement GPU. */ cpu = 1; /* Must be between 0.0 and 1.0. * * Physics allows it to be in 0 / infinity. * * Anything greater than 1.0 leads to numeric instabilities * for our simplistic method. For example, the following: * * 1.0 * * 1.0 0.0 1.0 * * 1.0 * * the center point goes above its surroundings on the next time step (2.0) * for a conduction coefficient of 2.0. * * Negative values make temperatures unbounded and breaks energy conservation. * * But you obviously will try out "bad" values in the simulation to see what happens. * The behaviour of this value around 1.99, 2.0, 2.01, 3.0 is specially interesting. * * At 0.0, the system does not evolve. Your mouse heat source becomes a permanent pen. * The close to one, the faster your writting dissipates. * */ conduction_coeff = 1.0; if (argc > 5) { conduction_coeff = strtod(argv[5], NULL); } which_boundary = 0; if (argc > 6) { which_boundary = strtol(argv[6], NULL, 10); } /* Ideally set to make simulation be 60 FPS. */ steps_per_frame = 1; if (argc > 7) { steps_per_frame = strtol(argv[7], NULL, 10); } window_x = 0; if (argc > 8) { window_x = strtol(argv[8], NULL, 10); } square_x = width / 2; square_y = height / 2; square_width = width / 20; square_height = height / 20; window_grid_ratio_x = width / (double)window_width; window_grid_ratio_y = height / (double)window_height; /* Window. */ glfwInit(); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); window = glfwCreateWindow(window_width, window_height, __FILE__, NULL, NULL); glfwSetWindowPos(window, window_x, 0); glfwMakeContextCurrent(window); glfwSwapInterval(1); glewInit(); /* Shader. */ program = common_get_shader_program(vertex_shader_source, fragment_shader_source); coord2d_location = glGetAttribLocation(program, "coord2d"); vertexUv_location = glGetAttribLocation(program, "vertexUv"); textureSampler_location = glGetUniformLocation(program, "textureSampler"); if (!cpu) { /* Compute shader. */ int work_group_width_len = snprintf(NULL, 0, "%d", work_group_width); size_t compute_shader_source_len = sizeof(compute_shader_source_template) + 2 * work_group_width_len; compute_shader_source = malloc(compute_shader_source_len); snprintf( compute_shader_source, compute_shader_source_len, compute_shader_source_template, work_group_width, work_group_width ); compute_program = common_get_compute_program(compute_shader_source); free(compute_shader_source); width_location = glGetUniformLocation(compute_program, "width"); } /* vbo */ glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices_xy_uv), vertices_xy_uv, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); /* ebo */ glGenBuffers(1, &ebo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); /* vao */ glGenVertexArrays(1, &vao); glBindVertexArray(vao); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribPointer(coord2d_location, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(vertices_xy_uv[0]), (GLvoid*)0); glEnableVertexAttribArray(coord2d_location); glVertexAttribPointer(vertexUv_location, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(vertices_xy_uv[0]), (GLvoid*)(2 * sizeof(vertices_xy_uv[0]))); glEnableVertexAttribArray(vertexUv_location); glBindVertexArray(0); /* ssbo */ srand(time(NULL)); n_temperatures = width * height; temperatures = malloc(n_temperatures * sizeof(temperatures[0])); /* Initial condition. TODO: make continuous with boundary conditions. */ for (size_t i = 1; i < height - 1; ++i) { for (size_t j = 1; j < width - 1; ++j) { temperatures[i * width + j] = 0.0; } } if (cpu) { temperatures2 = malloc(n_temperatures * sizeof(temperatures[0])); /* Boundary must also be initialized for this buffer, * since the boundary is never touched after the beginning. */ init_boundary(temperatures2, width, height, which_boundary, step); } else { glGenBuffers(1, &ssbo); glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo); glBufferData(GL_SHADER_STORAGE_BUFFER, n_temperatures * sizeof(temperatures[0]), temperatures, GL_DYNAMIC_COPY); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); free(temperatures); } /* Texture. */ glGenTextures(1, &texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (!cpu) { glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RED, GL_FLOAT, NULL); /* Bind to image unit so can write to specific pixels from the compute shader. */ glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_R32F); } /* Constant state. */ glViewport(0, 0, window_width, window_height); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); /* Main loop. */ common_fps_init(); while (!glfwWindowShouldClose(window)) { if (cpu) { for ( unsigned int steps_this_frame = 0; steps_this_frame < steps_per_frame; ++steps_this_frame ) { glfwPollEvents(); glfwGetCursorPos(window, &cursor_pos_x, &cursor_pos_y); glfwSetMouseButtonCallback(window, mouse_button_callback); square_x = width - (cursor_pos_x * window_grid_ratio_y); square_y = cursor_pos_y * window_grid_ratio_y; moving_boundary_set_square( temperatures, width, height, square_x, square_y, square_width, square_height, moving_boundary_value ); init_boundary(temperatures, width, height, which_boundary, step); for (unsigned int i = 1; i < height - 1; ++i) { for (unsigned int j = 1; j < width - 1; ++j) { size_t idx = i * width + j; temperatures2[idx] = (1.0 - conduction_coeff) * temperatures2[idx] + conduction_coeff * ( temperatures[idx - 1] + temperatures[idx + 1] + temperatures[idx - width] + temperatures[idx + width] ) / 4.0; } } /* Swap old and new. */ temperature_buf = temperatures; temperatures = temperatures2; temperatures2 = temperature_buf; step++; } glTexImage2D( GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_FLOAT, temperatures2 ); } else { /* Compute. */ glUseProgram(compute_program); glUniform1ui(width_location, width); glDispatchCompute((GLuint)width / work_group_width, (GLuint)height / work_group_width, 1); glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT); } /* Draw. */ glClear(GL_COLOR_BUFFER_BIT); glUseProgram(program); glUniform1i(textureSampler_location, 0); glBindVertexArray(vao); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glBindVertexArray(0); glfwSwapBuffers(window); glfwPollEvents(); common_fps_print(); } /* Cleanup. */ glDeleteBuffers(1, &ebo); if (cpu) { free(temperatures); free(temperatures2); } else { glDeleteBuffers(1, &ssbo); } glDeleteBuffers(1, &vbo); glDeleteVertexArrays(1, &vao); glDeleteTextures(1, &texture); glDeleteProgram(program); glDeleteProgram(compute_program); glfwTerminate(); return EXIT_SUCCESS; }
int main(int argc, char **argv) { GLFWwindow *window; GLint attribute_coord2d, ibo_size, periods_location, pi2_location, time_location, win_dim_location ; GLuint height, ibo, program, width, vbo; const char *attribute_name = "coord2d"; const float periods_x = 5.0, periods_y = 10.0, pi2 = 2.0 * acos(-1.0) ; /* CLI arguments. */ if (argc > 1) { width = strtol(argv[1], NULL, 10); } else { width = WIDTH; } height = width; /* Window system. */ glfwInit(); window = glfwCreateWindow(width, height, __FILE__, NULL, NULL); glfwMakeContextCurrent(window); glewInit(); /* Shader setup. */ program = common_get_shader_program(vertex_shader_source, fragment_shader_source); attribute_coord2d = glGetAttribLocation(program, attribute_name); periods_location = glGetUniformLocation(program, "periods"); pi2_location = glGetUniformLocation(program, "pi2"); time_location = glGetUniformLocation(program, "time"); win_dim_location = glGetUniformLocation(program, "win_dim"); /* Global settings. */ glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glUseProgram(program); glViewport(0, 0, width, height); /* vbo */ glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glVertexAttribPointer( attribute_coord2d, 2, GL_FLOAT, GL_FALSE, 0, 0 ); glEnableVertexAttribArray(attribute_coord2d); /* ibo */ glGenBuffers(1, &ibo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexes), indexes, GL_STATIC_DRAW); glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &ibo_size); /* Uniforms. */ glUniform1f(pi2_location, pi2); glUniform2f(win_dim_location, width, height); glUniform2f(periods_location, periods_x, periods_y); /* Main loop. */ common_fps_init(); while (!glfwWindowShouldClose(window)) { glfwPollEvents(); glClear(GL_COLOR_BUFFER_BIT); glUniform1f(time_location, glfwGetTime()); glDrawElements(GL_TRIANGLES, ibo_size / sizeof(indexes[0]), GL_UNSIGNED_INT, 0); glfwSwapBuffers(window); common_fps_print(); } /* Cleanup. */ glDisableVertexAttribArray(attribute_coord2d); glDeleteBuffers(1, &ibo); glDeleteBuffers(1, &vbo); glDeleteProgram(program); glfwTerminate(); return EXIT_SUCCESS; }