From 76e3b7854e3251438e43d45b8e277d791e9aee1c Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Wed, 17 Apr 2013 23:50:23 +0200 Subject: [PATCH] Made a renderer --- src/Base.cpp | 2 +- src/client/GameRenderer.cpp | 144 +++++++++++++++++++++++++++++++++++ src/client/GameRenderer.h | 70 +++++++++++++++++ src/client/client.cpp | 5 ++ src/client/client.hpp | 4 + src/client/client_common.hpp | 14 +++- 6 files changed, 235 insertions(+), 4 deletions(-) create mode 100644 src/client/GameRenderer.cpp create mode 100644 src/client/GameRenderer.h diff --git a/src/Base.cpp b/src/Base.cpp index 553482d..20fcd9c 100644 --- a/src/Base.cpp +++ b/src/Base.cpp @@ -58,7 +58,7 @@ void Base::draw(){ try { fbo.unbind(); moggle::gl::set_viewport(0, 0, window_width, window_height); - moggle::gl::set_clear_color(0.1f, 0.1f, 0.1f, 1.0f); + moggle::gl::set_clear_color(0.0f, 0.0f, 0.0f, 0.0f); moggle::gl::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); moggle::gl::enable(GL_DEPTH_TEST); moggle::gl::enable(GL_BLEND); diff --git a/src/client/GameRenderer.cpp b/src/client/GameRenderer.cpp new file mode 100644 index 0000000..78a995a --- /dev/null +++ b/src/client/GameRenderer.cpp @@ -0,0 +1,144 @@ +#include "GameRenderer.h" +#include "client.hpp" + +#include + +namespace games { +constexpr static const char* ball_attributes[] = { + "position", + "color", + "speed", + "texture_coordinate" +}; + +constexpr static const char* line_attributes[] = { + "position", + "color" +}; + +constexpr static const char* note_attributes[] = { + "position", + "color" +}; + +template +std::vector from_strarray(const char* const (& strs)[N]) { + std::vector v(N); + for(size_t i = 0; i < N; ++i){ + v.push_back(strs[i]); + } + return v; +} + +using namespace moggle; +using namespace motor; +GameRenderer::GameRenderer() +: ball_texture(::bundle.get_texture_path() + "bol.png") +{ + gl::enable(GL_LINE_SMOOTH); + glLineWidth(1.5f); + glPointSize(4.0f); + + auto load_shader = [](Shader & shader, std::string file, std::vector attributes){ + shader.a = attributes; + + try { + auto v = shader::from_file(shader_type::vertex, ::bundle.get_shader_path() + file + ".vsh"); + auto f = shader::from_file(shader_type::fragment, ::bundle.get_shader_path() + file + ".fsh"); + + shader.s.attach(v); + shader.s.attach(f); + } catch (std::exception & e){ + CERR << e.what(); + } + + for(auto str : ball_attributes){ + shader.s.bind_attribute(shader.attribute_location(str), str); + } + + shader.s.link(); + }; + + load_shader(ball_shader, "ball", {"position", "color", "texture_coordinate"}); + load_shader(line_shader, "line", {"position", "color"}); + load_shader(note_shader, "note", {"position"}); +} + +void GameRenderer::draw(Client const & client){ + gl::disable(GL_DEPTH_TEST); + + auto projectionMatrix = projection_matrices::orthographic(client.sim.bounds.xmin, client.sim.bounds.xmax, client.sim.bounds.ymax, client.sim.bounds.ymin, -100.0f, 100.0f); + auto modelViewProjectionMatrix = projectionMatrix; + + if(!client.beat.notes.empty()){ + moggle::gl::blend_function(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + note_shader.s.use(); + note_shader.s.uniform>("modelViewProjectionMatrix").set(modelViewProjectionMatrix); + + // glVertexAttribPointer(it->second, size, type, normalized, stride, ptr); + gl::enable_vertex_attribute_array(note_shader.attribute_location("position")); + gl::vertex_attribute_pointer(note_shader.attribute_location("position"), 2, GL_FLOAT, GL_FALSE, sizeof(note_type), &client.beat.notes[0].information); + + gl::draw_arrays(GL_POINTS, 0, client.beat.notes.size()); + } + + if(!client.lines.empty()){ + moggle::gl::blend_function(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + line_shader.s.use(); + line_shader.s.uniform>("modelViewProjectionMatrix").set(modelViewProjectionMatrix); + + lines.clear(); + lines.reserve(client.lines.size() * 2); + for(auto const & l : client.lines){ + Color color = (l->line_kind == simulation::kFallThrough) + ? Color{1.0f, l->color_intensity, std::sin(l->color_intensity)} + : Color{std::sin(l->color_intensity), 0.5f + 0.5f*l->color_intensity, 1.0f}; + lines.push_back({l->starting_point, color}); + lines.push_back({l->end_point, color}); + } + + if(debug_draw){ + for(auto const & l : client.sim.lines){ + Color color = (l.line_kind == simulation::kFallThrough) ? Color{1.0, 0.0, 0.0} : Color{0.0, 0.5, 1.0}; + lines.push_back({l.starting_point, color}); + lines.push_back({l.end_point, color}); + } + } + + gl::enable_vertex_attribute_array(line_shader.attribute_location("position")); + gl::vertex_attribute_pointer(line_shader.attribute_location("position"), 2, GL_FLOAT, GL_FALSE, sizeof(LineVertex), &lines[0]); + gl::enable_vertex_attribute_array(line_shader.attribute_location("color")); + gl::vertex_attribute_pointer(line_shader.attribute_location("color"), 3, GL_FLOAT, GL_FALSE, sizeof(LineVertex), &lines[0].color); + + gl::draw_arrays(GL_LINES, 0, lines.size()); + } + + if(!client.sim.balls.empty()){ + gl::blend_function(GL_ONE, GL_ONE); + ball_shader.s.use(); + ball_shader.s.uniform>("modelViewProjectionMatrix").set(modelViewProjectionMatrix); + + balls.clear(); + balls.reserve(client.sim.balls.size()); + for(auto const & b : client.sim.balls){ + balls.emplace_back(b); + } + + gl::enable_vertex_attribute_array(ball_shader.attribute_location("position")); + gl::vertex_attribute_pointer(ball_shader.attribute_location("position"), 3, GL_FLOAT, GL_FALSE, sizeof(BallQuad::Vertex), &balls[0].quad[0].x); + gl::enable_vertex_attribute_array(ball_shader.attribute_location("color")); + gl::vertex_attribute_pointer(ball_shader.attribute_location("color"), 3, GL_FLOAT, GL_FALSE, sizeof(BallQuad::Vertex), &balls[0].quad[0].r); + gl::enable_vertex_attribute_array(ball_shader.attribute_location("texture_coordinate")); + gl::vertex_attribute_pointer(ball_shader.attribute_location("texture_coordinate"), 2, GL_FLOAT, GL_FALSE, sizeof(BallQuad::Vertex), &balls[0].quad[0].s); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, ball_texture.get_id()); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + ball_shader.s.uniform("texture").set(0); + + gl::draw_arrays(GL_TRIANGLE_STRIP, 0, balls.size() * 6); + } + +} +} \ No newline at end of file diff --git a/src/client/GameRenderer.h b/src/client/GameRenderer.h new file mode 100644 index 0000000..e9b5c49 --- /dev/null +++ b/src/client/GameRenderer.h @@ -0,0 +1,70 @@ +#pragma once + +#include + +#include +#include + +#include "client_common.hpp" + +namespace games { +struct BallQuad { + struct Vertex{ + float x,y,z; + float r,g,b; + float s,t; + }; + + // degenerate + std::array quad; + BallQuad(ball_type const & b){ + quad = { + Vertex{b.position.x-hsize, b.position.y-hsize, 0.0f, 0.9f, 0.4f, 0.1f, 0.0f, 0.0f}, + Vertex{b.position.x-hsize, b.position.y-hsize, 0.0f, 0.9f, 0.4f, 0.1f, 0.0f, 0.0f}, + Vertex{b.position.x+hsize, b.position.y-hsize, 0.0f, 0.9f, 0.4f, 0.1f, 1.0f, 0.0f}, + Vertex{b.position.x-hsize, b.position.y+hsize, 0.0f, 0.9f, 0.4f, 0.1f, 0.0f, 1.0f}, + Vertex{b.position.x+hsize, b.position.y+hsize, 0.0f, 0.9f, 0.4f, 0.1f, 1.0f, 1.0f}, + Vertex{b.position.x+hsize, b.position.y+hsize, 0.0f, 0.9f, 0.4f, 0.1f, 1.0f, 1.0f}, + }; + } +}; + +struct Color { + float r,g,b; +}; + +struct LineVertex { + math::Vec2 position; + Color color; +}; + +struct Client; +struct GameRenderer { + std::vector lines; + std::vector balls; + + struct Shader{ + moggle::shader_program s; + std::vector a; + + GLuint attribute_location(std::string attribute) const { + GLuint c = 0; + for(auto str : a){ + if(str == attribute) break; + else ++c; + } + return c; + } + }; + Shader ball_shader; + Shader line_shader; + Shader note_shader; + motor::Texture ball_texture; + + bool debug_draw{false}; + + GameRenderer(); + + void draw(Client const & client); +}; +} \ No newline at end of file diff --git a/src/client/client.cpp b/src/client/client.cpp index 6aa6c61..dc99c21 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -148,6 +148,7 @@ namespace games { void Client::draw(){ Base::draw(); + game_renderer.draw(*this); } void Client::update(float const dt, Input input){ @@ -158,6 +159,10 @@ namespace games { scene->camera.set_position({0, 0, 20}); // simulation + for(auto l : lines){ + l->update(dt); + } + for(auto x : sim.update(dt)){ x.line.information->play(); } diff --git a/src/client/client.hpp b/src/client/client.hpp index a41b98f..14ee4bf 100644 --- a/src/client/client.hpp +++ b/src/client/client.hpp @@ -13,6 +13,7 @@ #include "../input.hpp" #include "client_common.hpp" +#include "GameRenderer.h" namespace games { @@ -46,6 +47,9 @@ namespace games { std::vector::const_iterator current_scale{scales.begin()}; Scale scale; + // Graphics + GameRenderer game_renderer; + // Base part Client(int window_width, int window_height, std::shared_ptr& active_base); diff --git a/src/client/client_common.hpp b/src/client/client_common.hpp index 2d6a8bc..a35d923 100644 --- a/src/client/client_common.hpp +++ b/src/client/client_common.hpp @@ -1,5 +1,7 @@ #pragma once +#include + #include #include "../../../beats-server/src/basics.h" #include "../../../beats-server/src/adaptions.h" @@ -13,7 +15,7 @@ using LineKind = simulation::LineKind; struct Instrument; using ball_info = int; -using line_info = Instrument const *; +using line_info = Instrument *; using ball_type = simulation::Ball; using line_type = simulation::Line; using simu_type = simulation::Simulation; @@ -31,6 +33,7 @@ struct Instrument { math::Vec2 end_point; int line_kind; + float color_intensity{0.0}; Instrument() = default; @@ -41,7 +44,7 @@ struct Instrument { {} // create 6 lines, to emulate width, and rounded edges - std::vector calculate_lines() const { + std::vector calculate_lines() { auto dir = normalize(end_point - starting_point); auto normal = rotate_ccw(dir); LineKind lk = static_cast(line_kind); @@ -67,8 +70,13 @@ struct Instrument { return d.sqr_length(); } - void play() const { + void play() { sound->play(); + color_intensity += 1.0; + } + + void update(float dt){ + color_intensity *= std::pow(0.15, dt); } };