You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
5.0 KiB
156 lines
5.0 KiB
//
|
|
// Drawer.cpp
|
|
// OSXGLEssentials
|
|
//
|
|
// Created by Joshua Moerman on 10/03/14.
|
|
//
|
|
//
|
|
|
|
#include "Drawer.h"
|
|
|
|
#include <moggle/math/projection.hpp>
|
|
#include <moggle/math/transformation.hpp>
|
|
|
|
using namespace moggle;
|
|
|
|
// We need to pass relative addresses to opengl
|
|
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
|
|
|
|
// We may assume this at some point
|
|
static_assert(sizeof(Vertex) == 6*4, "wrong size");
|
|
|
|
// Circles
|
|
static constexpr size_t circleVertices = 13;
|
|
static const Vertex::Position (&getCircle())[circleVertices]{
|
|
static Vertex::Position vertices[circleVertices];
|
|
static bool shouldInit = true;
|
|
if(shouldInit){
|
|
for(int i = 0; i < circleVertices;++i){
|
|
auto phi = 2 * i / double(circleVertices-1) * M_PI;
|
|
vertices[i] = {cos(phi), -sin(phi)};
|
|
}
|
|
shouldInit = false;
|
|
}
|
|
return vertices;
|
|
}
|
|
|
|
static const float viewSize = 20.0;
|
|
|
|
#if TARGET_OS_IPHONE
|
|
static const char * file = "/plain-iOS";
|
|
#else
|
|
static const char * file = "/plain";
|
|
#endif
|
|
|
|
// Implementation
|
|
Drawer::Drawer(std::string const & bundle){
|
|
gl::enable(GL_BLEND);
|
|
gl::blend_function(GL_SRC_ALPHA, GL_ONE);
|
|
|
|
gl::clear_color(0.2f, 0.05f, 0.05f, 1.0f);
|
|
|
|
projection = projection_matrices::orthographic(-viewSize, viewSize, -viewSize, viewSize, -1, 1);
|
|
|
|
auto vertex = shader::from_file(shader_type::vertex, bundle + file + ".vsh");
|
|
auto fragment = shader::from_file(shader_type::fragment, bundle + file + ".fsh");
|
|
|
|
program.attach(vertex);
|
|
program.attach(fragment);
|
|
|
|
program.bind_attribute(0, "position");
|
|
program.bind_attribute(1, "color");
|
|
|
|
program.link();
|
|
|
|
gl::generate_vertex_arrays(1, &vao);
|
|
gl::bind_vertex_array(vao);
|
|
|
|
gl::generate_buffers(1, &buf);
|
|
gl::bind_buffer(GL_ARRAY_BUFFER, buf);
|
|
}
|
|
|
|
void Drawer::draw(){
|
|
// bug when going to fullscreen
|
|
// possibly related http://lists.apple.com/archives/mac-opengl/2012/Jul/msg00041.html
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
if(glGetError() != GL_NO_ERROR) return;
|
|
|
|
matrix4<float> mvp = projection * transformation_matrices::translate(-camera);
|
|
|
|
program.use();
|
|
program.uniform<matrix4<float>>("mvp").set(mvp);
|
|
|
|
if(!segments.empty()){
|
|
if(verbose) printf("drawing %lu objects and %lu segments\n", sizes.size(), segments.size());
|
|
|
|
gl::bind_vertex_array(vao);
|
|
gl::bind_buffer(GL_ARRAY_BUFFER, buf);
|
|
gl::buffer_data(GL_ARRAY_BUFFER, sizeof(Vertex) * segments.size(), &segments[0], GL_STATIC_DRAW);
|
|
|
|
gl::enable_vertex_attribute_array(0);
|
|
gl::enable_vertex_attribute_array(1);
|
|
gl::vertex_attribute_pointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(0));
|
|
gl::vertex_attribute_pointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), BUFFER_OFFSET(3*4));
|
|
|
|
GLuint start = 0;
|
|
for(auto&& s : sizes){
|
|
gl::draw_arrays(GL_LINE_LOOP, start, s);
|
|
start += s;
|
|
}
|
|
}
|
|
}
|
|
|
|
void Drawer::clear(){
|
|
sizes.clear();
|
|
segments.clear();
|
|
}
|
|
|
|
void Drawer::resize(float width, float height){
|
|
auto aspect = width / height;
|
|
auto hheight = viewSize;
|
|
projection = projection_matrices::orthographic(-hheight * aspect, hheight * aspect, -hheight, hheight, -5, 5);
|
|
}
|
|
|
|
void Drawer::DrawPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color){
|
|
if(verbose) printf("polygon (not solid)\n %d vertices\n %f %f %f\n", vertexCount, color.r, color.g, color.b);
|
|
for(int i = 0; i < vertexCount; ++i){
|
|
segments.push_back(Vertex{convert(vertices[i]), convert(color)});
|
|
}
|
|
sizes.emplace_back(vertexCount);
|
|
}
|
|
|
|
void Drawer::DrawSolidPolygon(const b2Vec2* vertices, int32 vertexCount, const b2Color& color){
|
|
if(verbose) printf("polygon (solid, deferred)\n");
|
|
DrawPolygon(vertices, vertexCount, color);
|
|
}
|
|
|
|
void Drawer::DrawCircle(const b2Vec2& center, float32 radius, const b2Color& color){
|
|
if(verbose) printf("circle (not solid)\n at %f %f (%f)\n %f %f %f\n", center.x, center.y, radius, color.r, color.g, color.b);
|
|
for(auto&& p : getCircle()){
|
|
segments.push_back(Vertex{convert(center) + radius * p, convert(color)});
|
|
}
|
|
sizes.emplace_back(circleVertices);
|
|
}
|
|
|
|
void Drawer::DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color){
|
|
if(verbose) printf("circle (solid, deferred)\n");
|
|
segments.push_back(Vertex{convert(center) - radius * convert(axis), convert(color)});
|
|
segments.push_back(Vertex{convert(center) + radius * convert(axis), convert(color)});
|
|
sizes.push_back(2);
|
|
DrawCircle(center, radius, color);
|
|
}
|
|
|
|
void Drawer::DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color){
|
|
if(verbose) printf("segment\n %f %f -> %f %f\n %f %f %f\n", p1.x, p1.y, p2.x, p2.y, color.r, color.g, color.b);
|
|
segments.push_back(Vertex{convert(p1), convert(color)});
|
|
segments.push_back(Vertex{convert(p2), convert(color)});
|
|
sizes.emplace_back(2);
|
|
}
|
|
|
|
void Drawer::DrawTransform(const b2Transform& xf){
|
|
if(verbose) printf("transform\n");
|
|
}
|
|
|
|
|
|
|
|
|
|
|