Made a renderer
This commit is contained in:
parent
57b813ef57
commit
76e3b7854e
6 changed files with 235 additions and 4 deletions
|
@ -58,7 +58,7 @@ void Base::draw(){
|
||||||
try {
|
try {
|
||||||
fbo.unbind();
|
fbo.unbind();
|
||||||
moggle::gl::set_viewport(0, 0, window_width, window_height);
|
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::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
moggle::gl::enable(GL_DEPTH_TEST);
|
moggle::gl::enable(GL_DEPTH_TEST);
|
||||||
moggle::gl::enable(GL_BLEND);
|
moggle::gl::enable(GL_BLEND);
|
||||||
|
|
144
src/client/GameRenderer.cpp
Normal file
144
src/client/GameRenderer.cpp
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
#include "GameRenderer.h"
|
||||||
|
#include "client.hpp"
|
||||||
|
|
||||||
|
#include <moggle/math/projection.hpp>
|
||||||
|
|
||||||
|
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 <size_t N>
|
||||||
|
std::vector<std::string> from_strarray(const char* const (& strs)[N]) {
|
||||||
|
std::vector<std::string> 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<std::string> 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<matrix<float, 4>>("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<matrix<float, 4>>("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<matrix<float, 4>>("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<GLint>("texture").set(0);
|
||||||
|
|
||||||
|
gl::draw_arrays(GL_TRIANGLE_STRIP, 0, balls.size() * 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
70
src/client/GameRenderer.h
Normal file
70
src/client/GameRenderer.h
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <moggle/core/shader.hpp>
|
||||||
|
#include <motor/core/fbo.hpp>
|
||||||
|
|
||||||
|
#include "client_common.hpp"
|
||||||
|
|
||||||
|
namespace games {
|
||||||
|
struct BallQuad {
|
||||||
|
struct Vertex{
|
||||||
|
float x,y,z;
|
||||||
|
float r,g,b;
|
||||||
|
float s,t;
|
||||||
|
};
|
||||||
|
|
||||||
|
// degenerate
|
||||||
|
std::array<Vertex, 6> 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<LineVertex> lines;
|
||||||
|
std::vector<BallQuad> balls;
|
||||||
|
|
||||||
|
struct Shader{
|
||||||
|
moggle::shader_program s;
|
||||||
|
std::vector<std::string> 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);
|
||||||
|
};
|
||||||
|
}
|
|
@ -148,6 +148,7 @@ namespace games {
|
||||||
|
|
||||||
void Client::draw(){
|
void Client::draw(){
|
||||||
Base::draw();
|
Base::draw();
|
||||||
|
game_renderer.draw(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::update(float const dt, Input input){
|
void Client::update(float const dt, Input input){
|
||||||
|
@ -158,6 +159,10 @@ namespace games {
|
||||||
scene->camera.set_position({0, 0, 20});
|
scene->camera.set_position({0, 0, 20});
|
||||||
|
|
||||||
// simulation
|
// simulation
|
||||||
|
for(auto l : lines){
|
||||||
|
l->update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
for(auto x : sim.update(dt)){
|
for(auto x : sim.update(dt)){
|
||||||
x.line.information->play();
|
x.line.information->play();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "../input.hpp"
|
#include "../input.hpp"
|
||||||
|
|
||||||
#include "client_common.hpp"
|
#include "client_common.hpp"
|
||||||
|
#include "GameRenderer.h"
|
||||||
|
|
||||||
|
|
||||||
namespace games {
|
namespace games {
|
||||||
|
@ -46,6 +47,9 @@ namespace games {
|
||||||
std::vector<std::string>::const_iterator current_scale{scales.begin()};
|
std::vector<std::string>::const_iterator current_scale{scales.begin()};
|
||||||
Scale scale;
|
Scale scale;
|
||||||
|
|
||||||
|
// Graphics
|
||||||
|
GameRenderer game_renderer;
|
||||||
|
|
||||||
// Base part
|
// Base part
|
||||||
Client(int window_width, int window_height, std::shared_ptr<Base>& active_base);
|
Client(int window_width, int window_height, std::shared_ptr<Base>& active_base);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include <motor/sound/sound.hpp>
|
#include <motor/sound/sound.hpp>
|
||||||
#include "../../../beats-server/src/basics.h"
|
#include "../../../beats-server/src/basics.h"
|
||||||
#include "../../../beats-server/src/adaptions.h"
|
#include "../../../beats-server/src/adaptions.h"
|
||||||
|
@ -13,7 +15,7 @@ using LineKind = simulation::LineKind;
|
||||||
|
|
||||||
struct Instrument;
|
struct Instrument;
|
||||||
using ball_info = int;
|
using ball_info = int;
|
||||||
using line_info = Instrument const *;
|
using line_info = Instrument *;
|
||||||
using ball_type = simulation::Ball<ball_info>;
|
using ball_type = simulation::Ball<ball_info>;
|
||||||
using line_type = simulation::Line<line_info>;
|
using line_type = simulation::Line<line_info>;
|
||||||
using simu_type = simulation::Simulation<ball_info, line_info>;
|
using simu_type = simulation::Simulation<ball_info, line_info>;
|
||||||
|
@ -31,6 +33,7 @@ struct Instrument {
|
||||||
math::Vec2 end_point;
|
math::Vec2 end_point;
|
||||||
|
|
||||||
int line_kind;
|
int line_kind;
|
||||||
|
float color_intensity{0.0};
|
||||||
|
|
||||||
Instrument() = default;
|
Instrument() = default;
|
||||||
|
|
||||||
|
@ -41,7 +44,7 @@ struct Instrument {
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// create 6 lines, to emulate width, and rounded edges
|
// create 6 lines, to emulate width, and rounded edges
|
||||||
std::vector<line_type> calculate_lines() const {
|
std::vector<line_type> calculate_lines() {
|
||||||
auto dir = normalize(end_point - starting_point);
|
auto dir = normalize(end_point - starting_point);
|
||||||
auto normal = rotate_ccw(dir);
|
auto normal = rotate_ccw(dir);
|
||||||
LineKind lk = static_cast<LineKind>(line_kind);
|
LineKind lk = static_cast<LineKind>(line_kind);
|
||||||
|
@ -67,8 +70,13 @@ struct Instrument {
|
||||||
return d.sqr_length();
|
return d.sqr_length();
|
||||||
}
|
}
|
||||||
|
|
||||||
void play() const {
|
void play() {
|
||||||
sound->play();
|
sound->play();
|
||||||
|
color_intensity += 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(float dt){
|
||||||
|
color_intensity *= std::pow(0.15, dt);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Reference in a new issue