diff --git a/small3dlib.h b/small3dlib.h index bc5eb73..e8f9c33 100644 --- a/small3dlib.h +++ b/small3dlib.h @@ -274,65 +274,6 @@ typedef uint16_t S3L_Index; #define S3L_HALF_RESOLUTION_X (S3L_RESOLUTION_X >> 1) #define S3L_HALF_RESOLUTION_Y (S3L_RESOLUTION_Y >> 1) -#define S3L_PROJECTION_PLANE_HEIGHT\ - ((S3L_RESOLUTION_Y * S3L_FRACTIONS_PER_UNIT * 2) / S3L_RESOLUTION_X) - -/** Predefined vertices of a cube to simply insert in an array. These come with - S3L_CUBE_TRIANGLES and S3L_CUBE_TEXCOORDS. */ -#define S3L_CUBE_VERTICES\ - /* 0 front, bottom, right */\ - S3L_FRACTIONS_PER_UNIT/2,-S3L_FRACTIONS_PER_UNIT/2,-S3L_FRACTIONS_PER_UNIT/2,\ - /* 1 front, bottom, left */\ --S3L_FRACTIONS_PER_UNIT/2,-S3L_FRACTIONS_PER_UNIT/2,-S3L_FRACTIONS_PER_UNIT/2,\ - /* 2 front, top, right */\ - S3L_FRACTIONS_PER_UNIT/2,S3L_FRACTIONS_PER_UNIT/2,-S3L_FRACTIONS_PER_UNIT/2,\ - /* 3 front, top, left */\ --S3L_FRACTIONS_PER_UNIT/2,S3L_FRACTIONS_PER_UNIT/2,-S3L_FRACTIONS_PER_UNIT/2,\ - /* 4 back, bottom, right */\ - S3L_FRACTIONS_PER_UNIT/2,-S3L_FRACTIONS_PER_UNIT/2,S3L_FRACTIONS_PER_UNIT/2,\ - /* 5 back, bottom, left */\ --S3L_FRACTIONS_PER_UNIT/2,-S3L_FRACTIONS_PER_UNIT/2,S3L_FRACTIONS_PER_UNIT/2,\ - /* 6 back, top, right */\ - S3L_FRACTIONS_PER_UNIT/2,S3L_FRACTIONS_PER_UNIT/2,S3L_FRACTIONS_PER_UNIT/2,\ - /* 7 back, top, left */\ --S3L_FRACTIONS_PER_UNIT/2,S3L_FRACTIONS_PER_UNIT/2,S3L_FRACTIONS_PER_UNIT/2 - -#define S3L_CUBE_VERTEX_COUNT 8 - -/** Predefined triangle indices of a cube, to be used with S3L_CUBE_VERTICES - and S3L_CUBE_TEXCOORDS. */ -#define S3L_CUBE_TRIANGLES\ - 0, 3, 2, /* front */\ - 0, 1, 3,\ - 4, 0, 2, /* right */\ - 4, 2, 6,\ - 5, 4, 6, /* back */\ - 6, 7, 5,\ - 7, 3, 1, /* left */\ - 7, 1, 5,\ - 3, 6, 2, /* top */\ - 3, 7, 6,\ - 4, 1, 0, /* bottom */\ - 4, 5, 1 - -#define S3L_CUBE_TRIANGLE_COUNT 12 - -/** Predefined texture coordinates of a cube, corresponding to triangles (NOT - vertices), to be used with S3L_CUBE_VERTICES and S3L_CUBE_TRIANGLES. */ -#define S3L_CUBE_TEXCOORDS(m)\ - m,m, 0,0, m,0,\ - m,m, 0,m, 0,0,\ - m,0, m,m, 0,m,\ - m,0, 0,m, 0,0,\ - 0,0, m,0, m,m,\ - m,m, 0,m, 0,0,\ - 0,m, 0,0, m,0,\ - 0,m, m,0, m,m,\ - m,m, 0,0, m,0,\ - m,m, 0,m, 0,0,\ - 0,m, m,0, m,m,\ - 0,m, 0,0, m,0 - /** Vector that consists of four scalars and can represent homogenous coordinates, but is generally also used as Vec3 and Vec2. */ typedef struct @@ -536,6 +477,8 @@ static inline S3L_Unit S3L_interpolateByUnitFrom0( S3L_Unit v2, S3L_Unit t); +static inline S3L_Unit S3L_distanceManhattan(S3L_Vec4 a, S3L_Vec4 b); + /** Returns a value interpolated between the three triangle vertices based on barycentric coordinates. */ static inline S3L_Unit S3L_interpolateBarycentric( @@ -574,9 +517,68 @@ void S3L_stencilBufferClear(); static inline void S3L_rotate2DPoint(S3L_Unit *x, S3L_Unit *y, S3L_Unit angle); +/** Predefined vertices of a cube to simply insert in an array. These come with + S3L_CUBE_TRIANGLES and S3L_CUBE_TEXCOORDS. */ +#define S3L_CUBE_VERTICES(m)\ + /* 0 front, bottom, right */\ + m/2, -m/2, -m/2,\ + /* 1 front, bottom, left */\ +-m/2, -m/2, -m/2,\ + /* 2 front, top, right */\ + m/2, m/2, -m/2,\ + /* 3 front, top, left */\ +-m/2, m/2, -m/2,\ + /* 4 back, bottom, right */\ + m/2, -m/2, m/2,\ + /* 5 back, bottom, left */\ +-m/2, -m/2, m/2,\ + /* 6 back, top, right */\ + m/2, m/2, m/2,\ + /* 7 back, top, left */\ +-m/2, m/2, m/2 + +#define S3L_CUBE_VERTEX_COUNT 8 + +/** Predefined triangle indices of a cube, to be used with S3L_CUBE_VERTICES + and S3L_CUBE_TEXCOORDS. */ +#define S3L_CUBE_TRIANGLES\ + 0, 3, 2, /* front */\ + 0, 1, 3,\ + 4, 0, 2, /* right */\ + 4, 2, 6,\ + 5, 4, 6, /* back */\ + 6, 7, 5,\ + 7, 3, 1, /* left */\ + 7, 1, 5,\ + 3, 6, 2, /* top */\ + 3, 7, 6,\ + 4, 1, 0, /* bottom */\ + 4, 5, 1 + +#define S3L_CUBE_TRIANGLE_COUNT 12 + +/** Predefined texture coordinates of a cube, corresponding to triangles (NOT + vertices), to be used with S3L_CUBE_VERTICES and S3L_CUBE_TRIANGLES. */ +#define S3L_CUBE_TEXCOORDS(m)\ + m,m, 0,0, m,0,\ + m,m, 0,m, 0,0,\ + m,0, m,m, 0,m,\ + m,0, 0,m, 0,0,\ + 0,0, m,0, m,m,\ + m,m, 0,m, 0,0,\ + 0,m, 0,0, m,0,\ + 0,m, m,0, m,m,\ + m,m, 0,0, m,0,\ + m,m, 0,m, 0,0,\ + 0,m, m,0, m,m,\ + 0,m, 0,0, m,0 + //============================================================================= // privates +#define S3L_PROJECTION_PLANE_HEIGHT\ + ((S3L_RESOLUTION_Y * S3L_FRACTIONS_PER_UNIT * 2) / S3L_RESOLUTION_X) + #if S3L_Z_BUFFER == 1 #define S3L_COMPUTE_DEPTH 1 #define S3L_MAX_DEPTH 2147483647 @@ -836,6 +838,14 @@ S3L_Unit S3L_interpolateFrom0(S3L_Unit v2, S3L_Unit t, S3L_Unit tMax) return (v2 * t) / tMax; } +S3L_Unit S3L_distanceManhattan(S3L_Vec4 a, S3L_Vec4 b) +{ + return + S3L_abs(a.x - b.x) + + S3L_abs(a.y - b.y) + + S3L_abs(a.z - b.z); +} + void S3L_mat4Xmat4(S3L_Mat4 *m1, S3L_Mat4 *m2) { S3L_Mat4 mat1; diff --git a/testSDL.c b/testSDL.c index 31567f2..c0f065d 100644 --- a/testSDL.c +++ b/testSDL.c @@ -23,20 +23,22 @@ #include "small3dlib.h" +#include "houseTexture.h" #include "house.h" int32_t offScreenPixels = 0; -const S3L_Unit ver[] = { S3L_CUBE_VERTICES }; +const S3L_Unit ver[] = { S3L_CUBE_VERTICES(S3L_FRACTIONS_PER_UNIT) }; const S3L_Index tri[] = { S3L_CUBE_TRIANGLES }; const S3L_Unit tex_coords[] = { S3L_CUBE_TEXCOORDS(16) }; S3L_Model3D models[2]; S3L_Scene scene; +uint8_t houseVertexLighting[127]; + int8_t keys[256]; const uint8_t testTexture[] = -/* { 2,2,2,0,0,0,2,2,2,2,0,0,0,2,2,2, 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, @@ -55,7 +57,7 @@ const uint8_t testTexture[] = 2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, 2,2,2,0,0,0,2,2,2,2,0,0,0,2,2,2 }; -*/ +/* { 0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0, 1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1, @@ -73,6 +75,7 @@ const uint8_t testTexture[] = 1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1, 2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2 }; +*/ uint32_t pixels[S3L_RESOLUTION_X * S3L_RESOLUTION_Y]; @@ -126,8 +129,19 @@ void houseTex(int32_t u, int32_t v, uint8_t *r, uint8_t *g, uint8_t *b) *b = houseTexture[index + 2]; } +int l0, l1, l2; +int previousTriangle = 255; + void drawPixel(S3L_PixelInfo *p) { + if (p->triangleIndex != previousTriangle) + { + l0 = houseVertexLighting[houseTriangleIndices[p->triangleIndex * 3]]; + l1 = houseVertexLighting[houseTriangleIndices[p->triangleIndex * 3 + 1]]; + l2 = houseVertexLighting[houseTriangleIndices[p->triangleIndex * 3 + 2]]; + previousTriangle = p->triangleIndex; + } + if (p->x < 0 || p ->x >= S3L_RESOLUTION_X || p->y < 0 || p->y >= S3L_RESOLUTION_Y) { offScreenPixels++; @@ -185,7 +199,26 @@ if (p->modelIndex != 0) (u / ((float) S3L_FRACTIONS_PER_UNIT)) * HOUSE_TEXTURE_WIDTH, (v / ((float) S3L_FRACTIONS_PER_UNIT)) * HOUSE_TEXTURE_HEIGHT, &r,&g,&b); - setPixel(p->x,p->y,r,g,b); + + uint8_t l = S3L_interpolateBarycentric(l0,l1,l2, + p->barycentric[0], + p->barycentric[1], + p->barycentric[2]); + + l = 255 - l; + + l /= 2; + + int16_t clampTmp = r - l; + r = clampTmp >= 0 ? clampTmp : 0; + + clampTmp = g - l; + g = clampTmp >= 0 ? clampTmp : 0; + + clampTmp = b - l; + b = clampTmp >= 0 ? clampTmp : 0; + + setPixel(p->x,p->y,r,g,b); } else { @@ -223,6 +256,39 @@ clock_t nextT; int fps = 0; +void recomputeLight() +{ + S3L_Mat4 m; + + S3L_makeWorldMatrix(scene.models[1].transform,&m); + + int radius = S3L_FRACTIONS_PER_UNIT * 12; + + for (int i = 0; i < 127; ++i) + { + S3L_Vec4 v; + + int index = i * 3; + + v.x = houseVertices[index]; + v.y = houseVertices[index + 1]; + v.z = houseVertices[index + 2]; + + S3L_vec3Xmat4(&v,m); + + S3L_Unit d = S3L_distanceManhattan(v,scene.camera.transform.translation); + + d = radius - d; + + int l = 0; + + if (d >= 0) + l = 255 - S3L_interpolateFrom0(255,d,radius); + + houseVertexLighting[i] = l; + } +} + void draw() { S3L_newFrame(); @@ -233,6 +299,9 @@ void draw() uint32_t f = frame; + if (f % 16 == 0) + recomputeLight(); + //scene.models[0].transform.rotation.z = f * 0.1; //scene.models[0].transform.rotation.x = f * 0.3; @@ -280,7 +349,7 @@ scene.camera.transform.rotation.x = -35; scene.camera.transform.rotation.y = 128; scene.camera.transform.rotation.z = 0; -S3L_setTransform3D(-542,-449,4000,39,216,0,512,512,512,&(scene.camera.transform)); +S3L_setTransform3D(3196,1814,5958,-18,300,0,512,512,512,&(scene.camera.transform)); scene.modelCount = 2; scene.models = models; @@ -296,12 +365,14 @@ S3L_setTransform3D(-542,-449,4000,39,216,0,512,512,512,&(scene.camera.transform) // scene.models[1] = scene.models[0]; // scene.models[1].transform.translation.x = 0.5 * S3L_FRACTIONS_PER_UNIT; - scene.models[1] = house; + scene.models[1] = houseModel; S3L_initTransoform3D(&(scene.models[1].transform)); S3L_initDrawConfig(&(scene.models[1].config)); scene.models[1].transform.translation.y = -1 * S3L_FRACTIONS_PER_UNIT; scene.models[1].transform.translation.z = 4 * S3L_FRACTIONS_PER_UNIT; + recomputeLight(); + // scene.camera.transform.translation.x = S3L_FRACTIONS_PER_UNIT; // scene.camera.transform.translation.y = S3L_FRACTIONS_PER_UNIT; @@ -350,7 +421,7 @@ S3L_setTransform3D(-542,-449,4000,39,216,0,512,512,512,&(scene.camera.transform) } S3L_Vec4 camF, camR, camU; - int step = 10; + int step = 50; S3L_rotationToDirections( scene.camera.transform.rotation,