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

Start highPoly demo

This commit is contained in:
Miloslav Číž 2019-06-27 23:07:46 +02:00
parent 465e941e99
commit 010f5b3e59
5 changed files with 21558 additions and 10 deletions

21409
programs/alligatorModel.h Normal file

File diff suppressed because it is too large Load diff

120
programs/highPoly.c Normal file
View file

@ -0,0 +1,120 @@
/*
Example program for small3dlib, testing a high-poly offline model.
author: Miloslav Ciz
license: CC0 1.0
*/
#include <stdio.h>
#include <math.h>
#include <time.h>
#define S3L_STRICT_NEAR_CULLING 0
#if TEXTURES
#define S3L_PERSPECTIVE_CORRECTION 2
#else
#define S3L_PERSPECTIVE_CORRECTION 0
#endif
#define S3L_NEAR (S3L_FRACTIONS_PER_UNIT / 5)
#define S3L_Z_BUFFER 1
#define S3L_PIXEL_FUNCTION drawPixel
#define S3L_RESOLUTION_X 800
#define S3L_RESOLUTION_Y 600
#include "../small3dlib.h"
#include "alligatorModel.h"
S3L_Unit normals[ALLIGATOR_VERTEX_COUNT * 3];
uint8_t frameBuffer[S3L_RESOLUTION_X * S3L_RESOLUTION_Y * 3];
S3L_Scene scene;
S3L_Vec4 teleportPoint;
uint32_t pixels[S3L_RESOLUTION_X * S3L_RESOLUTION_Y];
void clearScreen()
{
memset(frameBuffer,255,S3L_RESOLUTION_X * S3L_RESOLUTION_Y * 3 * sizeof(uint8_t));
}
void saveImage(char *fileName)
{
printf("saving image file: %s\n",fileName);
FILE *f = fopen(fileName,"w");
fprintf(f,"P3\n%d %d\n255\n",S3L_RESOLUTION_X,S3L_RESOLUTION_Y);
for (int i = 0; i < S3L_RESOLUTION_X * S3L_RESOLUTION_Y * 3; i += 3)
fprintf(f,"%d %d %d\n",frameBuffer[i],frameBuffer[i + 1],frameBuffer[i + 2]);
fclose(f);
}
uint32_t previousTriangle = 1000;
S3L_Vec4 n0, n1, n2, toLight;
void drawPixel(S3L_PixelInfo *p)
{
if (p->triangleID != previousTriangle)
{
S3L_getIndexedTriangleValues(
p->triangleIndex,
scene.models[p->modelIndex].triangles,
normals,3,&n0,&n1,&n2);
previousTriangle = p->triangleID;
}
S3L_Vec4 normal;
normal.x = S3L_interpolateBarycentric(n0.x,n1.x,n2.x,p->barycentric);
normal.y = S3L_interpolateBarycentric(n0.y,n1.y,n2.y,p->barycentric);
normal.z = S3L_interpolateBarycentric(n0.z,n1.z,n2.z,p->barycentric);
S3L_normalizeVec3(&normal);
uint8_t shading =
S3L_clamp((S3L_dotProductVec3(normal,toLight) + S3L_FRACTIONS_PER_UNIT) / 4,0,255);
int index = (p->y * S3L_RESOLUTION_X + p->x) * 3;
frameBuffer[index] = shading;
frameBuffer[index + 1] = shading;
frameBuffer[index + 2] = shading;
}
int main()
{
S3L_setVec4(&toLight,10,10,10,0);
S3L_normalizeVec3(&toLight);
alligatorModelInit();
S3L_computeModelNormals(alligatorModel,normals,0);
S3L_initScene(&alligatorModel,1,&scene);
scene.camera.transform.translation.z = -8 * S3L_FRACTIONS_PER_UNIT;
scene.camera.transform.translation.x = 9 * S3L_FRACTIONS_PER_UNIT;
scene.camera.transform.translation.y = 6 * S3L_FRACTIONS_PER_UNIT;
S3L_lookAt(scene.models[0].transform.translation,&(scene.camera.transform));
clearScreen();
S3L_newFrame();
S3L_drawScene(scene);
saveImage("allligator.ppm");
return 0;
}

View file

@ -140,7 +140,6 @@ void sampleTexture(uint8_t *texture, int w, int h, float x, float y, uint8_t col
color[0] = interpolate(interpolate(c0[0],c1[0],xFract),interpolate(c2[0],c3[0],xFract),yFract);
color[1] = interpolate(interpolate(c0[1],c1[1],xFract),interpolate(c2[1],c3[1],xFract),yFract);
color[2] = interpolate(interpolate(c0[2],c1[2],xFract),interpolate(c2[2],c3[2],xFract),yFract);
}
void drawPixel(S3L_PixelInfo *p)

View file

@ -282,6 +282,13 @@ typedef uint16_t S3L_Index;
#define S3L_NEAR 1 // Can't be <= 0.
#endif
#ifndef S3L_NORMAL_COMPUTE_MAXIMUM_AVERAGE
/** Affects the S3L_computeModelNormals function. See its description for
details. */
#define S3L_NORMAL_COMPUTE_MAXIMUM_AVERAGE 6
#endif
#ifndef S3L_FAST_LERP_QUALITY
/** Quality (scaling) of SOME (stepped) linear interpolations. 0 will most
likely be a tiny bit faster, but artifacts can occur for bigger tris, while
@ -570,7 +577,12 @@ void S3L_getIndexedTriangleValues(
sufficient size preallocated! The size is: number of model vertices * 3 *
sizeof(S3L_Unit). Note that for advanced allowing sharp edges it is not
sufficient to have per-vertex normals, but must be per-triangle. This
function doesn't support this. */
function doesn't support this.
The function computes a normal for each vertex by averaging normals of
the triangles containing the vertex. The maximum number of these triangle
normals that will be averaged is set with
S3L_NORMAL_COMPUTE_MAXIMUM_AVERAGE. */
void S3L_computeModelNormals(S3L_Model3D model, S3L_Unit *dst,
int8_t transformNormals);
@ -1019,16 +1031,14 @@ void S3L_computeModelNormals(S3L_Model3D model, S3L_Unit *dst,
n.w = 0;
#define MAX_NORMALS 6
S3L_Vec4 ns[MAX_NORMALS];
S3L_Vec4 ns[S3L_NORMAL_COMPUTE_MAXIMUM_AVERAGE];
S3L_Index normalCount;
for (S3L_Index i = 0; i < model.vertexCount; ++i)
for (uint32_t i = 0; i < model.vertexCount; ++i)
{
normalCount = 0;
for (S3L_Index j = 0; j < model.triangleCount * 3; j += 3)
for (uint32_t j = 0; j < model.triangleCount * 3; j += 3)
{
if (
(model.triangles[j] == i) ||
@ -1056,7 +1066,7 @@ void S3L_computeModelNormals(S3L_Model3D model, S3L_Unit *dst,
normalCount++;
if (normalCount >= MAX_NORMALS)
if (normalCount >= S3L_NORMAL_COMPUTE_MAXIMUM_AVERAGE)
break;
}
}
@ -1095,8 +1105,6 @@ void S3L_computeModelNormals(S3L_Model3D model, S3L_Unit *dst,
vPos++;
}
#undef MAX_NORMALS
S3L_Mat4 m;
S3L_makeWorldMatrix(model.transform,&m);
@ -1440,6 +1448,16 @@ S3L_Unit S3L_vec2Length(S3L_Vec4 v)
void S3L_normalizeVec3(S3L_Vec4 *v)
{
#define SCALE 16
v->x *= SCALE;
v->y *= SCALE;
v->z *= SCALE;
// ^ This pre-scale prevents inaccuracy with very small vectors ([1,1,1]).
#undef SCALE
S3L_Unit l = S3L_vec3Length(*v);
if (l == 0)

View file

@ -87,6 +87,8 @@ features:
bugs:
- obj tools still crosses the 80 column alignment limit (alligator model)
repeated:
- valgrind (and similar) checks