1
0
Fork 0
mirror of https://git.coom.tech/drummyfish/small3dlib.git synced 2024-11-21 20:39:57 +01:00
small3dlib/programs/terminalCube.c

101 lines
3.1 KiB
C
Raw Normal View History

2020-06-21 17:24:35 +02:00
/**
2019-06-08 16:56:54 +02:00
Simple example of small3dlib, rendering in terminal.
2020-06-21 17:24:35 +02:00
by drummyfish, released under CC0 1.0, public domain
2019-06-08 16:56:54 +02:00
*/
2019-07-13 18:43:20 +02:00
#include <stdio.h>
2020-06-21 17:24:35 +02:00
#include <unistd.h> // for usleep
2019-06-08 16:56:54 +02:00
// we need to define screen resolution before including the library:
#define S3L_RESOLUTION_X 80
#define S3L_RESOLUTION_Y 40
// and a name of the function we'll be using to draw individual pixels:
#define S3L_PIXEL_FUNCTION drawPixel
2020-06-21 17:24:35 +02:00
#include "../small3dlib.h" // now include the library
2019-06-08 16:56:54 +02:00
2020-06-21 17:24:35 +02:00
// we'll use a predefined geometry of a cube from the library:
2019-06-08 16:56:54 +02:00
S3L_Unit cubeVertices[] = { S3L_CUBE_VERTICES(S3L_FRACTIONS_PER_UNIT) };
S3L_Index cubeTriangles[] = { S3L_CUBE_TRIANGLES };
S3L_Model3D cubeModel; // 3D model, has a geometry, position, rotation etc.
S3L_Scene scene; // scene we'll be rendring (can have multiple models)
2020-06-21 17:24:35 +02:00
#define FRAME_OFFSET 20 // how many newlines will be printed before each frame
#define SCREEN_SIZE (FRAME_OFFSET + (S3L_RESOLUTION_X + 1) * S3L_RESOLUTION_Y + 1)
uint8_t screen[SCREEN_SIZE]; // ASCII screen
2019-06-08 16:56:54 +02:00
/* This function will be called by the library to draw individual rasterized
pixels to the screen. We should try to make this function as fast as possible
as it tends to be the performance bottle neck. */
void drawPixel(S3L_PixelInfo *p)
{
uint8_t c; // ASCII pixel we'll write to the screen
/* We'll draw different triangles with different ASCII symbols to give the
illusion of lighting. */
if (p->triangleIndex == 0 || p->triangleIndex == 1 ||
p->triangleIndex == 4 || p->triangleIndex == 5)
c = '#';
else if (p->triangleIndex == 2 || p->triangleIndex == 3 ||
p->triangleIndex == 6 || p->triangleIndex == 7)
c = 'x';
else
c = '.';
2020-06-21 17:24:35 +02:00
// draw to ASCII screen
screen[FRAME_OFFSET + p->y * (S3L_RESOLUTION_X + 1) + p->x] = c;
2019-06-08 16:56:54 +02:00
}
int main()
{
2021-12-28 23:25:22 +01:00
S3L_model3DInit(
2019-06-08 16:56:54 +02:00
cubeVertices,
S3L_CUBE_VERTEX_COUNT,
cubeTriangles,
S3L_CUBE_TRIANGLE_COUNT,
&cubeModel);
2021-12-28 23:25:22 +01:00
S3L_sceneInit( // Initialize the scene we'll be rendering.
2020-06-21 17:24:35 +02:00
&cubeModel, // This is like an array with only one model in it.
2019-06-08 16:56:54 +02:00
1,
&scene);
// shift the camera a little bit backwards so that it's not inside the cube:
scene.camera.transform.translation.z = -2 * S3L_FRACTIONS_PER_UNIT;
2020-06-21 17:24:35 +02:00
for (int i = 0; i < 200; ++i) // render 200 frames
2019-06-08 16:56:54 +02:00
{
2020-06-21 17:24:35 +02:00
// clear the screen
for (int j = 0; j < FRAME_OFFSET; ++j)
screen[j] = '\n';
2019-06-08 16:56:54 +02:00
2020-06-21 17:24:35 +02:00
for (int j = FRAME_OFFSET; j < SCREEN_SIZE; ++j)
screen[j] = ((j - FRAME_OFFSET + 1) % (S3L_RESOLUTION_X + 1) ? ' ' : '\n');
screen[SCREEN_SIZE - 1] = 0; // terminate the string
2019-07-13 18:43:20 +02:00
2020-06-21 17:24:35 +02:00
S3L_newFrame(); // has to be called before each frame
2019-06-08 16:56:54 +02:00
S3L_drawScene(scene); /* This starts the scene rendering. The drawPixel
function will be called to draw it. */
2020-06-21 17:24:35 +02:00
puts(screen); // display the frame
2019-06-08 16:56:54 +02:00
usleep(100000); // wait a bit to let the user see the frame
// now move and rotate the cube a little to see some movement:
scene.models[0].transform.rotation.y += 10;
scene.models[0].transform.rotation.x += 4;
scene.models[0].transform.translation.x = S3L_sin(i * 4);
scene.models[0].transform.translation.y = S3L_sin(i * 2) / 2;
}
return 0;
}