mirror of
https://git.coom.tech/drummyfish/small3dlib.git
synced 2024-11-24 21:09:57 +01:00
Add screen projection function
This commit is contained in:
parent
a89f3c192f
commit
4ed5e5fd84
3 changed files with 82 additions and 11 deletions
|
@ -29,6 +29,8 @@
|
||||||
S3L_Model3D models[3];
|
S3L_Model3D models[3];
|
||||||
S3L_Scene scene;
|
S3L_Scene scene;
|
||||||
|
|
||||||
|
S3L_Vec4 teleportPoint;
|
||||||
|
|
||||||
uint32_t pixels[S3L_RESOLUTION_X * S3L_RESOLUTION_Y];
|
uint32_t pixels[S3L_RESOLUTION_X * S3L_RESOLUTION_Y];
|
||||||
|
|
||||||
uint32_t frame = 0;
|
uint32_t frame = 0;
|
||||||
|
@ -80,6 +82,20 @@ void sampleTxture(S3L_Unit u, S3L_Unit v, uint8_t *r, uint8_t *g, uint8_t *b)
|
||||||
*b = texture[index];
|
*b = texture[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void drawTeleport(int16_t x, int16_t y, S3L_ScreenCoord size)
|
||||||
|
{
|
||||||
|
int16_t halfSize = size / 2;
|
||||||
|
|
||||||
|
S3L_ScreenCoord x0 = S3L_max(0,x - halfSize);
|
||||||
|
S3L_ScreenCoord x1 = S3L_min(S3L_RESOLUTION_X - 1,x + halfSize);
|
||||||
|
S3L_ScreenCoord y0 = S3L_max(0,y - halfSize);
|
||||||
|
S3L_ScreenCoord y1 = S3L_min(S3L_RESOLUTION_Y - 1,y + halfSize);
|
||||||
|
|
||||||
|
for (S3L_ScreenCoord j = y0; j < y1; ++j)
|
||||||
|
for (S3L_ScreenCoord i = x0; i < x1; ++i)
|
||||||
|
setPixel(i,j,255,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
void drawPixel(S3L_PixelInfo *p)
|
void drawPixel(S3L_PixelInfo *p)
|
||||||
{
|
{
|
||||||
if (p->triangleID != previousTriangle)
|
if (p->triangleID != previousTriangle)
|
||||||
|
@ -142,6 +158,13 @@ void draw()
|
||||||
|
|
||||||
S3L_drawScene(scene);
|
S3L_drawScene(scene);
|
||||||
|
|
||||||
|
S3L_Vec4 screenPoint;
|
||||||
|
|
||||||
|
project3DPointToScreen(teleportPoint,scene.camera,&screenPoint);
|
||||||
|
|
||||||
|
if (screenPoint.z < S3L_zBufferRead(screenPoint.x,screenPoint.y))
|
||||||
|
drawTeleport(screenPoint.x,screenPoint.y,screenPoint.w);
|
||||||
|
|
||||||
clock_t nowT = clock();
|
clock_t nowT = clock();
|
||||||
|
|
||||||
double timeDiff = ((double) (nowT - nextT)) / CLOCKS_PER_SEC;
|
double timeDiff = ((double) (nowT - nextT)) / CLOCKS_PER_SEC;
|
||||||
|
@ -167,6 +190,11 @@ int main()
|
||||||
SDL_Surface *screenSurface = SDL_GetWindowSurface(window);
|
SDL_Surface *screenSurface = SDL_GetWindowSurface(window);
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
|
||||||
|
teleportPoint.x = 6 * S3L_FRACTIONS_PER_UNIT;
|
||||||
|
teleportPoint.y = -3 * S3L_FRACTIONS_PER_UNIT;
|
||||||
|
teleportPoint.z = 2 * S3L_FRACTIONS_PER_UNIT;
|
||||||
|
teleportPoint.w = S3L_FRACTIONS_PER_UNIT;
|
||||||
|
|
||||||
nextT = clock();
|
nextT = clock();
|
||||||
|
|
||||||
S3L_initCamera(&scene.camera);
|
S3L_initCamera(&scene.camera);
|
||||||
|
|
63
small3dlib.h
63
small3dlib.h
|
@ -512,6 +512,15 @@ static inline S3L_Unit S3L_cos(S3L_Unit x);
|
||||||
S3L_Unit S3L_vec3Length(S3L_Vec4 v);
|
S3L_Unit S3L_vec3Length(S3L_Vec4 v);
|
||||||
S3L_Unit S3L_sqrt(S3L_Unit value);
|
S3L_Unit S3L_sqrt(S3L_Unit value);
|
||||||
|
|
||||||
|
/** Projects a single point from 3D space to the screen space (pixels), which
|
||||||
|
can be useful e.g. for drawing sprites. The w component of input and result
|
||||||
|
holds the point size. If this size is 0 in the result, the sprite is outside
|
||||||
|
the view. */
|
||||||
|
void project3DPointToScreen(
|
||||||
|
S3L_Vec4 point,
|
||||||
|
S3L_Camera camera,
|
||||||
|
S3L_Vec4 *result);
|
||||||
|
|
||||||
/** Computes a normalized normal of given triangle. */
|
/** Computes a normalized normal of given triangle. */
|
||||||
void S3L_triangleNormal(S3L_Vec4 t0, S3L_Vec4 t1, S3L_Vec4 t2,
|
void S3L_triangleNormal(S3L_Vec4 t0, S3L_Vec4 t1, S3L_Vec4 t2,
|
||||||
S3L_Vec4 *n);
|
S3L_Vec4 *n);
|
||||||
|
@ -1419,6 +1428,50 @@ void S3L_initTransoform3D(S3L_Transform3D *t)
|
||||||
t->scale.w = 0;
|
t->scale.w = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs perspecive division (z-divide). Does NOT check for division by zero.
|
||||||
|
*/
|
||||||
|
static inline void S3L_perspectiveDivide(S3L_Vec4 *vector,
|
||||||
|
S3L_Unit focalLength)
|
||||||
|
{
|
||||||
|
vector->x = (vector->x * focalLength) / vector->z;
|
||||||
|
vector->y = (vector->y * focalLength) / vector->z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void project3DPointToScreen(
|
||||||
|
S3L_Vec4 point,
|
||||||
|
S3L_Camera camera,
|
||||||
|
S3L_Vec4 *result)
|
||||||
|
{
|
||||||
|
S3L_Mat4 m;
|
||||||
|
S3L_makeCameraMatrix(camera.transform,&m);
|
||||||
|
|
||||||
|
S3L_Unit s = point.w;
|
||||||
|
|
||||||
|
point.w = S3L_FRACTIONS_PER_UNIT;
|
||||||
|
|
||||||
|
S3L_vec3Xmat4(&point,&m);
|
||||||
|
|
||||||
|
point.z = S3L_nonZero(point.z);
|
||||||
|
|
||||||
|
S3L_perspectiveDivide(&point,camera.focalLength);
|
||||||
|
|
||||||
|
S3L_ScreenCoord x, y;
|
||||||
|
|
||||||
|
S3L_mapProjectionPlaneToScreen(point,&x,&y);
|
||||||
|
|
||||||
|
result->x = x;
|
||||||
|
result->y = y;
|
||||||
|
result->z = point.z;
|
||||||
|
|
||||||
|
result->w =
|
||||||
|
(point.z < 0) ? 0 :
|
||||||
|
(
|
||||||
|
(s * camera.focalLength * S3L_RESOLUTION_X) /
|
||||||
|
(point.z * S3L_FRACTIONS_PER_UNIT)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void S3L_lookAt(S3L_Vec4 pointTo, S3L_Transform3D *t)
|
void S3L_lookAt(S3L_Vec4 pointTo, S3L_Transform3D *t)
|
||||||
{
|
{
|
||||||
S3L_Vec4 v;
|
S3L_Vec4 v;
|
||||||
|
@ -2296,16 +2349,6 @@ void S3L_makeCameraMatrix(S3L_Transform3D cameraTransform, S3L_Mat4 *m)
|
||||||
S3L_mat4Xmat4(m,&r);
|
S3L_mat4Xmat4(m,&r);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
Performs perspecive division (z-divide). Does NOT check for division by zero.
|
|
||||||
*/
|
|
||||||
static inline void S3L_perspectiveDivide(S3L_Vec4 *vector,
|
|
||||||
S3L_Unit focalLength)
|
|
||||||
{
|
|
||||||
vector->x = (vector->x * focalLength) / vector->z;
|
|
||||||
vector->y = (vector->y * focalLength) / vector->z;
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t S3L_triangleWinding(
|
int8_t S3L_triangleWinding(
|
||||||
S3L_ScreenCoord x0,
|
S3L_ScreenCoord x0,
|
||||||
S3L_ScreenCoord y0,
|
S3L_ScreenCoord y0,
|
||||||
|
|
2
todo.txt
2
todo.txt
|
@ -16,7 +16,7 @@ features:
|
||||||
- function to set/clear stencil buffer -- can be useful
|
- function to set/clear stencil buffer -- can be useful
|
||||||
|
|
||||||
- function to map one point in 3D space to screen, along with size (for mapping
|
- function to map one point in 3D space to screen, along with size (for mapping
|
||||||
billboards/sprites etc.)
|
billboards/sprites etc.) DONE
|
||||||
|
|
||||||
- Optimize persp. correction!
|
- Optimize persp. correction!
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue