first commit
This commit is contained in:
commit
149ab4c305
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/perspective
|
||||
*.o
|
10
Makefile
Normal file
10
Makefile
Normal 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
200
main.c
Normal 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();
|
||||
}
|
Loading…
Reference in New Issue
Block a user