#include #include #include #include #include using J3ML::LinearAlgebra::Vector2; using namespace JGL; JGL::Font FreeSans; JGL::Font Jupiteroid; class Gizmo { public: Gizmo() {} Gizmo(const Vector2& pos) : position(pos) {} bool dragging = false; bool hovered = false; Vector2 position; float range = 6.f; void Grab() { if (hovered) dragging = true; } void Release() { dragging = false; } void Update(const Vector2& mouse) { if (dragging) position = position.Lerp(mouse, 0.25f); hovered = mouse.Distance(position) < range; } void Draw() { if (dragging) J2D::DrawPoint(Colors::White, position, 4.f); else if (hovered) J2D::DrawPoint(Colors::Reds::Crimson, position, 6.f); else J2D::DrawPoint(Colors::Reds::Salmon, position, 3.f); J2D::DrawString(Colors::White, std::format("{:.1f},{:.1f}", position.x, position.y), position.x, position.y, 1.f, 10, FreeSans); } }; class Camera { public: Vector3 position = {0,0,0}; Vector3 angle = {0,0,0}; std::vector lookAt(const Vector3& eye, const Vector3& center, const Vector3& up) { Vector3 f = Vector3::Normalized((center - eye)); Vector3 upN = Vector3::Normalized(up); Vector3 s = Vector3::Normalized(f.Cross(upN)); Vector3 u = Vector3::Normalized(s.Cross(f)); std::vector result = { s.x, u.x, -f.x, 0.0f, s.y, u.y, -f.y, 0.0f, s.z, u.z, -f.z, 0.0f, -s.Dot(eye), -u.Dot(eye), f.Dot(eye), 1.0f }; return result; } void render() { glRotatef(angle.x,1.0f, 0.0f, 0.0f); glRotatef(angle.y,0.0f, 1.0f, 0.0f); glRotatef(angle.z,0.0f, 0.0f, 1.0f); glMultMatrixf(lookAt({position.x, position.y, position.z}, {position.x, position.y, 100.f + position.z}, {0,1,0}).data()); } }; Camera* camera; using J3ML::LinearAlgebra::Matrix4x4; struct point { GLfloat x; GLfloat y; GLfloat s; GLfloat t; }; Gizmo a({250, 150}); Gizmo b({200, 250}); Gizmo c({350, 300}); Gizmo d({450, 250}); Texture* image; RenderTarget* j2d_render_target; class JGLDemoWindow : public ReWindow::RWindow { public: void initGL() { camera = new Camera; gladLoadGL(); JGL::InitTextEngine(); JGL::Update(getSize()); J3D::Init(getSize(), 90, 100); FreeSans = JGL::Font("assets/fonts/FreeSans.ttf"); Jupiteroid = JGL::Font("assets/fonts/Jupiteroid.ttf"); glClearColor(0.f, 0.f, 0.f, 0.f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glDepthMask(GL_TRUE); image = new Texture("assets/sprites/Re3D.png", TextureFilteringMode::BILINEAR); j2d_render_target = new RenderTarget({500, 500}, {255,0,0,0}); } Vector3 textAngle = {0,0,0}; float fov = 90; float sprite_radians = 0; bool fov_increasing = true; unsigned long long frames = 0; bool framerate_measurement = false; std::chrono::system_clock::time_point start; float elapsed = 0.0f; void display() { if (framerate_measurement) start = std::chrono::high_resolution_clock::now(); JGL::Update(getSize()); if (fov_increasing) fov += 0.25; else fov -= 0.50; if (fov >= 120) fov_increasing = false; else if (fov <= 75) fov_increasing = true; J3D::ChangeFOV(fov); sprite_radians += 0.05; textAngle.y += 2.0f; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); camera->render(); // All 3D elements of the scene and JGL elements *must* be rendered before the 2D stuff /* if rendering to screen space directly. */ J3D::Begin(); J3D::DrawLine(Colors::Red, {-0.33,-0.125,1}, {-1,-0.125,1}); J3D::DrawLine(Colors::Red, {-0.33,-0.125,1}, {-0.33,0.25,1}); J3D::DrawString(Colors::Red, "JGL Sample Text", {-0.33, -0.1, 1.0f}, 1.f, 32, FreeSans, textAngle, true); J3D::End(); J2D::Begin(j2d_render_target, true); J2D::FillRect(Colors::Blue, {0,52}, {100,100}); J2D::DrawMirrorSprite(*image, {400, 300}, Direction::Horizontal | Direction::Vertical, sprite_radians, {0.5,0.5}, {1, 1}, Colors::White); J2D::DrawPartialSprite(*image, {225, 300}, image->GetDimensions() * 0.25, image->GetDimensions() * 0.75, sprite_radians, {0.5, 0.5}); J2D::FillRect(Colors::Pinks::HotPink, {68, 120}, {32, 32}); J2D::FillGradientRect(Colors::Red, Colors::Blue, Direction::Diagonal_SWNE, {100,52}, {100,100}); J2D::FillRoundedRect(Colors::Red, {200, 52}, {100, 100}, 8, 8); J2D::FillRoundedRect(Colors::Purples::BlueViolet, {300, 52}, {100, 100}, 8, 4); J2D::FillCircle(Colors::White, {52, 204}, 50, 24); J2D::OutlineCircle(Colors::White, {153, 204}, 50, 24); J2D::FillGradientTriangle(Color4(Colors::Red), Color4(Colors::Green), Color4(Colors::Blue), {{0, 275}, {0, 375}, {100, 375}}); J2D::OutlineTriangle(Colors::Blue, {{100, 275}, {0, 275}, {100, 375}}); J2D::DrawGradientLine(Colors::Red, Colors::Blue, {105, 375}, {200, 275}, 2); auto result = Jupiteroid.MeasureString("Jupiteroid Font", 16); J2D::FillRect(Colors::Gray, {0, 0}, result); J2D::DrawString(Colors::Green, "Jupteroid Font", 0.f, 0, 1.f, 16, Jupiteroid); J2D::DrawString(Colors::White, "Position: " + std::to_string(camera->position.x) + " " + std::to_string(camera->position.y) + " " + std::to_string(camera->position.z), 0, 16, 1,16, Jupiteroid); J2D::DrawString(Colors::White, "ViewAngle: " + std::to_string(camera->angle.x) + " " + std::to_string(camera->angle.y) + " " + std::to_string(camera->angle.z), 0, 33, 1,16, Jupiteroid); J2D::OutlinePolygon(Colors::White, {{200, 400}, {220, 420}, {220, 430}, {230, 410}, {200, 400}}); //J2D::FillPolygon(Colors::White, {{200, 400}, {220, 420}, {220, 430}, {230, 410}, {200, 400}}); J2D::DrawCubicBezierCurve(Colors::Blues::CornflowerBlue, a.position, b.position, c.position, d.position , 20, 1.5f); a.Draw(); b.Draw(); c.Draw(); d.Draw(); J2D::End(); //Draw the Render Target that we just drew all that stuff onto. J2D::Begin(); J2D::DrawRenderTargetAsSprite(*j2d_render_target, {0, 0}, sprite_radians * 0.25, {0.5, 0.5}, {1,1}, Colors::White); J2D::End(); if (framerate_measurement) { frames++; std::chrono::system_clock::time_point stop = std::chrono::high_resolution_clock::now(); std::chrono::duration frame_time = stop - start; elapsed += frame_time.count(); if (elapsed >= 1) std::cout << "Framerate: " << frames << std::endl, frames = 0, elapsed = 0, framerate_measurement = false, setVsyncEnabled(true); } else if (isKeyDown(Keys::One)) framerate_measurement = true, frames = 0, setVsyncEnabled(false); } void OnRefresh(float elapsed) override { auto mouse = GetMouseCoordinates(); a.Update(mouse); b.Update(mouse); c.Update(mouse); d.Update(mouse); display(); int glError = glGetError(); if (glError != GL_NO_ERROR) std::cout << glError << std::endl; glSwapBuffers(); } void OnMouseButtonDown(const ReWindow::WindowEvents::MouseButtonDownEvent & ev) override { RWindow::OnMouseButtonDown(ev); a.Grab(); b.Grab(); c.Grab(); d.Grab(); } void OnMouseButtonUp(const ReWindow::WindowEvents::MouseButtonUpEvent & ev) override { RWindow::OnMouseButtonUp(ev); a.Release(); b.Release(); c.Release(); d.Release(); } bool OnResizeRequest(const ReWindow::WindowResizeRequestEvent& e) override {return true;} JGLDemoWindow() : ReWindow::RWindow() {} JGLDemoWindow(const std::string& title, int width, int height) : ReWindow::RWindow(title, width, height){} }; int main(int argc, char** argv) { auto* window = new JGLDemoWindow("JGL Demo Window", 1280, 720); window->setRenderer(RenderingAPI::OPENGL); window->Open(); window->initGL(); window->setResizable(true); window->setVsyncEnabled(true); while (window->isAlive()) { window->pollEvents(); window->refresh(); } return 0; }