1
0
Fork 0
mirror of https://git.coom.tech/drummyfish/small3dlib.git synced 2024-11-20 20:29:58 +01:00

Add helloTerminal

This commit is contained in:
Miloslav Číž 2019-06-08 16:56:54 +02:00
parent 5e67aeb2c8
commit 55b6edfcb0
3 changed files with 163 additions and 8 deletions

120
programs/helloTerminal.c Normal file
View file

@ -0,0 +1,120 @@
/*
Simple example of small3dlib, rendering in terminal.
license: CC0 1.0
*/
#include <unistd.h> // for usleep
// 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
// now include the library:
#include "../small3dlib.h"
// we'll use a predefined geometry of a cube that's in the library:
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)
uint8_t screen[S3L_RESOLUTION_X * S3L_RESOLUTION_Y]; // our screen
/* 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 = '.';
screen[p->y * S3L_RESOLUTION_X + p->x] = c; // draw the pixel to the screen
}
void clearScreen()
{
for (int j = 0; j < S3L_RESOLUTION_X * S3L_RESOLUTION_Y; ++j)
screen[j] = ' ';
}
// This function prints out the content of the screen to the terminal.
void drawScreen()
{
for (int i = 0; i < 20; ++i)
printf("\n");
int pos = 0;
for (int y = 0; y < S3L_RESOLUTION_Y; ++y)
{
for (int x = 0; x < S3L_RESOLUTION_X; ++x)
{
printf("%c",screen[pos]);
pos++;
}
printf("\n");
}
}
int main()
{
S3L_initModel3D(
cubeVertices,
S3L_CUBE_VERTEX_COUNT,
cubeTriangles,
S3L_CUBE_TRIANGLE_COUNT,
&cubeModel);
S3L_initScene( // Initialize the scene we'll be rendering.
&cubeModel, /* We only have one model (the cube), this is like an array
with only one model in it. */
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;
for (int i = 0; i < 200; ++i) // render 200 frames
{
clearScreen();
S3L_drawScene(scene); /* This starts the scene rendering. The drawPixel
function will be called to draw it. */
drawScreen();
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;
}

View file

@ -417,7 +417,7 @@ int main()
S3L_normalizeVec3(&toLight);
S3L_initCamera(&scene.camera);
S3L_initScene(&model,1,&scene);
scene.camera.transform.translation.z = -S3L_FRACTIONS_PER_UNIT * 8;
@ -425,9 +425,6 @@ int main()
catModel.vertices = catVertices;
animate(0);
scene.modelCount = 1;
scene.models = &model;
int8_t modelIndex = 0;
int8_t modelsTotal = 4;
setModel(0);

View file

@ -390,7 +390,7 @@ typedef struct
S3L_Transform3D transform;
} S3L_Camera;
static inline void S3L_initCamera(S3L_Camera *c);
void S3L_initCamera(S3L_Camera *camera);
typedef struct
{
@ -414,6 +414,13 @@ typedef struct
S3L_DrawConfig config;
} S3L_Model3D; ///< Represents a 3D model.
void S3L_initModel3D(
S3L_Unit *vertices,
S3L_Unit vertexCount,
S3L_Index *triangles,
S3L_Index triangleCount,
S3L_Model3D *model);
typedef struct
{
S3L_Model3D *models;
@ -421,6 +428,11 @@ typedef struct
S3L_Camera camera;
} S3L_Scene; ///< Represent the 3D scene to be rendered.
void S3L_initScene(
S3L_Model3D *models,
S3L_Index modelCount,
S3L_Scene *scene);
typedef struct
{
S3L_ScreenCoord x; ///< Screen X coordinate.
@ -1319,10 +1331,10 @@ void S3L_setTransform3D(
t->scale.z = sz;
}
void S3L_initCamera(S3L_Camera *c)
void S3L_initCamera(S3L_Camera *camera)
{
c->focalLength = S3L_FRACTIONS_PER_UNIT;
S3L_initTransoform3D(&(c->transform));
camera->focalLength = S3L_FRACTIONS_PER_UNIT;
S3L_initTransoform3D(&(camera->transform));
}
void S3L_rotationToDirections(
@ -1373,6 +1385,32 @@ void S3L_initPixelInfo(S3L_PixelInfo *p) // TODO: maybe non-pointer for p
p->previousZ = 0;
}
void S3L_initModel3D(
S3L_Unit *vertices,
S3L_Unit vertexCount,
S3L_Index *triangles,
S3L_Index triangleCount,
S3L_Model3D *model)
{
model->vertices = vertices;
model->vertexCount = vertexCount;
model->triangles = triangles;
model->triangleCount = triangleCount;
S3L_initTransoform3D(&(model->transform));
S3L_initDrawConfig(&(model->config));
}
void S3L_initScene(
S3L_Model3D *models,
S3L_Index modelCount,
S3L_Scene *scene)
{
scene->models = models;
scene->modelCount = modelCount;
S3L_initCamera(&(scene->camera));
}
void S3L_initDrawConfig(S3L_DrawConfig *config)
{
config->backfaceCulling = 2;