#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;
float _frameRate = 60.0f;
float deltaTime = 0.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;
std::string g_sketchName = "Sketch";
// Read sketch name from environment (set by CppRunner at runtime)
static struct _SketchNameInit {
_SketchNameInit() {
const char* env = std::getenv("PROCESSING_SKETCH_NAME");
if (env && env[0]) g_sketchName = env;
}
} _sketchNameInit;
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<:pair>> shapeVerts; // 2D projections (for stroke outlines)
static std::vector<:array>> shapeVerts3D; // full 3D positions (for fill)
static std::vector<:pair>> 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