first commit

This commit is contained in:
corey 2024-07-04 07:33:24 -05:00
commit 149ab4c305
3 changed files with 212 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/perspective
*.o

10
Makefile Normal file
View File

@ -0,0 +1,10 @@
CFLAGS= -Wfatal-errors -Wall -Wextra $(shell pkgconf --cflags sdl2)
LDFLAGS= -s $(shell pkgconf --libs sdl2)
all: perspective
perspective: main.o
$(CC) $^ -o $@ $(LDFLAGS)
%.o: %.c
$(CC) -c $^ -o $@ $(CFLAGS)
clean:
$(RM) *.o perspective

200
main.c Normal file
View File

@ -0,0 +1,200 @@
/*******
* Convert 3d points into 2d points
* and display them to the screen
*******/
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdint.h>
#include<stdbool.h>
#include<SDL2/SDL.h>
typedef struct Point3d
{
float x;
float y;
float z;
} Point3d;
typedef struct Quad
{
Point3d p[4];
} Quad;
typedef struct Point2d
{
float x;
float y;
} Point2d;
typedef struct Cube
{
float x;
float y;
float z;
float w;
float h;
float d;
} Cube;
Point2d rasterize(Point3d cam,Point3d p)
{
Point2d p2={0};
if(!p.z)return p2; // divide by zero error
/* p2.x=-p.x/p.z; */
/* p2.y=-p.y/p.z; */
p2.x=(p.x-cam.x)/(p.z-cam.z);
p2.y=(p.y-cam.y)/(p.z-cam.z);
return p2;
}
void print_point3d(Point3d p)
{
printf("(%g,%g,%g)\n",p.x,p.y,p.z);
}
void print_point2d(Point2d p)
{
printf("(%g,%g)\n",p.x,p.y);
}
#define cube_wire(cam,r)\
do{\
if(r.z>cam.z){\
Point2d _p[4];\
Point3d _p3[4];\
_p3[0]=(Point3d){.x=r.x,.y=r.y,.z=r.z};\
_p3[1]=(Point3d){.x=r.x+r.w,.y=r.y,.z=r.z};\
_p3[2]=(Point3d){.x=r.x,.y=r.y+r.h,.z=r.z};\
_p3[3]=(Point3d){.x=r.x+r.w,.y=r.y+r.h,.z=r.z};\
for(int i=0;i<4;++i)\
_p[i]=rasterize(cam,_p3[i]);\
SDL_RenderDrawLine(ren,width/2+_p[0].x,height/2-_p[0].y,width/2+_p[1].x,height/2-_p[1].y);\
SDL_RenderDrawLine(ren,width/2+_p[2].x,height/2-_p[2].y,width/2+_p[3].x,height/2-_p[3].y);\
SDL_RenderDrawLine(ren,width/2+_p[0].x,height/2-_p[0].y,width/2+_p[2].x,height/2-_p[2].y);\
SDL_RenderDrawLine(ren,width/2+_p[1].x,height/2-_p[1].y,width/2+_p[3].x,height/2-_p[3].y);\
}\
}while(0)
int main(void)
{
Point2d p2;
Point3d p3={.x=2,.y=3,.z=1};
Point3d cam={0};
Quad q1;
Quad q2;
SDL_Renderer*ren;
SDL_Window*win;
bool running=true;
const int height=240;
const int width=320;
Cube cube={.x=5,.y=4,.w=20,.h=20,.z=1};
Cube cube2={.x=5,.y=4,.w=20,.h=20,.z=2};
// Init SDL
SDL_Init(SDL_INIT_EVERYTHING);
win=SDL_CreateWindow("",SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,width,height,0);
ren=SDL_CreateRenderer(win,-1,0);
q1.p[0]=(Point3d){.x=1,.y=20,.z=1};
q1.p[1]=(Point3d){.x=20,.y=20,.z=1};
q1.p[2]=(Point3d){.x=1,.y=1,.z=1};
q1.p[3]=(Point3d){.x=20,.y=1,.z=1};
q2.p[0]=(Point3d){.x=1,.y=20,.z=2};
q2.p[1]=(Point3d){.x=20,.y=20,.z=2};
q2.p[2]=(Point3d){.x=1,.y=1,.z=2};
q2.p[3]=(Point3d){.x=20,.y=1,.z=2};
/* for(int i=0;i<4;++i) */
/* { */
/* Point2d p=rasterize(q1.p[i]); */
/* print_point2d(p); */
/* } */
// Convert points
print_point3d(p3);
p2=rasterize(cam,p3);
print_point2d(p2);
// Event loop
while(running)
{
SDL_Event evt;
// Check events
if(SDL_PollEvent(&evt))
{
switch(evt.type)
{
case SDL_QUIT:running=false;break;
case SDL_KEYDOWN:
switch(evt.key.keysym.sym)
{
case SDLK_ESCAPE:
case SDLK_q:
running=false;
break;
case SDLK_LEFT:--cam.x;break;
case SDLK_RIGHT:++cam.x;break;
case SDLK_UP:++cam.y;break;
case SDLK_DOWN:--cam.y;break;
case SDLK_w:cam.z+=0.1;break;
case SDLK_s:cam.z-=0.1;break;
}
break;
}
}
// Render
SDL_SetRenderDrawColor(ren,0,0,0,0);
SDL_RenderClear(ren);
SDL_SetRenderDrawColor(ren,128,128,128,0);
SDL_RenderDrawLine(ren,width/2,0,width/2,height);
SDL_RenderDrawLine(ren,0,height/2,width,height/2);
// Draw points
SDL_SetRenderDrawColor(ren,255,255,255,0);
/* SDL_RenderDrawPoint(ren,p2.x,p2.y); */
/* for(int i=0;i<4;++i) */
/* { */
/* Point2d p; */
/* p=rasterize(q1.p[i]); */
/* SDL_RenderDrawPoint(ren,width/2+p.x,height/2-p.y); */
/* */
/* p=rasterize(q2.p[i]); */
/* SDL_RenderDrawPoint(ren,width/2+p.x,height/2-p.y); */
/* } */
/* SDL_SetRenderDrawColor(ren,255,255,255,0); */
/* quad_wire(q1); */
/* SDL_SetRenderDrawColor(ren,192,192,192,0); */
/* quad_wire(q2); */
SDL_SetRenderDrawColor(ren,255,255,255,0);
cube_wire(cam,cube);
SDL_SetRenderDrawColor(ren,192,192,192,0);
cube_wire(cam,cube2);
SDL_RenderPresent(ren);
usleep(20000);
}
// Quit
if(win)SDL_DestroyWindow(win);
if(ren)SDL_DestroyRenderer(ren);
SDL_Quit();
}