example_texgen(void) : scale(1.0f) , aspect(1.0f) { gl.uniform(erg.scale_loc, scale, scale); gl.disable(GL.depth_test); }
lighting_example( const example_params& params, const example_state_view& state, eagine::memory::buffer& temp_buffer ): erase_prog(params) , light_prog(params) , background( temp_buffer, (shapes::vertex_attrib_kind::position |0), 36, 72 ), shape( temp_buffer, (shapes::vertex_attrib_kind::position |0)+ (shapes::vertex_attrib_kind::normal |1)+ (shapes::vertex_attrib_kind::wrap_coord|2), 96, 144 ), shp_turns(0.0f) , cam_orbit(0.0f) , cam_turns(0.0f) , cam_pitch(0.5f) , cam_dist_dir(-1) , cam_turn_dir(1) , cam_elev_dir(1) { gl.clear_depth(1); gl.disable(GL.cull_face); set_projection(state); }
void resize(const example_state_view& state) override { gl.viewport(state.width(), state.height()); aspect = state.aspect(); gl.uniform(prog.scale_loc, scale*aspect, scale); }
example_program(void) { shader vs(GL.vertex_shader); vs.source(glsl_literal( "#version 140\n" "uniform mat4 Projection;\n" "in vec4 Position;\n" "in vec3 Normal;\n" "in vec3 BoxCoord;\n" "in vec3 TexCoord;\n" "out vec2 vertCoord;\n" "out vec3 vertColor1;\n" "out vec3 vertColor2;\n" "void main(void)\n" "{\n" " gl_Position = Projection*Position;\n" " vertColor1 = mix(BoxCoord,abs(Normal),0.5);\n" " vertColor2 = vertColor1 * 0.3;\n" " vertCoord = TexCoord.xy*(2+TexCoord.z);\n" "}\n" )); vs.compile(); shader fs(GL.fragment_shader); fs.source(glsl_literal( "#version 140\n" "in vec2 vertCoord;\n" "in vec3 vertColor1;\n" "in vec3 vertColor2;\n" "out vec3 fragColor;\n" "float pattern(vec2 tc)\n" "{\n" " return float((int(tc.x)%2+int(tc.y)%2)%2);\n" "}\n" "void main(void)\n" "{\n" " float c = pattern(vertCoord);\n" " fragColor = mix(vertColor1, vertColor2, c);\n" "}\n" )); fs.compile(); attach(vs); attach(fs); link(); report_link_error(); gl.use(*this); gl.query_location(projection, *this, "Projection"); }
void init(const texture_image_file& image_data) { gl.bind(GL.texture_2d, *this); gl.texture_min_filter(GL.texture_2d, GL.nearest); gl.texture_mag_filter(GL.texture_2d, GL.nearest); gl.texture_wrap( GL.texture_2d, GL.texture_wrap_s, GL.repeat ); gl.texture_image_2d(GL.texture_2d, image_data.spec()); }
voronoi_program(const example_params& params) { std::string path = params.get_resource_file_path( example_resource_type::program_source, cstr_ref("014_voronoi.oglpprog") ); _init(program_source_file(cstr_ref(path))); gl.use(*this); gl.query_location(offset_loc, *this, "Offset"); gl.query_location(scale_loc, *this, "Scale"); }
lighting_program(const example_params& params) { std::string path = params.get_resource_file_path( example_resource_type::program_source, cstr_ref("028_lighting-lt.oglpprog") ); build_program(*this, program_source_file(cstr_ref(path))); gl.use(*this); gl.query_location(projection, *this, "Projection"); gl.query_location(modelview, *this, "Modelview"); }
void user_idle(const example_state_view& state) override { if(state.user_idle_time() > seconds_(1)) { const float t = value(state.frame_duration())*60; scale *= std::pow(1.f+0.05f*t, scale_dir); if(scale < min_scale) { scale_dir *= -1.f; ofs_x_dir *= -1.f; ofs_y_dir *= ofs_x_dir; scale = min_scale; } if(scale > max_scale) { scale_dir *= -1.f; ofs_y_dir *= -1.f; ofs_x_dir *= ofs_y_dir; scale = max_scale; } offset_x += ofs_x_dir*t*scale/30; offset_y += ofs_y_dir*t*scale/30; gl.uniform(prog.offset_loc, offset_x, offset_y); gl.uniform(prog.scale_loc, scale*aspect, scale); } }
void resize(const example_state_view& state) override { gl.viewport(0, 0, state.width(), state.height()); erg.set_dimensions(state.width(), state.height()); aspect = state.aspect(); }
void pointer_scrolling(const example_state_view& state) override { scale *= float(std::pow(2,-state.norm_delta_pointer_z())); if(scale < min_scale) scale = min_scale; if(scale > max_scale) scale = max_scale; gl.uniform(erg.scale_loc, scale*aspect, scale); }
void set_projection(const example_state_view& state) { auto projection = matrix_perspective::y( right_angle_(), state.aspect(), 0.5f, 50.f )*matrix_orbiting_y_up( vec3(), smooth_lerp(1.5f, 5.0f, cam_orbit), turns_(cam_turns), smooth_oscillate(radians_(1.5f), cam_pitch) ); gl.use(light_prog); gl.uniform(light_prog.projection, projection); gl.use(erase_prog); gl.uniform(erase_prog.projection, projection); }
void pointer_motion(const example_state_view& state) override { if(state.pointer_dragging()) { offset_x -= 2*state.norm_delta_pointer_x()*scale; offset_y -= 2*state.norm_delta_pointer_y()*scale; gl.uniform(prog.offset_loc, offset_x, offset_y); } }
cube_example( const example_state_view& state, eagine::memory::buffer& temp_buffer ): prog() , cube( temp_buffer, shapes::vertex_attrib_kind::position+ shapes::vertex_attrib_kind::normal+ shapes::vertex_attrib_kind::box_coord+ shapes::vertex_attrib_kind::face_coord ), cam_orbit(0.5) , cam_turns(0.12f) , cam_pitch(0.72f) , cam_dist_dir(-1) , cam_turn_dir(1) , cam_elev_dir(1) { gl.clear_color(0.6f, 0.6f, 0.5f, 0); gl.clear_depth(1); gl.enable(GL.depth_test); set_projection(state); }
example_voronoi(const example_params& params) : tex(params) , prog(params) , screen(prog) , ofs_x_dir(1.f) , ofs_y_dir(1.f) , offset_x(-0.5f) , offset_y(0.0f) , scale_dir(1.f) , scale(10.0f) , aspect(1.0f) { gl.disable(GL.depth_test); }
void user_idle(const example_state_view& state) override { if(state.user_idle_time() > seconds_(1)) { using namespace eagine::math; float new_sc = float(smooth_lerp( min_scale, max_scale, value(state.exec_time())*0.4f )); scale = interpolate_linear(new_sc, scale, 0.9f); gl.uniform(erg.scale_loc, scale, scale); } }
void user_idle(const example_state_view& state) override { if(state.user_idle_time() > seconds_(1)) { const float s = value(state.frame_duration())*60; const float dest_offset_x = -0.525929f; const float dest_offset_y = -0.668547f; const float c = 0.02f * s; offset_x = c*dest_offset_x + (1-c)*offset_x; offset_y = c*dest_offset_y + (1-c)*offset_y; scale *= (1-0.01f*s); if(scale < min_scale) scale = min_scale; gl.uniform(offset_loc, offset_x, offset_y); gl.uniform(scale_loc, scale*aspect, scale); } }
example_recursive_cube(void) : tex_side(512) , rnd_tex(tex_side) , cube(prog) , current_buf(0) , rad(0.0f) { gl.clear_color(0.8f, 0.8f, 0.8f, 0.0f); gl.clear_depth(1.0f); gl.enable(GL.depth_test); gl.enable(GL.cull_face); gl.cull_face(GL.back); gl.front_face(GL.ccw); }
void render(const example_state_view& state) override { gl.use(erase_prog); gl.disable(GL.depth_test); background.use(); background.draw(); shp_turns += 0.1f*state.frame_duration().value(); gl.use(light_prog); gl.uniform( light_prog.modelview, matrix_rotation_x(turns_(shp_turns)/1)* matrix_rotation_y(turns_(shp_turns)/2)* matrix_rotation_z(turns_(shp_turns)/3) ); gl.clear(GL.depth_buffer_bit); gl.enable(GL.depth_test); shape.use(); shape.draw(); }
example_program(void) { shader vs(GL.vertex_shader); vs.source(glsl_literal( "#version 140\n" "uniform mat4 Projection;" "uniform mat4 Modelview;" "uniform vec3 LightPos;" "in vec4 Position;\n" "in vec3 Normal;\n" "in vec2 TexCoord;\n" "out vec3 vertNormal;\n" "out vec3 vertLightDir;\n" "out vec2 vertTexCoord;\n" "void main(void)\n" "{\n" " gl_Position = Modelview*Position;\n" " vertNormal = mat3(Modelview)*Normal;\n" " vertLightDir = LightPos - gl_Position.xyz;\n" " vertTexCoord = TexCoord;\n" " gl_Position = Projection*gl_Position;\n" "}\n" )); vs.compile(); vs.report_compile_error(); shader fs(GL.fragment_shader); fs.source(glsl_literal( "#version 140\n" "uniform sampler2D CubeTex;" "in vec3 vertNormal;\n" "in vec3 vertLightDir;\n" "in vec2 vertTexCoord;\n" "out vec4 fragColor;\n" "void main(void)\n" "{\n" " float d=0.3*dot(vertNormal, normalize(vertLightDir));\n" " float i=0.6 + max(d, 0.0);\n" " fragColor = texture(CubeTex, vertTexCoord)*i;\n" "}\n" )); fs.compile(); fs.report_compile_error(); attach(vs); attach(fs); link(); report_link_error(); gl.use(*this); gl.query_location(projection, *this, "Projection"); gl.query_location(modelview, *this, "Modelview"); gl.query_location(light_pos, *this, "LightPos"); gl.query_location(cube_tex, *this, "CubeTex"); }
rendered_textures(GLsizei tex_side) { for(GLuint i=0; i<2u; ++i) { texture_name tex = texs[i]; gl.active_texture(GL.texture0+i); gl.bind(GL.texture_2d, tex); gl.texture_min_filter(GL.texture_2d, GL.linear); gl.texture_mag_filter(GL.texture_2d, GL.linear); gl.texture_image_2d( GL.texture_2d, 0, GL.rgb, tex_side, tex_side, 0, GL.rgb, GL.unsigned_byte, const_memory_block() ); renderbuffer_name rbo = rbos[i]; gl.bind(GL.renderbuffer, rbo); gl.renderbuffer_storage( GL.renderbuffer, GL.depth_component, tex_side, tex_side ); framebuffer_name fbo = fbos[i]; gl.bind(GL.draw_framebuffer, fbo); gl.framebuffer_texture_2d( GL.draw_framebuffer, GL.color_attachment0, GL.texture_2d, tex, 0 ); gl.framebuffer_renderbuffer( GL.draw_framebuffer, GL.depth_attachment, GL.renderbuffer, rbo ); gl.viewport(tex_side, tex_side); gl.clear(GL.color_buffer_bit); } gl.bind(GL.draw_framebuffer, default_framebuffer); gl.bind(GL.renderbuffer, no_renderbuffer); }
namespace oglplus { static constants GL; static operations gl; class example_program : public program { public: uniform_location projection, modelview, light_pos, cube_tex; example_program(void) { shader vs(GL.vertex_shader); vs.source(glsl_literal( "#version 140\n" "uniform mat4 Projection;" "uniform mat4 Modelview;" "uniform vec3 LightPos;" "in vec4 Position;\n" "in vec3 Normal;\n" "in vec2 TexCoord;\n" "out vec3 vertNormal;\n" "out vec3 vertLightDir;\n" "out vec2 vertTexCoord;\n" "void main(void)\n" "{\n" " gl_Position = Modelview*Position;\n" " vertNormal = mat3(Modelview)*Normal;\n" " vertLightDir = LightPos - gl_Position.xyz;\n" " vertTexCoord = TexCoord;\n" " gl_Position = Projection*gl_Position;\n" "}\n" )); vs.compile(); vs.report_compile_error(); shader fs(GL.fragment_shader); fs.source(glsl_literal( "#version 140\n" "uniform sampler2D CubeTex;" "in vec3 vertNormal;\n" "in vec3 vertLightDir;\n" "in vec2 vertTexCoord;\n" "out vec4 fragColor;\n" "void main(void)\n" "{\n" " float d=0.3*dot(vertNormal, normalize(vertLightDir));\n" " float i=0.6 + max(d, 0.0);\n" " fragColor = texture(CubeTex, vertTexCoord)*i;\n" "}\n" )); fs.compile(); fs.report_compile_error(); attach(vs); attach(fs); link(); report_link_error(); gl.use(*this); gl.query_location(projection, *this, "Projection"); gl.query_location(modelview, *this, "Modelview"); gl.query_location(light_pos, *this, "LightPos"); gl.query_location(cube_tex, *this, "CubeTex"); } }; class cube_model { private: buffer positions; buffer normals; buffer texcoords; public: vertex_array vao; cube_model(const program& prog) { const GLfloat v[8][3] = { {-0.5f, -0.5f, -0.5f}, {+0.5f, -0.5f, -0.5f}, {-0.5f, +0.5f, -0.5f}, {+0.5f, +0.5f, -0.5f}, {-0.5f, -0.5f, +0.5f}, {+0.5f, -0.5f, +0.5f}, {-0.5f, +0.5f, +0.5f}, {+0.5f, +0.5f, +0.5f} }; const GLint f[6][2][3] = { {{0, 4, 2}, {2, 4, 6}}, {{5, 1, 7}, {7, 1, 3}}, {{0, 1, 4}, {4, 1, 5}}, {{6, 7, 2}, {2, 7, 3}}, {{1, 0, 3}, {3, 0, 2}}, {{4, 5, 6}, {6, 5, 7}} }; gl.bind(vao); const GLuint vertex_count = 6 * 2 * 3; // positions GLfloat vertex_data[vertex_count * 3]; for(GLuint fi=0;fi!=6;++fi) for(GLuint ti=0;ti!=2;++ti) for(GLuint vi=0;vi!=3;++vi) { for(GLuint ci=0;ci!=3;++ci) { vertex_data[fi*2*3*3+ti*3*3+vi*3+ci] = v[f[fi][ti][vi]][ci]; } } gl.bind(GL.array_buffer, positions); gl.buffer_data(GL.array_buffer, vertex_data, GL.static_draw); gl.vertex_array_attrib_pointer( vertex_attrib_location(0), 3, GL.float_, false, 0, nullptr ); gl.enable_vertex_array_attrib(vertex_attrib_location(0)); vertex_attrib_location va_p; gl.query_location(va_p, prog, "Position"); gl.vertex_array_attrib_pointer( va_p, 3, GL.float_, false, 0, nullptr ); gl.enable_vertex_array_attrib(va_p); // normals const GLfloat n[6][3] = { {-1.0f, 0.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f, -1.0f, 0.0f}, { 0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, { 0.0f, 0.0f, 1.0f} }; for(GLuint fi=0;fi!=6;++fi) for(GLuint vi=0;vi!=6;++vi) { for(GLuint ci=0;ci!=3;++ci) { vertex_data[(fi*6+vi)*3+ci] = n[fi][ci]; } } gl.bind(GL.array_buffer, normals); gl.buffer_data(GL.array_buffer, vertex_data, GL.static_draw); vertex_attrib_location va_n; gl.query_location(va_n, prog, "Normal"); gl.vertex_array_attrib_pointer( va_n, 3, GL.float_, false, 0, nullptr ); gl.enable_vertex_array_attrib(va_n); // tex-coords const GLfloat c[6][2] = { {0.0f, 0.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 1.0f} }; for(GLuint fi=0;fi!=6;++fi) { for(GLuint vi=0;vi!=6;++vi) { for(GLuint ci=0;ci!=2;++ci) { vertex_data[(fi*6+vi)*2+ci] = c[vi][ci]; } } } gl.bind(GL.array_buffer, texcoords); gl.buffer_data( GL.array_buffer, buffer_data_spec{vertex_data, vertex_count * 2}, GL.static_draw ); vertex_attrib_location va_c; gl.query_location(va_c, prog, "TexCoord"); gl.vertex_array_attrib_pointer( va_c, 2, GL.float_, false, 0, nullptr ); gl.enable_vertex_array_attrib(va_c); } }; class rendered_textures { public: texture_array<2> texs; renderbuffer_array<2> rbos; framebuffer_array<2> fbos; rendered_textures(GLsizei tex_side) { for(GLuint i=0; i<2u; ++i) { texture_name tex = texs[i]; gl.active_texture(GL.texture0+i); gl.bind(GL.texture_2d, tex); gl.texture_min_filter(GL.texture_2d, GL.linear); gl.texture_mag_filter(GL.texture_2d, GL.linear); gl.texture_image_2d( GL.texture_2d, 0, GL.rgb, tex_side, tex_side, 0, GL.rgb, GL.unsigned_byte, const_memory_block() ); renderbuffer_name rbo = rbos[i]; gl.bind(GL.renderbuffer, rbo); gl.renderbuffer_storage( GL.renderbuffer, GL.depth_component, tex_side, tex_side ); framebuffer_name fbo = fbos[i]; gl.bind(GL.draw_framebuffer, fbo); gl.framebuffer_texture_2d( GL.draw_framebuffer, GL.color_attachment0, GL.texture_2d, tex, 0 ); gl.framebuffer_renderbuffer( GL.draw_framebuffer, GL.depth_attachment, GL.renderbuffer, rbo ); gl.viewport(tex_side, tex_side); gl.clear(GL.color_buffer_bit); } gl.bind(GL.draw_framebuffer, default_framebuffer); gl.bind(GL.renderbuffer, no_renderbuffer); } }; class example_recursive_cube : public example { private: const GLsizei tex_side; rendered_textures rnd_tex; example_program prog; cube_model cube; unsigned current_buf; radians_t<float> rad; public: example_recursive_cube(void) : tex_side(512) , rnd_tex(tex_side) , cube(prog) , current_buf(0) , rad(0.0f) { gl.clear_color(0.8f, 0.8f, 0.8f, 0.0f); gl.clear_depth(1.0f); gl.enable(GL.depth_test); gl.enable(GL.cull_face); gl.cull_face(GL.back); gl.front_face(GL.ccw); } void resize(const example_state_view& state) override { gl.viewport(state.width(), state.height()); } bool continue_running(const example_state_view& state) override { return state.user_idle_time() < seconds_(20); } void render(const example_state_view& state) override { rad += radians_(0.5f*state.frame_duration().value()); current_buf = (current_buf+1)%2; gl.uniform( prog.light_pos, vec3(cos(rad)*4, sin(rad)*4, 8) ); gl.uniform( prog.modelview, matrix_rotation_x(rad*1)* matrix_rotation_y(rad*2)* matrix_rotation_z(rad*3) ); // draw into the texture gl.bind(GL.draw_framebuffer, rnd_tex.fbos[current_buf]); gl.viewport(tex_side, tex_side); GLfloat s = 0.5f; gl.uniform( prog.projection, oglplus::matrix_perspective(-s,+s, -s,+s, 1.0f, 5)* oglplus::matrix_translation(0,0,-2) ); gl.clear(GL.color_buffer_bit|GL.depth_buffer_bit); gl.draw_arrays(GL.triangles, 0, 6 * 2 * 3); // draw on screen gl.bind(GL.draw_framebuffer, default_framebuffer); gl.viewport(state.width(), state.height()); gl.uniform(prog.cube_tex, GLint(current_buf)); GLfloat h = 0.55f; GLfloat w = h*state.aspect(); gl.uniform( prog.projection, oglplus::matrix_perspective(-w,+w, -h,+h, 1, 3)* oglplus::matrix_translation(0,0,-2) ); gl.clear(GL.color_buffer_bit|GL.depth_buffer_bit); gl.draw_arrays(GL.triangles, 0, 6 * 2 * 3); } }; std::unique_ptr<example> make_example( const example_args&, const example_params&, const example_state_view& ) { return std::unique_ptr<example>(new example_recursive_cube()); } void adjust_params(example_params& params) { params.depth_buffer(true); params.stencil_buffer(false); } bool is_example_param(const example_arg&) { return false; } } // namespace oglplus
cube_model(const program& prog) { const GLfloat v[8][3] = { {-0.5f, -0.5f, -0.5f}, {+0.5f, -0.5f, -0.5f}, {-0.5f, +0.5f, -0.5f}, {+0.5f, +0.5f, -0.5f}, {-0.5f, -0.5f, +0.5f}, {+0.5f, -0.5f, +0.5f}, {-0.5f, +0.5f, +0.5f}, {+0.5f, +0.5f, +0.5f} }; const GLint f[6][2][3] = { {{0, 4, 2}, {2, 4, 6}}, {{5, 1, 7}, {7, 1, 3}}, {{0, 1, 4}, {4, 1, 5}}, {{6, 7, 2}, {2, 7, 3}}, {{1, 0, 3}, {3, 0, 2}}, {{4, 5, 6}, {6, 5, 7}} }; gl.bind(vao); const GLuint vertex_count = 6 * 2 * 3; // positions GLfloat vertex_data[vertex_count * 3]; for(GLuint fi=0;fi!=6;++fi) for(GLuint ti=0;ti!=2;++ti) for(GLuint vi=0;vi!=3;++vi) { for(GLuint ci=0;ci!=3;++ci) { vertex_data[fi*2*3*3+ti*3*3+vi*3+ci] = v[f[fi][ti][vi]][ci]; } } gl.bind(GL.array_buffer, positions); gl.buffer_data(GL.array_buffer, vertex_data, GL.static_draw); gl.vertex_array_attrib_pointer( vertex_attrib_location(0), 3, GL.float_, false, 0, nullptr ); gl.enable_vertex_array_attrib(vertex_attrib_location(0)); vertex_attrib_location va_p; gl.query_location(va_p, prog, "Position"); gl.vertex_array_attrib_pointer( va_p, 3, GL.float_, false, 0, nullptr ); gl.enable_vertex_array_attrib(va_p); // normals const GLfloat n[6][3] = { {-1.0f, 0.0f, 0.0f}, { 1.0f, 0.0f, 0.0f}, { 0.0f, -1.0f, 0.0f}, { 0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, { 0.0f, 0.0f, 1.0f} }; for(GLuint fi=0;fi!=6;++fi) for(GLuint vi=0;vi!=6;++vi) { for(GLuint ci=0;ci!=3;++ci) { vertex_data[(fi*6+vi)*3+ci] = n[fi][ci]; } } gl.bind(GL.array_buffer, normals); gl.buffer_data(GL.array_buffer, vertex_data, GL.static_draw); vertex_attrib_location va_n; gl.query_location(va_n, prog, "Normal"); gl.vertex_array_attrib_pointer( va_n, 3, GL.float_, false, 0, nullptr ); gl.enable_vertex_array_attrib(va_n); // tex-coords const GLfloat c[6][2] = { {0.0f, 0.0f}, {1.0f, 0.0f}, {0.0f, 1.0f}, {0.0f, 1.0f}, {1.0f, 0.0f}, {1.0f, 1.0f} }; for(GLuint fi=0;fi!=6;++fi) { for(GLuint vi=0;vi!=6;++vi) { for(GLuint ci=0;ci!=2;++ci) { vertex_data[(fi*6+vi)*2+ci] = c[vi][ci]; } } } gl.bind(GL.array_buffer, texcoords); gl.buffer_data( GL.array_buffer, buffer_data_spec{vertex_data, vertex_count * 2}, GL.static_draw ); vertex_attrib_location va_c; gl.query_location(va_c, prog, "TexCoord"); gl.vertex_array_attrib_pointer( va_c, 2, GL.float_, false, 0, nullptr ); gl.enable_vertex_array_attrib(va_c); }
namespace oglplus { static constants GL; static operations gl; class erase_program : public program { private: program_source_file _get_source(const example_params& params) { std::string path = params.get_resource_file_path( example_resource_type::program_source, cstr_ref("028_lighting-bg.oglpprog") ); return program_source_file(cstr_ref(path)); } public: uniform_location projection; erase_program(const example_params& params) : program(build_program(_get_source(params))) { gl.use(*this); gl.query_location(projection, *this, "Projection"); } }; class lighting_program : public program { public: uniform_location projection, modelview; lighting_program(const example_params& params) { std::string path = params.get_resource_file_path( example_resource_type::program_source, cstr_ref("028_lighting-lt.oglpprog") ); build_program(*this, program_source_file(cstr_ref(path))); gl.use(*this); gl.query_location(projection, *this, "Projection"); gl.query_location(modelview, *this, "Modelview"); } }; class lighting_example : public example { private: erase_program erase_prog; lighting_program light_prog; shapes::generator_wrapper<shapes::unit_sphere_gen, 1> background; shapes::generator_wrapper<shapes::unit_torus_gen, 3> shape; float shp_turns; float cam_orbit; float cam_turns; float cam_pitch; short cam_dist_dir; short cam_turn_dir; short cam_elev_dir; void mod_bouncing(short& dir, float& val, float inc) { val += inc; if(val > 1.f) { val = 1.f; dir = -1; } if(val < 0.f) { val = 0.f; dir = +1; } } void mod_cam_orbit(float inc) { mod_bouncing(cam_dist_dir, cam_orbit, inc); } void mod_cam_turns(float inc) { cam_turns += inc; cam_turn_dir = (inc > 0)?1:-1; } void mod_cam_pitch(float inc) { mod_bouncing(cam_elev_dir, cam_pitch, inc); } void set_projection(const example_state_view& state) { auto projection = matrix_perspective::y( right_angle_(), state.aspect(), 0.5f, 50.f )*matrix_orbiting_y_up( vec3(), smooth_lerp(1.5f, 5.0f, cam_orbit), turns_(cam_turns), smooth_oscillate(radians_(1.5f), cam_pitch) ); gl.use(light_prog); gl.uniform(light_prog.projection, projection); gl.use(erase_prog); gl.uniform(erase_prog.projection, projection); } public: lighting_example( const example_params& params, const example_state_view& state, eagine::memory::buffer& temp_buffer ): erase_prog(params) , light_prog(params) , background( temp_buffer, (shapes::vertex_attrib_kind::position |0), 36, 72 ), shape( temp_buffer, (shapes::vertex_attrib_kind::position |0)+ (shapes::vertex_attrib_kind::normal |1)+ (shapes::vertex_attrib_kind::wrap_coord|2), 96, 144 ), shp_turns(0.0f) , cam_orbit(0.0f) , cam_turns(0.0f) , cam_pitch(0.5f) , cam_dist_dir(-1) , cam_turn_dir(1) , cam_elev_dir(1) { gl.clear_depth(1); gl.disable(GL.cull_face); set_projection(state); } void pointer_motion(const example_state_view& state) override { if(state.pointer_dragging()) { mod_cam_turns(-state.norm_delta_pointer_x()*0.5f); mod_cam_pitch(-state.norm_delta_pointer_y()*1.0f); set_projection(state); } } void pointer_scrolling(const example_state_view& state) override { mod_cam_orbit(-state.norm_delta_pointer_z()); set_projection(state); } void resize(const example_state_view& state) override { gl.viewport(state.width(), state.height()); set_projection(state); } void user_idle(const example_state_view& state) override { if(state.user_idle_time() > seconds_(1)) { const float s = state.frame_duration().value()/5; mod_cam_orbit(s*cam_dist_dir); mod_cam_turns(s*cam_turn_dir); mod_cam_pitch(s*cam_elev_dir); set_projection(state); } } void render(const example_state_view& state) override { gl.use(erase_prog); gl.disable(GL.depth_test); background.use(); background.draw(); shp_turns += 0.1f*state.frame_duration().value(); gl.use(light_prog); gl.uniform( light_prog.modelview, matrix_rotation_x(turns_(shp_turns)/1)* matrix_rotation_y(turns_(shp_turns)/2)* matrix_rotation_z(turns_(shp_turns)/3) ); gl.clear(GL.depth_buffer_bit); gl.enable(GL.depth_test); shape.use(); shape.draw(); } bool continue_running(const example_state_view& state) override { return state.user_idle_time() < seconds_(20); } }; std::unique_ptr<example> make_example( const example_args&, const example_params& params, const example_state_view& state ) { eagine::memory::buffer temp_buffer; return std::unique_ptr<example>(new lighting_example( params, state, temp_buffer )); } void adjust_params(example_params& params) { params.depth_buffer(true); params.stencil_buffer(false); } bool is_example_param(const example_arg&) { return false; } } // namespace oglplus
erase_program(const example_params& params) : program(build_program(_get_source(params))) { gl.use(*this); gl.query_location(projection, *this, "Projection"); }
screen_shape(const program& prog) { gl.bind(vao); GLfloat position_data[4*2] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; gl.bind(GL.array_buffer, positions); gl.buffer_data(GL.array_buffer, position_data, GL.static_draw); vertex_attrib_location va_p; gl.query_location(va_p, prog, "Position"); gl.vertex_array_attrib_pointer( va_p, 2, GL.float_, false, 0, nullptr ); gl.enable_vertex_array_attrib(va_p); GLfloat coord_data[4*2] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; gl.bind(GL.array_buffer, coords); gl.buffer_data(GL.array_buffer, coord_data, GL.static_draw); vertex_attrib_location va_c; gl.query_location(va_c, prog, "TexCoord"); gl.vertex_array_attrib_pointer( va_c, 2, GL.float_, false, 0, nullptr ); gl.enable_vertex_array_attrib(va_c); }
example_mandelbrot(void) : offset_x(-0.5f) , offset_y(0.0f) , scale(1.0f) , aspect(1.0f) { shader vs(GL.vertex_shader); vs.source(glsl_literal( "#version 130\n" "uniform vec2 Offset;\n" "uniform vec2 Scale;\n" "in vec2 Position;\n" "in vec2 Coord;\n" "out vec2 vertCoord;\n" "void main(void)\n" "{\n" " vertCoord = Coord*Scale+Offset;\n" " gl_Position = vec4(Position, 0.0, 1.0);\n" "}\n" )); vs.compile(); shader fs(GL.fragment_shader); fs.source(glsl_literal( "#version 130\n" "uniform sampler1D gradient;\n" "in vec2 vertCoord;\n" "out vec4 fragColor;\n" "void main(void)\n" "{\n" " vec2 z = vec2(0.0, 0.0);\n" " vec2 c = vertCoord;\n" " int i = 0, max = 256;\n" " while((i != max) && (distance(z, c) < 2.0))\n" " {\n" " vec2 zn = vec2(\n" " z.x * z.x - z.y * z.y + c.x,\n" " 2.0 * z.x * z.y + c.y\n" " );\n" " z = zn;\n" " ++i;\n" " }\n" " float a = float(i)/float(max);\n" " fragColor = texture(gradient, a+sqrt(length(c))*0.1);\n" "} \n" )); fs.compile(); prog.attach(vs); prog.attach(fs); prog.link(); gl.use(prog); gl.query_location(offset_loc, prog, "Offset"); gl.query_location(scale_loc, prog, "Scale"); gl.uniform(offset_loc, offset_x, offset_y); gl.bind(vao); GLfloat position_data[4*2] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; gl.bind(GL.array_buffer, positions); gl.buffer_data(GL.array_buffer, position_data, GL.static_draw); vertex_attrib_location va_p; gl.query_location(va_p, prog, "Position"); gl.vertex_array_attrib_pointer( va_p, 2, GL.float_, false, 0, nullptr ); gl.enable_vertex_array_attrib(va_p); GLfloat coord_data[4*2] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; gl.bind(GL.array_buffer, coords); gl.buffer_data(GL.array_buffer, coord_data, GL.static_draw); vertex_attrib_location va_c; gl.query_location(va_c, prog, "Coord"); gl.vertex_array_attrib_pointer( va_c, 2, GL.float_, false, 0, nullptr ); gl.enable_vertex_array_attrib(va_c); GLfloat gradient_data[8*3]; for(int i=0; i<8*3; ++i) { gradient_data[i] = (std::rand() % 10000) / 10000.f; } gl.bind(GL.texture_1d, gradient); gl.texture_min_filter(GL.texture_1d, GL.linear); gl.texture_mag_filter(GL.texture_1d, GL.linear); gl.texture_wrap( GL.texture_1d, GL.texture_wrap_s, GL.repeat ); gl.texture_image_1d( GL.texture_1d, 0, GL.rgb, 8, 0, GL.rgb, GL.float_, const_memory_block{gradient_data} ); gl.disable(GL.depth_test); }
void resize(const example_state_view& state) override { gl.viewport(state.width(), state.height()); }
namespace oglplus { static constants GL; static operations gl; class voronoi_program : public program { private: void _init(const program_source_file& prog_src) { for(span_size_t i=0, n=prog_src.shader_source_count(); i<n; ++i) { shader shdr(prog_src.shader_type(i)); shdr.source(prog_src.shader_source(i)); shdr.compile(); shdr.report_compile_error(); attach(shdr); } link(); report_link_error(); } public: uniform<GLfloat> offset_loc; uniform<GLfloat> scale_loc; voronoi_program(const example_params& params) { std::string path = params.get_resource_file_path( example_resource_type::program_source, cstr_ref("014_voronoi.oglpprog") ); _init(program_source_file(cstr_ref(path))); gl.use(*this); gl.query_location(offset_loc, *this, "Offset"); gl.query_location(scale_loc, *this, "Scale"); } }; class random_texture : public texture { private: void init(const texture_image_file& image_data) { gl.bind(GL.texture_2d, *this); gl.texture_min_filter(GL.texture_2d, GL.nearest); gl.texture_mag_filter(GL.texture_2d, GL.nearest); gl.texture_wrap( GL.texture_2d, GL.texture_wrap_s, GL.repeat ); gl.texture_image_2d(GL.texture_2d, image_data.spec()); } public: random_texture(const example_params& params) { std::string path = params.get_resource_file_path( example_resource_type::texture, cstr_ref("noise.256x256x3.oglptex") ); init(texture_image_file(cstr_ref(path))); } }; class screen_shape { private: buffer positions; buffer coords; public: vertex_array vao; screen_shape(const program& prog) { gl.bind(vao); GLfloat position_data[4*2] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; gl.bind(GL.array_buffer, positions); gl.buffer_data(GL.array_buffer, position_data, GL.static_draw); vertex_attrib_location va_p; gl.query_location(va_p, prog, "Position"); gl.vertex_array_attrib_pointer( va_p, 2, GL.float_, false, 0, nullptr ); gl.enable_vertex_array_attrib(va_p); GLfloat coord_data[4*2] = { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f }; gl.bind(GL.array_buffer, coords); gl.buffer_data(GL.array_buffer, coord_data, GL.static_draw); vertex_attrib_location va_c; gl.query_location(va_c, prog, "TexCoord"); gl.vertex_array_attrib_pointer( va_c, 2, GL.float_, false, 0, nullptr ); gl.enable_vertex_array_attrib(va_c); } }; class example_voronoi : public example { private: random_texture tex; voronoi_program prog; screen_shape screen; GLfloat ofs_x_dir, ofs_y_dir, offset_x, offset_y; GLfloat scale_dir, scale, aspect; static constexpr const float min_scale = 1.0f; static constexpr const float max_scale = 100.0f; public: example_voronoi(const example_params& params) : tex(params) , prog(params) , screen(prog) , ofs_x_dir(1.f) , ofs_y_dir(1.f) , offset_x(-0.5f) , offset_y(0.0f) , scale_dir(1.f) , scale(10.0f) , aspect(1.0f) { gl.disable(GL.depth_test); } void pointer_motion(const example_state_view& state) override { if(state.pointer_dragging()) { offset_x -= 2*state.norm_delta_pointer_x()*scale; offset_y -= 2*state.norm_delta_pointer_y()*scale; gl.uniform(prog.offset_loc, offset_x, offset_y); } } void pointer_scrolling(const example_state_view& state) override { scale *= float(std::pow(2,-state.norm_delta_pointer_z())); if(scale < min_scale) scale = min_scale; if(scale > max_scale) scale = max_scale; gl.uniform(prog.scale_loc, scale*aspect, scale); } void resize(const example_state_view& state) override { gl.viewport(state.width(), state.height()); aspect = state.aspect(); gl.uniform(prog.scale_loc, scale*aspect, scale); } void user_idle(const example_state_view& state) override { if(state.user_idle_time() > seconds_(1)) { const float t = value(state.frame_duration())*60; scale *= std::pow(1.f+0.05f*t, scale_dir); if(scale < min_scale) { scale_dir *= -1.f; ofs_x_dir *= -1.f; ofs_y_dir *= ofs_x_dir; scale = min_scale; } if(scale > max_scale) { scale_dir *= -1.f; ofs_y_dir *= -1.f; ofs_x_dir *= ofs_y_dir; scale = max_scale; } offset_x += ofs_x_dir*t*scale/30; offset_y += ofs_y_dir*t*scale/30; gl.uniform(prog.offset_loc, offset_x, offset_y); gl.uniform(prog.scale_loc, scale*aspect, scale); } } bool continue_running(const example_state_view& state) override { return state.user_idle_time() < seconds_(20); } void render(const example_state_view& /*state*/) override { gl.draw_arrays(GL.triangle_strip, 0, 4); } }; std::unique_ptr<example> make_example( const example_args&, const example_params& params, const example_state_view& ) { return std::unique_ptr<example>(new example_voronoi(params)); } void adjust_params(example_params& params) { params.rand_seed(1234); params.depth_buffer(false); params.stencil_buffer(false); } bool is_example_param(const example_arg&) { return false; } } // namespace oglplus
void render(const example_state_view& state) override { rad += radians_(0.5f*state.frame_duration().value()); current_buf = (current_buf+1)%2; gl.uniform( prog.light_pos, vec3(cos(rad)*4, sin(rad)*4, 8) ); gl.uniform( prog.modelview, matrix_rotation_x(rad*1)* matrix_rotation_y(rad*2)* matrix_rotation_z(rad*3) ); // draw into the texture gl.bind(GL.draw_framebuffer, rnd_tex.fbos[current_buf]); gl.viewport(tex_side, tex_side); GLfloat s = 0.5f; gl.uniform( prog.projection, oglplus::matrix_perspective(-s,+s, -s,+s, 1.0f, 5)* oglplus::matrix_translation(0,0,-2) ); gl.clear(GL.color_buffer_bit|GL.depth_buffer_bit); gl.draw_arrays(GL.triangles, 0, 6 * 2 * 3); // draw on screen gl.bind(GL.draw_framebuffer, default_framebuffer); gl.viewport(state.width(), state.height()); gl.uniform(prog.cube_tex, GLint(current_buf)); GLfloat h = 0.55f; GLfloat w = h*state.aspect(); gl.uniform( prog.projection, oglplus::matrix_perspective(-w,+w, -h,+h, 1, 3)* oglplus::matrix_translation(0,0,-2) ); gl.clear(GL.color_buffer_bit|GL.depth_buffer_bit); gl.draw_arrays(GL.triangles, 0, 6 * 2 * 3); }
void render(const example_state_view& /*state*/) override { gl.draw_arrays(GL.triangle_strip, 0, 4); }