#include "Processing.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // stb_image.h must be in the src/ folder for loadImage() to work. // Download from: https://github.com/nothings/stb/blob/master/stb_image.h #ifdef PROCESSING_HAS_STB_IMAGE #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" #endif // Uncomment + drop stb_image_write.h to enable saveFrame()/save(): // #define STB_IMAGE_WRITE_IMPLEMENTATION // #include "stb_image_write.h" // ── Manual glu replacements (no GLU header needed) ─────────────────────────── static void _gluPerspective(double fovY_deg, double aspect, double zNear, double zFar) { // Identical to gluPerspective -- sets up a perspective projection matrix double f = 1.0 / std::tan(fovY_deg * M_PI / 360.0); double m[16] = {0}; m[0] = f / aspect; m[5] = f; m[10] = (zFar + zNear) / (zNear - zFar); m[11] = -1.0; m[14] = (2.0 * zFar * zNear) / (zNear - zFar); glMultMatrixd(m); } static void _gluLookAt(double ex,double ey,double ez, double cx,double cy,double cz, double ux,double uy,double uz) { // Identical to gluLookAt double fx=cx-ex, fy=cy-ey, fz=cz-ez; double len=std::sqrt(fx*fx+fy*fy+fz*fz); fx/=len;fy/=len;fz/=len; double rx=fy*uz-fz*uy, ry=fz*ux-fx*uz, rz=fx*uy-fy*ux; len=std::sqrt(rx*rx+ry*ry+rz*rz); rx/=len;ry/=len;rz/=len; double upx=ry*fz-rz*fy, upy=rz*fx-rx*fz, upz=rx*fy-ry*fx; double m[16]={ rx, upx, -fx, 0, ry, upy, -fy, 0, rz, upz, -fz, 0, 0, 0, 0, 1 }; glMultMatrixd(m); glTranslated(-ex,-ey,-ez); } // stb_truetype -- drop stb_truetype.h next to this file for TTF font rendering. // default.ttf in the project root is loaded automatically as the default font. #if __has_include("stb_truetype.h") # define STB_TRUETYPE_IMPLEMENTATION # include "stb_truetype.h" # define PROCESSING_HAS_STB_TRUETYPE 1 #else # define PROCESSING_HAS_STB_TRUETYPE 0 #endif namespace Processing { // ============================================================================= // STATE // ============================================================================= // Window / canvas size int winWidth = 640, winHeight = 480; // current window size (updated by size()) int logicalW = 640, logicalH = 480; // sketch's coordinate space (from size()) static int fbW = 640, fbH = 480; // actual framebuffer (may be 2× on HiDPI) int displayWidth = 0, displayHeight = 0; int pixelWidth = 0, pixelHeight = 0; int pixelDensityValue = 1; bool isResizable = false; bool focused = false; // Mouse state float mouseX = 0, mouseY = 0, pmouseX = 0, pmouseY = 0; bool mouseInWindow = false; // true once cursor has entered the window bool _mousePressed = false; int mouseButton = -1; // Keyboard state bool _keyPressed = false; int keyCode = 0; char key = 0; // Frame timing int frameCount = 1; float currentFrameRate = 60.0f; bool looping = true; static bool redrawOnce = false; float measuredFrameRate = 0.0f; static double targetFrameTime = 1.0 / 60.0; // Current draw style float fillR = 1, fillG = 1, fillB = 1, fillA = 1; float strokeR = 0, strokeG = 0, strokeB = 0, strokeA = 1; float strokeW = 1; bool doFill = true, doStroke = true, smoothing = true; int currentRectMode = CORNER; int currentEllipseMode = CENTER; int currentImageMode = CORNER; float tintR = 1, tintG = 1, tintB = 1, tintA = 1; bool doTint = false; // Lighting state static float pendingSpecR = 0, pendingSpecG = 0, pendingSpecB = 0; // from lightSpecular() static float lightConcentration[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; // spotlight exponent static float lightCutoffCos[8] = { -1, -1, -1, -1, -1, -1, -1, -1 }; // cos(cutoff), -1 = no cone // Color mode int colorModeVal = RGB; float colorMaxH = 255.f, colorMaxS = 255.f, colorMaxB = 255.f, colorMaxA = 255.f; std::vector pixels; // User event callbacks std::function _onKeyPressed; std::function _onKeyReleased; std::function _onKeyTyped; std::function _onMousePressed; std::function _onMouseReleased; std::function _onMouseClicked; std::function _onMouseMoved; std::function _onMouseDragged; std::function _onMouseWheel; std::function _onWindowMoved; std::function _onWindowResized; // On Windows: IDE.cpp stores a raw function pointer here before static init // of Processing.cpp completes. Raw function pointers are POD -- zero-initialized // at program start before ANY constructor runs, so this is always safe to write. void (*_wireCallbacksFn)() = nullptr; void (*_staticSketchSetup)() = nullptr; // set by static sketches for i3 redraw static GLFWwindow* gWindow=nullptr; static bool is3DMode=false; static int sphereRes=48; static int curveDetailVal=20; static float curveTightnessVal=0.0f; static int bezierDetailVal=60; static bool lightsEnabled=false; static int lightIndex=0; // Shape state static int shapeKind=-1; static bool inShape=false,inContour=false; static bool shape3D=false; static std::vector> shapeVerts; // 2D projections (for stroke outlines) static std::vector> shapeVerts3D; // full 3D positions (for fill) static std::vector> contourVerts; // Style stack struct Style { float fillR, fillG, fillB, fillA; float strokeR, strokeG, strokeB, strokeA, strokeW; bool doFill, doStroke; int rectMode, ellipseMode, imageMode; float tintR, tintG, tintB, tintA; bool doTint; int colorMode; float cmH, cmS, cmB, cmA; }; static std::vector