mirror of
https://git.coom.tech/drummyfish/small3dlib.git
synced 2024-11-21 20:39:57 +01:00
Fix L/R
This commit is contained in:
parent
1d52e3b516
commit
182ee3b65d
3 changed files with 70 additions and 33 deletions
8
make.sh
8
make.sh
|
@ -1,5 +1,9 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
PROGRAM=testSDL
|
clear; clear
|
||||||
|
|
||||||
clear; clear; g++ -x c -g -fmax-errors=5 -pedantic -Wall -Wextra -o $PROGRAM $PROGRAM.c -lSDL2 2>&1 >/dev/null && ./$PROGRAM
|
make
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
./PokittoEmu ./BUILD/firmware.bin $1
|
||||||
|
fi
|
||||||
|
|
66
s3l.h
66
s3l.h
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef int16_t S3L_UNIT;
|
typedef int16_t S3L_Unit;
|
||||||
#define S3L_FRACTIONS_PER_UNIT 1024
|
#define S3L_FRACTIONS_PER_UNIT 1024
|
||||||
typedef int16_t S3L_COORD;
|
typedef int16_t S3L_COORD;
|
||||||
|
|
||||||
|
@ -12,16 +12,27 @@ typedef struct
|
||||||
S3L_COORD x; ///< Screen X coordinate.
|
S3L_COORD x; ///< Screen X coordinate.
|
||||||
S3L_COORD y; ///< Screen Y coordinate.
|
S3L_COORD y; ///< Screen Y coordinate.
|
||||||
|
|
||||||
S3L_UNIT barycentric0; /**< Barycentric coord A (corresponds to 1st vertex).
|
S3L_Unit barycentric0; /**< Barycentric coord A (corresponds to 1st vertex).
|
||||||
Together with B and C coords these serve to
|
Together with B and C coords these serve to
|
||||||
locate the pixel on a triangle and interpolate
|
locate the pixel on a triangle and interpolate
|
||||||
values between it's three points. The sum of the
|
values between it's three points. The sum of the
|
||||||
three coordinates will always be exactly
|
three coordinates will always be exactly
|
||||||
S3L_FRACTIONS_PER_UNIT. */
|
S3L_FRACTIONS_PER_UNIT. */
|
||||||
S3L_UNIT barycentric1; ///< Baryc. coord B (corresponds to 2nd vertex).
|
S3L_Unit barycentric1; ///< Baryc. coord B (corresponds to 2nd vertex).
|
||||||
S3L_UNIT barycentric2; ///< Baryc. coord C (corresponds to 3rd vertex).
|
S3L_Unit barycentric2; ///< Baryc. coord C (corresponds to 3rd vertex).
|
||||||
} S3L_PixelInfo;
|
} S3L_PixelInfo;
|
||||||
|
|
||||||
|
#define S3L_BACKFACE_CULLING_NONE 0
|
||||||
|
#define S3L_BACKFACE_CULLING_CW 1
|
||||||
|
#define S3L_BACKFACE_CULLING_CCW 2
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int backfaceCulling;
|
||||||
|
} S3L_DrawConfig;
|
||||||
|
|
||||||
|
void S3L_PIXEL_FUNCTION(S3L_PixelInfo *pixel); // forward decl
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int16_t steps;
|
int16_t steps;
|
||||||
|
@ -52,6 +63,16 @@ static inline int16_t S3L_max(int16_t v1, int16_t v2)
|
||||||
return v1 >= v2 ? v1 : v2;
|
return v1 >= v2 ? v1 : v2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline S3L_Unit S3L_wrap(S3L_Unit value, S3L_Unit mod)
|
||||||
|
{
|
||||||
|
return value >= 0 ? (value % mod) : (mod + (value % mod) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline S3L_nonZero(S3L_Unit value)
|
||||||
|
{
|
||||||
|
return value != 0 ? value : 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Interpolated between two values, v1 and v2, in the same ratio as t is to
|
Interpolated between two values, v1 and v2, in the same ratio as t is to
|
||||||
tMax. Does NOT prevent zero division.
|
tMax. Does NOT prevent zero division.
|
||||||
|
@ -130,7 +151,7 @@ int S3L_bresenhamStep(S3L_BresenhamState *state)
|
||||||
return state->steps >= 0;
|
return state->steps >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void S3L_drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2)
|
void S3L_drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, S3L_DrawConfig config)
|
||||||
{
|
{
|
||||||
S3L_COORD
|
S3L_COORD
|
||||||
tPointX, tPointY, // top triangle point coords
|
tPointX, tPointY, // top triangle point coords
|
||||||
|
@ -143,14 +164,19 @@ void S3L_drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2
|
||||||
p.barycentric1 = 0;
|
p.barycentric1 = 0;
|
||||||
p.barycentric2 = 0;
|
p.barycentric2 = 0;
|
||||||
|
|
||||||
S3L_UNIT *barycentric0; // bar. coord that gets higher from L to R
|
S3L_Unit *barycentric0; // bar. coord that gets higher from L to R
|
||||||
S3L_UNIT *barycentric1; // bar. coord that gets higher from R to L
|
S3L_Unit *barycentric1; // bar. coord that gets higher from R to L
|
||||||
S3L_UNIT *barycentric2; // bar. coord that gets higher from bottom up
|
S3L_Unit *barycentric2; // bar. coord that gets higher from bottom up
|
||||||
|
|
||||||
// Sort the points.
|
// Sort the points.
|
||||||
|
|
||||||
#define handleLR(a,b)\
|
#define handleLR(t,a,b)\
|
||||||
if (x##a <= x##b)\
|
int16_t aDx = x##a - x##t;\
|
||||||
|
int16_t bDx = x##b - x##t;\
|
||||||
|
int16_t aDy = S3L_nonZero(y##a - y##t);\
|
||||||
|
int16_t bDy = S3L_nonZero(y##b - y##t);\
|
||||||
|
if ((aDx << 4) / aDy < (bDx << 4) / bDy)\
|
||||||
|
/*if (x##a <= x##b)*/\
|
||||||
{\
|
{\
|
||||||
lPointX = x##a; lPointY = y##a;\
|
lPointX = x##a; lPointY = y##a;\
|
||||||
rPointX = x##b; rPointY = y##b;\
|
rPointX = x##b; rPointY = y##b;\
|
||||||
|
@ -172,14 +198,14 @@ void S3L_drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2
|
||||||
tPointX = x0;
|
tPointX = x0;
|
||||||
tPointY = y0;
|
tPointY = y0;
|
||||||
barycentric2 = &p.barycentric0;
|
barycentric2 = &p.barycentric0;
|
||||||
handleLR(1,2)
|
handleLR(0,1,2)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tPointX = x2;
|
tPointX = x2;
|
||||||
tPointY = y2;
|
tPointY = y2;
|
||||||
barycentric2 = &p.barycentric2;
|
barycentric2 = &p.barycentric2;
|
||||||
handleLR(0,1)
|
handleLR(2,0,1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -189,14 +215,14 @@ void S3L_drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2
|
||||||
tPointX = x1;
|
tPointX = x1;
|
||||||
tPointY = y1;
|
tPointY = y1;
|
||||||
barycentric2 = &p.barycentric1;
|
barycentric2 = &p.barycentric1;
|
||||||
handleLR(0,2)
|
handleLR(1,0,2)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tPointX = x2;
|
tPointX = x2;
|
||||||
tPointY = y2;
|
tPointY = y2;
|
||||||
barycentric2 = &p.barycentric2;
|
barycentric2 = &p.barycentric2;
|
||||||
handleLR(0,1)
|
handleLR(2,0,1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +263,7 @@ void S3L_drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2
|
||||||
lErrAdd, rErrAdd, // error value to add in each Bresenham cycle
|
lErrAdd, rErrAdd, // error value to add in each Bresenham cycle
|
||||||
lErrSub, rErrSub; // error value to substract when moving in x direction
|
lErrSub, rErrSub; // error value to substract when moving in x direction
|
||||||
|
|
||||||
S3L_UNIT
|
S3L_Unit
|
||||||
lSideUnitStep, rSideUnitStep,
|
lSideUnitStep, rSideUnitStep,
|
||||||
lSideUnitPos, rSideUnitPos;
|
lSideUnitPos, rSideUnitPos;
|
||||||
|
|
||||||
|
@ -281,7 +307,7 @@ void S3L_drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2
|
||||||
{
|
{
|
||||||
initSide(l,l,r,0);
|
initSide(l,l,r,0);
|
||||||
|
|
||||||
S3L_UNIT *tmp = barycentric0;
|
S3L_Unit *tmp = barycentric0;
|
||||||
barycentric0 = barycentric2;
|
barycentric0 = barycentric2;
|
||||||
barycentric2 = tmp;
|
barycentric2 = tmp;
|
||||||
|
|
||||||
|
@ -292,7 +318,7 @@ void S3L_drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2
|
||||||
{
|
{
|
||||||
initSide(r,r,l,0);
|
initSide(r,r,l,0);
|
||||||
|
|
||||||
S3L_UNIT *tmp = barycentric1;
|
S3L_Unit *tmp = barycentric1;
|
||||||
barycentric1 = barycentric2;
|
barycentric1 = barycentric2;
|
||||||
barycentric2 = tmp;
|
barycentric2 = tmp;
|
||||||
|
|
||||||
|
@ -305,11 +331,11 @@ void S3L_drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2
|
||||||
|
|
||||||
// draw the line
|
// draw the line
|
||||||
|
|
||||||
S3L_UNIT tMax = rX - lX;
|
S3L_Unit tMax = rX - lX;
|
||||||
tMax = tMax != 0 ? tMax : 1; // prevent division by zero
|
tMax = tMax != 0 ? tMax : 1; // prevent division by zero
|
||||||
|
|
||||||
S3L_UNIT t1 = 0;
|
S3L_Unit t1 = 0;
|
||||||
S3L_UNIT t2 = tMax;
|
S3L_Unit t2 = tMax;
|
||||||
|
|
||||||
for (S3L_COORD x = lX; x <= rX; ++x)
|
for (S3L_COORD x = lX; x <= rX; ++x)
|
||||||
{
|
{
|
||||||
|
|
29
testSDL.c
29
testSDL.c
|
@ -47,7 +47,7 @@ const int16_t test_coords[] =
|
||||||
{
|
{
|
||||||
100,100, 99,101, 101,101, // 0, small triangle
|
100,100, 99,101, 101,101, // 0, small triangle
|
||||||
190,50, 200,10, 400,80, // 1, arbitrary
|
190,50, 200,10, 400,80, // 1, arbitrary
|
||||||
40,80, 20,50, 100,30, // 2, arbitrary
|
40,80, 60,50, 100,30, // 2, arbitrary
|
||||||
350,270, 440,200, 490,220, // 3, arbitrary
|
350,270, 440,200, 490,220, // 3, arbitrary
|
||||||
150,300, 290,400, 450,400, // 4, regular
|
150,300, 290,400, 450,400, // 4, regular
|
||||||
105,200, 120,200, 201,200, // 5, horizontal line
|
105,200, 120,200, 201,200, // 5, horizontal line
|
||||||
|
@ -58,7 +58,11 @@ void draw()
|
||||||
{
|
{
|
||||||
clearScreen();
|
clearScreen();
|
||||||
|
|
||||||
/*
|
S3L_DrawConfig conf;
|
||||||
|
|
||||||
|
conf.backfaceCulling = S3L_BACKFACE_CULLING_NONE;
|
||||||
|
|
||||||
|
|
||||||
for (int c = 0; c < 7; ++c)
|
for (int c = 0; c < 7; ++c)
|
||||||
{
|
{
|
||||||
int
|
int
|
||||||
|
@ -69,26 +73,29 @@ void draw()
|
||||||
x2 = test_coords[6 * c + 4],
|
x2 = test_coords[6 * c + 4],
|
||||||
y2 = test_coords[6 * c + 5];
|
y2 = test_coords[6 * c + 5];
|
||||||
|
|
||||||
S3L_drawTriangle(x0,y0,x1,y1,x2,y2);
|
//int cent = (x0 + x1 + x2) / 3.0;
|
||||||
|
//x1 = cent + (x1 - cent) * sin(frame * 0.01);
|
||||||
|
|
||||||
|
S3L_drawTriangle(x0,y0,x1,y1,x2,y2,conf);
|
||||||
|
|
||||||
|
|
||||||
setPixel(x0,y0,255,0,0);
|
setPixel(x0,y0,255,0,0);
|
||||||
setPixel(x1,y1,255,0,0);
|
setPixel(x1,y1,255,0,0);
|
||||||
setPixel(x2,y2,255,0,0);
|
setPixel(x2,y2,255,0,0);
|
||||||
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
int16_t rotX0 = 200 + sin(frame * 0.01) * 50;
|
int16_t rotX0 = 200 + sin(frame * 0.01) * 50;
|
||||||
int16_t rotY0 = 200 + cos(frame * 0.01) * 50;
|
int16_t rotY0 = 200 + cos(frame * 0.01) * 50;
|
||||||
|
|
||||||
int16_t rotX1 = 200 + sin((frame + 300) * 0.01) * 50;
|
int16_t rotX1 = 200 + sin((frame + 500) * 0.01) * 50;
|
||||||
int16_t rotY1 = 200 + cos((frame + 300) * 0.01) * 50;
|
int16_t rotY1 = 200 + cos((frame + 500) * 0.01) * 50;
|
||||||
|
|
||||||
int16_t rotX2 = 200 + sin((frame + 500) * 0.01) * 50;
|
|
||||||
int16_t rotY2 = 200 + cos((frame + 500) * 0.01) * 50;
|
|
||||||
|
|
||||||
S3L_drawTriangle(rotX0,rotY0,rotX1,rotY1,rotX2,rotY2);
|
|
||||||
|
|
||||||
|
int16_t rotX2 = 200 + sin((frame + 300) * 0.01) * 50;
|
||||||
|
int16_t rotY2 = 200 + cos((frame + 300) * 0.01) * 50;
|
||||||
|
|
||||||
|
S3L_drawTriangle(rotX0,rotY0,rotX1,rotY1,rotX2,rotY2,conf);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue