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

Update tests

This commit is contained in:
Miloslav Číž 2020-06-21 17:24:35 +02:00
parent 681503a703
commit 53d3c84fbf
3 changed files with 121 additions and 47 deletions

View file

@ -39,7 +39,16 @@ PC (SDL, offline rendering, terminal):
- **Different drawing strategies** to choose from: none, z-buffer (none, full, reduced), triangle sorting (back-to-front, fron-to-back with stencil buffer).
- Triangles provide **barycentric coordinates**, thanks to which practically anything that can be achieved with OpenGL can be achieved (texturing, shading, normal-mapping, texture fitering, transparency, PBR, shadow mapping, MIP mapping, ...).
- **Top-left rasterization rule**, pixels of adjacent triangles don't overlap or have holes (just like in OpenGL).
- **Tested on multiple platforms** (PC, Pokitto, Gamebuino META).
- **Tested on many platforms**:
- PC (little endian, 64bit GNU)
- PowerPC emulator (big endian)
- compilers: gcc, clang
- Arduboy (only experimental)
- Gamebuino META (32bit resource-limited embedded ARM)
- TODO:
- Android
- Windows
- emscripten (web browser, JavaScript transpile)
- **Many compile-time options** to tune the performance vs quality.
- **Similar to OpenGL** in principle, but simpler, easier to use, with higher-level features.
- **Tools** (Python scripts) for converting 3D models and textures to C array format used by the library.
@ -51,8 +60,22 @@ be an as-is set of tools that the users is welcome to adjust for their
specific project. So new features will be preferred to keeping the same
interface.
## why?
You just need to make a small mini 3D game, quick 3D animation or visualization and don't want to go through the horror of learning and setting
up OpenGL, installing drivers and libraries? Don't want to be tied to HW, 3rd party API or libraries and their dependencies? Don't want to install
gigabytes of heavy super ultra graphics engines just for playing around with a few low poly models? You want to create extremely portable 3D
graphics that will run on small and obscure platforms that don't have OpenGL, good specs or even standard C library? Want to just render something
offline simply and not caring about highest rendering speed? You want to toy around with modifying something in the rendering pipeline that you
can't easily do or debug in OpenGL (such as the rasterization algorithm)? Want to hack around in the demo scene? Want to create something public
domain and need a public domain renderer? Or just don't want to be bothered by conditions such as proper attribution or copyleft?
This library may help you.
## limitations
And advantages at the same time :)
- **No scenegraph** (object parenting), just a scene list. Parenting can still be achieved by using cutom transform matrices.
- Though performance is high, due to multiplatformness it **probably can't match platform-specific rasterizers written in assembly**.
- There is **no far plane**.

74
programs/helloWorld.c Normal file
View file

@ -0,0 +1,74 @@
/**
Simple hello world for small3dlib. Renders a triangle in terminal as ASCII.
by drummyfish, released under CC0 1.0, public domain
*/
#include <stdio.h> // for IO
// This tells the library the resolution of our ASCII screen.
#define S3L_RESOLUTION_X 64
#define S3L_RESOLUTION_Y 30
// This tells the library the name of a function we use to write pixels.
#define S3L_PIXEL_FUNCTION drawPixel
#include "../small3dlib.h" // now include the library
#define U S3L_FRACTIONS_PER_UNIT // this is the library unit, like e.g. 1 meter
S3L_Unit triangleVertices[] = { // x, y, z
U, 0, 0, // vertex 1
0, U, 0, // vertex 2
-U, U/2, 0 }; // vertex 3
S3L_Index triangleTriangles[] = { 0, 1, 2 }; // our single triangle
#undef U
#define SCREEN_SIZE (S3L_RESOLUTION_X * S3L_RESOLUTION_Y)
char screen[SCREEN_SIZE]; // our ASCII screen
/* This function will be called by the library to draw individual rasterized
pixels to our 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)
{
screen[p->y * S3L_RESOLUTION_X + p->x] = 'X';
}
int main()
{
for (int i = 0; i < SCREEN_SIZE; ++i) // init the screen
screen[i] = '.';
S3L_Model3D triangleModel; // 3D model representing our triangle
S3L_initModel3D(triangleVertices,9,triangleTriangles,1,&triangleModel);
S3L_Scene scene; // scene of 3D models (we only have 1)
S3L_initScene(&triangleModel,1,&scene);
// shift the camera a little bit so that we can see the triangle
scene.camera.transform.translation.z = -2 * S3L_FRACTIONS_PER_UNIT;
scene.camera.transform.translation.y = S3L_FRACTIONS_PER_UNIT / 2;
S3L_newFrame(); // has to be called before each frame
S3L_drawScene(scene); /* this starts the scene rendering, the library
will now start calling our drawPixel function to
render the camera view */
int index = 0;
for (int y = 0; y < S3L_RESOLUTION_Y; ++y) // now display the screen
{
for (int x = 0; x < S3L_RESOLUTION_X; ++x)
{
putchar(screen[index]);
index++;
}
putchar('\n');
}
return 0; // done!
}

View file

@ -1,26 +1,22 @@
/*
/**
Simple example of small3dlib, rendering in terminal.
license: CC0 1.0
by drummyfish, released under CC0 1.0, public domain
*/
#include <stdio.h>
#include <unistd.h> // for usleep
#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" // now include the library
#include "../small3dlib.h"
// we'll use a predefined geometry of a cube that's in the library:
// we'll use a predefined geometry of a cube from the library:
S3L_Unit cubeVertices[] = { S3L_CUBE_VERTICES(S3L_FRACTIONS_PER_UNIT) };
S3L_Index cubeTriangles[] = { S3L_CUBE_TRIANGLES };
@ -28,7 +24,10 @@ 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
#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
/* 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
@ -50,34 +49,8 @@ void drawPixel(S3L_PixelInfo *p)
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");
}
// draw to ASCII screen
screen[FRAME_OFFSET + p->y * (S3L_RESOLUTION_X + 1) + p->x] = c;
}
int main()
@ -89,9 +62,8 @@ int main()
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. */
S3L_initScene( // Initialize the scene we'll be rendering.
&cubeModel, // This is like an array with only one model in it.
1,
&scene);
@ -99,20 +71,25 @@ int main()
scene.camera.transform.translation.z = -2 * S3L_FRACTIONS_PER_UNIT;
for (int i = 0; i < 200; ++i) // render 200 frames
for (int i = 0; i < 200; ++i) // render 200 frames
{
clearScreen();
// clear the screen
for (int j = 0; j < FRAME_OFFSET; ++j)
screen[j] = '\n';
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
S3L_newFrame(); // has to be called before each frame
S3L_drawScene(scene); /* This starts the scene rendering. The drawPixel
function will be called to draw it. */
drawScreen();
puts(screen); // display the frame
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);