#include #include #include #include #include #include #include #include using J3ML::LinearAlgebra::Vector2; using namespace JGL::Fonts; using namespace JGL; float fps = 0.0f; /// A draggable 2D point that highlights when moused over and when clicked. class Gizmo { public: Gizmo() {} Gizmo(const Vector2& pos) : position(pos) {} bool dragging = false; bool hovered = false; Vector2 position; float range = 6.f; float base_radius = 3.f; float hover_radius = 6.f; float drag_radius = 4.f; Color4 base_color = Colors::Reds::Salmon; Color4 hover_color = Colors::Reds::Firebrick; Color4 drag_color = Colors::White; float lerp_rate = 0.25f; float text_scale = 1.f; int text_size = 12; void Grab() { if (hovered) dragging = true; } void Release() { dragging = false; } void Update(const Vector2& mouse) { if (dragging) position = position.Lerp(mouse, lerp_rate); hovered = mouse.Distance(position) < range; } void Draw() { if (dragging) J2D::DrawPoint(drag_color, position, drag_radius); else if (hovered) J2D::DrawPoint(hover_color, position, hover_radius); else J2D::DrawPoint(base_color, position, base_radius); J2D::DrawString(Colors::White, std::format("{:.1f},{:.1f}", position.x, position.y), position.x, position.y, text_scale, text_size); } }; /// A 3D Camera Controller. 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}); JGL::Font FreeSans; Texture* image; Texture* image_mask; RenderTarget* j2d_render_target; class JGLDemoWindow : public ReWindow::RWindow { public: void initGL() { camera = new Camera; if (!JGL::Init(GetSize(), 75, 100)) Logger::Fatal("Initialization failed."); // Load a custom font. FreeSans = JGL::Font("assets/fonts/FreeSans.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); image_mask = new Texture("assets/sprites/alpha_mask_2.png"); j2d_render_target = new RenderTarget({540, 540}, {0,0,0,0}, false, MSAA_SAMPLE_RATE::MSAA_NONE); //Texture::MultiplyByAlphaMask(*image, *image_mask); } EulerAngleXYZ textAngle = {0,0,0}; float fov = 90; float sprite_radians = 0; bool fov_increasing = true; int blit_pos = 0; void display() { float dt = GetDeltaTime(); JGL::Update(GetSize()); if (fov_increasing) fov += 0.025; else fov -= 0.050; if (fov >= 120) fov_increasing = false; else if (fov <= 75) fov_increasing = true; //J3D::ChangeFOV(fov); sprite_radians += 0.005; textAngle.yaw += 1; 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. */ // If a 3D object has transparency. The things you'd like to see through it must be drawn before. 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::WireframeSphere(Colors::Green, {0,0,0.5f}, 0.25f, 1, 128, 128); Sphere sphere = {{0,0, 0.5f}, 0.2125}; J3D::BatchWireframeRevoSphere(Colors::Green, &sphere, 1, 1, 16, 16, true); J3D::FillAABB(Colors::Whites::AliceBlue, {0,0,0.5f}, {0.1f, 0.1f, 0.1f}); J3D::WireframeAABB(Colors::Gray, {0,0,0.5f}, {0.11f, 0.06f, 0.11f}); AABB boxes[1] = {{Vector3(-0.2125, -0.2125,0.28750), Vector3(0.2125,0.2125,0.7125)}}; J3D::BatchWireframeAABB(Colors::Yellow, boxes, 1, 1); //J3D::WireframeOBB(Colors::Red, {0, 0, 1.5f}, {0.40f, 0.10f, 0.10f}, {0,textAngle.y, 0}); //J3D::FillSphere({0,255,0,120}, sphere); //J3D::DrawCubicBezierCurve(Colors::Blue, {0,0,0.3}, {0,0,0.5}, {0.2,0,0.3}, {0.2, 0.3, 0.1}, 30); //J3D::WireframeIcosahedron(Colors::Green, {0,0,0.5f}, 0.125f, 1.f); J3D::End(); J2D::Begin(j2d_render_target, true); J2D::FillRect(Colors::Blue, {0,52}, {100,100}); J2D::DrawSprite(image, {300, 400}, sprite_radians * 0.10f, {0.5,0.5}, {1, 1}, Colors::White); 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}, {1,1}, Colors::White); 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::FillChamferRect(Colors::Reds::LightSalmon, {150, 400}, {64, 64}, 5); J2D::OutlineRoundedRect(Colors::Reds::LightCoral, {250, 350}, {128, 128}, 10, 2); std::vector points = {{1,1}, {4,4}, {8,8}, {16,16}, {32,32}}; 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::DrawString(Colors::White, "Framerate: " + std::to_string((int) fps), 0, 48, 1, 16, Jupiteroid); std::array polygon = {Vector2(200, 400), {220, 420}, {220, 430}, {230, 410}, {200, 400}}; J2D::OutlinePolygon(Colors::White, polygon.data(), polygon.size()); //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(); RenderTarget::Blit(Colors::Red, {0, 0}, j2d_render_target); //Draw the Render Target that we just drew all that stuff onto. J2D::Begin(); J2D::DrawPartialRenderTarget(j2d_render_target, {0, 0}, {0,0}, {512, 512}); J2D::DrawSprite(image, image_mask, {0, 0}, 0.25, {0.5, 0.5}, {1,1}); //J2D::DrawSprite(, {0, 0}, 0, {0.5, 0.5}, {1,1}, Colors::White); //J2D::DrawSprite( {0, 0}, 0, {0.5, 0.5}, {1,1}, Colors::White); J2D::End(); } void OnRefresh(float elapsed) override { fps = GetRefreshRate(); if (IsKeyDown(Keys::RightArrow)) camera->angle.y += 45.f * elapsed; if (IsKeyDown(Keys::LeftArrow)) camera->angle.y -= 45.f * elapsed; if (IsKeyDown(Keys::UpArrow)) camera->angle.x -= 45.f * elapsed; if (IsKeyDown(Keys::DownArrow)) camera->angle.x += 45.f * elapsed; if (IsKeyDown(Keys::Space)) camera->position.y += 1.f * elapsed; if (IsKeyDown(Keys::LeftShift)) camera->position.y -= 1.f * elapsed; //This is wrong of course. Just for testing purposes. if (IsKeyDown(Keys::W)) camera->position.z += 1.f * elapsed; if (IsKeyDown(Keys::S)) camera->position.z -= 1.f * elapsed; if (IsKeyDown(Keys::A)) camera->position.x += 1.f * elapsed; if (IsKeyDown(Keys::D)) camera->position.x -= 1.f * elapsed; 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::MouseButtonDownEvent & ev) override { RWindow::OnMouseButtonDown(ev); a.Grab(); b.Grab(); c.Grab(); d.Grab(); } void OnMouseButtonUp(const ReWindow::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(false); ReWindow::Logger::Error.EnableConsole(false); ReWindow::Logger::Warning.EnableConsole(false); ReWindow::Logger::Debug.EnableConsole(false); while (window->IsAlive()) window->ManagedRefresh(); return 0; }