// // Drawer.cpp // OSXGLEssentials // // Created by Joshua Moerman on 10/03/14. // // #include "Drawer.h" #include #include 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 mvp = projection * transformation_matrices::translate(-camera); program.use(); program.uniform>("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"); }