mirror of
https://github.com/GayPizzaSpecifications/padlab.git
synced 2025-08-03 21:21:33 +00:00
It's also now no longer possible to trigger NW & SE angles when digital is set to 4 direction.
214 lines
5.2 KiB
C
214 lines
5.2 KiB
C
#include "draw.h"
|
|
#include "maths.h"
|
|
#include <SDL_video.h>
|
|
#include <SDL_opengl.h>
|
|
#include <stdbool.h>
|
|
|
|
static SDL_GLContext* ctx = NULL;
|
|
static SDL_Window* window = NULL;
|
|
static uint32_t colour = 0x00000000;
|
|
static uint32_t clrColour = 0x00000000;
|
|
static double scaleWidth = 0.0;
|
|
static double scaleHeight = 0.0;
|
|
static bool antialias = false;
|
|
|
|
void DrawWindowHints(void)
|
|
{
|
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); // Enable MSAA
|
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8); // 8x MSAA
|
|
|
|
// Legacy OpenGL profile
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
|
|
}
|
|
|
|
int InitDraw(SDL_Window* w)
|
|
{
|
|
ctx = SDL_GL_CreateContext(w);
|
|
window = w;
|
|
if (ctx == NULL || window == NULL)
|
|
return -1;
|
|
|
|
SDL_GL_SetSwapInterval(1); // Enable vsync
|
|
|
|
// Detect if MSAA is available & active
|
|
int res;
|
|
if (SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &res) == 0 && res == 1)
|
|
if (SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &res) == 0 && res > 0)
|
|
antialias = true;
|
|
|
|
// Disable depth test & culling, enable MSAA
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_CULL_FACE);
|
|
glEnable(GL_MULTISAMPLE);
|
|
|
|
SetDrawViewport(GetDrawSizeInPixels()); // Fills scaleWidth & scaleHeight
|
|
|
|
glLineWidth(2.0f);
|
|
|
|
// Setup orthographic viewport
|
|
glMatrixMode(GL_PROJECTION);
|
|
glOrtho(0.0, 1.0f, 1.0f, 0.0, 1.0, -1.0);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
|
|
return 0;
|
|
}
|
|
|
|
void QuitDraw(void)
|
|
{
|
|
SDL_GL_DeleteContext(ctx);
|
|
ctx = NULL;
|
|
window = NULL;
|
|
}
|
|
|
|
|
|
size GetDrawSizeInPixels(void)
|
|
{
|
|
size out;
|
|
SDL_GL_GetDrawableSize(SDL_GL_GetCurrentWindow(), &out.w, &out.h);
|
|
return out;
|
|
}
|
|
|
|
void SetDrawViewport(size size)
|
|
{
|
|
glViewport(0, 0, size.w, size.h);
|
|
scaleWidth = 1.0 / (double)size.w;
|
|
scaleHeight = 1.0 / (double)size.h;
|
|
}
|
|
|
|
|
|
void SetDrawColour(uint32_t c)
|
|
{
|
|
colour = c;
|
|
}
|
|
|
|
void DrawClear(void)
|
|
{
|
|
if (clrColour != colour)
|
|
{
|
|
const float mul = 1.0f / 255.0f;
|
|
glClearColor(
|
|
(GLclampf)((colour & 0xFF000000) >> 24) * mul,
|
|
(GLclampf)((colour & 0x00FF0000) >> 16) * mul,
|
|
(GLclampf)((colour & 0x0000FF00) >> 8) * mul,
|
|
(GLclampf)((colour & 0x000000FF)) * mul);
|
|
clrColour = colour;
|
|
}
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
}
|
|
|
|
static inline void GlColour(void)
|
|
{
|
|
const float mul = 1.0f / 255.0f;
|
|
glColor4f(
|
|
(GLclampf)((colour & 0xFF000000) >> 24) * mul,
|
|
(GLclampf)((colour & 0x00FF0000) >> 16) * mul,
|
|
(GLclampf)((colour & 0x0000FF00) >> 8) * mul,
|
|
(GLclampf)((colour & 0x000000FF)) * mul);
|
|
}
|
|
|
|
void DrawPoint(int x, int y)
|
|
{
|
|
const double fx = ((double)x) * scaleWidth;
|
|
const double fy = ((double)y) * scaleHeight;
|
|
|
|
glBegin(GL_POINTS);
|
|
GlColour();
|
|
glVertex2d(fx, fy);
|
|
glEnd();
|
|
}
|
|
|
|
void DrawRect(int x, int y, int w, int h)
|
|
{
|
|
const double fx = (double)x * scaleWidth;
|
|
const double fy = (double)y * scaleHeight;
|
|
const double fw = (double)w * scaleWidth;
|
|
const double fh = (double)h * scaleHeight;
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
GlColour();
|
|
glVertex2d(fx, fy);
|
|
glVertex2d(fx + fw, fy);
|
|
glVertex2d(fx + fw, fy + fh);
|
|
glVertex2d(fx, fy + fh);
|
|
glEnd();
|
|
}
|
|
|
|
void DrawLine(int x1, int y1, int x2, int y2)
|
|
{
|
|
const double fx1 = (double)x1 * scaleWidth;
|
|
const double fy1 = (double)y1 * scaleHeight;
|
|
const double fx2 = (double)x2 * scaleWidth;
|
|
const double fy2 = (double)y2 * scaleHeight;
|
|
|
|
glBegin(GL_LINES);
|
|
GlColour();
|
|
glVertex2d(fx1, fy1);
|
|
glVertex2d(fx2, fy2);
|
|
glEnd();
|
|
}
|
|
|
|
void DrawCircle(int x, int y, int r)
|
|
{
|
|
DrawCircleSteps(x, y, r, (int)(sqrt((double)r) * 8.0));
|
|
}
|
|
|
|
void DrawCircleSteps(int x, int y, int r, int steps)
|
|
{
|
|
// Circles look better when offset negatively by half a pixel w/o MSAA
|
|
const double fx = (antialias ? (double)x : (double)x - 0.5f) * scaleWidth;
|
|
const double fy = (antialias ? (double)y : (double)y - 0.5f) * scaleHeight;
|
|
|
|
const double stepsz = (double)TAU / (double)steps;
|
|
const double magw = (double)r * scaleWidth;
|
|
const double magh = (double)r * scaleHeight;
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
GlColour();
|
|
glVertex2d(fx + magw, fy);
|
|
for (int i = 1; i < steps; ++i)
|
|
{
|
|
const double theta = stepsz * (double)i;
|
|
double ofsx = cos(theta) * magw;
|
|
double ofsy = sin(theta) * magh;
|
|
glVertex2d(fx + ofsx, fy - ofsy);
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
void DrawArc(int x, int y, int r, int startAng, int endAng)
|
|
{
|
|
const int steps = (int)(sqrt((double)r) * (double)abs(endAng - startAng) / 360.0 * 8.0);
|
|
DrawArcSteps(x, y, r, startAng, endAng, steps);
|
|
}
|
|
|
|
void DrawArcSteps(int x, int y, int r, int startAng, int endAng, int steps)
|
|
{
|
|
// Arcs look better when offset negatively by half a pixel w/o MSAA
|
|
const double fx = (antialias ? (double)x : (double)x - 0.5f) * scaleWidth;
|
|
const double fy = (antialias ? (double)y : (double)y - 0.5f) * scaleHeight;
|
|
|
|
const double magw = (double)r * scaleWidth;
|
|
const double magh = (double)r * scaleHeight;
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
GlColour();
|
|
const double fstart = (double)startAng * DEG2RAD;
|
|
const double fstepSz = (double)(endAng - startAng) / abs(steps) * DEG2RAD;
|
|
for (int i = 0; i <= steps; ++i)
|
|
{
|
|
const double theta = fstart + fstepSz * (double)i;
|
|
double ofsx = cos(theta) * magw;
|
|
double ofsy = sin(theta) * magh;
|
|
glVertex2d(fx + ofsx, fy - ofsy);
|
|
}
|
|
glEnd();
|
|
}
|
|
|
|
void DrawPresent(void)
|
|
{
|
|
SDL_GL_SwapWindow(window);
|
|
}
|