int mrgss_renderer_initialize(mrgss_screen* window) { mrgss_renderer *renderer = window->renderer; size_t bufferSize; GLbitfield flags; //Create and activate the shader program as it will always use the same shader GLuint vshader,fshader; renderer->item_count = 0; renderer->tex_count = 0; renderer->isOutdated = 0; vshader = compile_shader(default_vertex, GL_VERTEX_SHADER); fshader = compile_shader(default_fragment, GL_FRAGMENT_SHADER); renderer->shader = compile_shader_program(vshader, fshader); glUseProgram(renderer->shader); // set ortho to the shader mrgss_renderer_resize_window(window); //creamos el buffer glGenBuffers(1, &renderer->vbo); glBindBuffer(GL_ARRAY_BUFFER, renderer->vbo); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex2D), 0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(vertex2D), (GLvoid *) (sizeof (GL_FLOAT) * 3) ); bufferSize = MAX_SPRITES * 4 * sizeof(vertex2D);//el tamaño del buffer es de 4 vertices por sprite flags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT; glBufferStorage(GL_ARRAY_BUFFER, bufferSize, 0, flags); renderer->persistentBuffer = (vertex2D*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bufferSize, flags); //// creamos un buffer para enviar info a los shadders glGenBuffers(1, &renderer->ssbo); glBindBuffer(GL_SHADER_STORAGE_BUFFER, renderer->ssbo); bufferSize = MAX_SPRITES * 16 * sizeof(GLfloat); glBufferStorage(GL_SHADER_STORAGE_BUFFER, bufferSize, 0, flags); renderer->persistentShaderBuffer = (GLfloat*)glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, bufferSize, flags); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, renderer->ssbo); glGenTextures(1, &renderer->texture); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D_ARRAY, renderer->texture); glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, MAX_IMG_SIZE, MAX_IMG_SIZE, 100); glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); return 0; }
Renderer::Renderer(int width, int height) : width_(width), height_(height) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // init texture glGenTextures(1, &texture_); glBindTexture(GL_TEXTURE_2D, texture_); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); glGenTextures(1, &disp_texture_); glBindTexture(GL_TEXTURE_2D, disp_texture_); glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, width_, height_, 0, GL_RED, GL_UNSIGNED_SHORT, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glBindTexture(GL_TEXTURE_2D, 0); // init shader program static const char* vert_src = "#version 330 core\n" "layout(location = 0) in vec3 position;\n" "layout(location = 1) in vec2 tex_coord;\n" "out vec2 uv_coord;\n" "void main() {\n" "gl_Position = vec4(position.xyz, 1.0);\n" "uv_coord = tex_coord\n;" "}\n"; static const char* input_frag_src = "#version 330 core\n" "precision highp float;\n" "out mediump vec4 fragColor;\n" "in vec2 uv_coord;\n" "uniform highp usampler2D tex_sampler;\n" "void main() {\n" " float x = float(texture(tex_sampler, uv_coord).r) / 256.0;\n" " vec4 color = vec4(x, x, x, 1.0);\n" " fragColor = color;\n" "}\n"; program_input_ = compile_shader_program(vert_src, input_frag_src); static const char* disp_frag_src = "#version 330 core\n" "precision highp float;\n" "out mediump vec4 fragColor;\n" "in vec2 uv_coord;\n" "uniform sampler2D tex_sampler;\n" "uniform int inv_disp_size;\n" "void main() {\n" " float x = texture(tex_sampler, uv_coord).r * inv_disp_size;\n" " vec4 color = vec4(x, x, x , 1.0);\n" " fragColor = color;\n" "}\n"; program_disp_ = compile_shader_program(vert_src, disp_frag_src); static const char* cdisp_frag_src = "#version 330 core\n" "precision highp float;\n" "out mediump vec4 fragColor;\n" "in vec2 uv_coord;\n" "uniform sampler2D tex_sampler;\n" "uniform int inv_disp_size;\n" "void main() {\n" " float val = texture(tex_sampler, uv_coord).r * inv_disp_size;\n" " vec4 color = clamp(vec4(-2.0 + val * 4.0, 2.0 - abs(val-0.5) * 4.0, 2.0 - val * 4.0, 1.0), 0.0, 1.0);\n" " fragColor = color;\n" "}\n"; program_cdisp_ = compile_shader_program(vert_src, cdisp_frag_src); // init array buffer glGenBuffers(1, &vert_buffer_); glBindBuffer(GL_ARRAY_BUFFER, vert_buffer_); const float verts[] = { // x, y, z, u, v -1.0, 1.0, 0.0, 0.0, 0.0, -1.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, -1.0, 0.0, 1.0, 1.0, }; glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); }
int main() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Create a GLFWwindow object that we can use for GLFW's functions auto window = glfwCreateWindow(WIDTH, HEIGHT, "N-Body", NULL, NULL); glfwMakeContextCurrent(window); if (!window) { std::cout << "Failed to create GLFW window: " << std::endl; glfwTerminate(); return -1; } // Set the required callback functions glfwSetKeyCallback(window, key_callback); if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) { std::cout << "Failed to initialize OpenGL context" << std::endl; return -1; } GLuint program = compile_shader_program( "#version 400\n" "layout(location = 0) in vec2 position;" "uniform mat4 mvp;" "void main() {" " gl_Position = mvp * vec4(position, 0, 1);" "}", "#version 400\n" "out vec4 color;" "void main() {" " color = vec4(0.8, 0.7, 0.7, 1.0);" "}" ); int width, height; glfwGetFramebufferSize(window, &width, &height); glViewport(0, 0, width, height); World world; std::random_device r; std::default_random_engine e(r()); std::uniform_real_distribution<float> position_dist(-0.8f, 0.8f); std::uniform_real_distribution<double> mass_dist(0, 2); for(size_t i = 0; i < 500; ++i) { Body body; body.position.x = position_dist(e); body.position.y = position_dist(e); body.mass = std::pow(10.0, mass_dist(e)); body.radius = std::pow(body.mass, 1.0/3.0)/200; world.bodies.push_back(body); } auto fan_vertices = create_circle_fan(32); GLuint vbo; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, fan_vertices.size() * sizeof(glm::vec2), &fan_vertices[0], GL_STATIC_DRAW); GLuint vao; glGenVertexArrays(1, &vao); glBindVertexArray(vao); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr); float aspect = static_cast<float>(width)/static_cast<float>(height); glm::mat4 projection = glm::ortho(-aspect, aspect, -1.0f, 1.0f, -1.0f, 1.0f); auto mvp_location = glGetUniformLocation(program, "mvp"); while (!glfwWindowShouldClose(window)) { glfwPollEvents(); world.tick(0.01); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(program); glBindVertexArray(vao); for(auto body : world.bodies) { glm::mat4 model = glm::scale(glm::translate(glm::mat4(), glm::vec3(body.position, 0.0)), glm::vec3(body.radius)); glm::mat4 mvp = projection * model; glUniformMatrix4fv(mvp_location, 1, GL_FALSE, glm::value_ptr(mvp)); glDrawArrays(GL_TRIANGLE_FAN, 0, fan_vertices.size()); } glfwSwapBuffers(window); } // Terminates GLFW, clearing any resources allocated by GLFW. glfwTerminate(); return 0; }