~zjm/Moon3D

78eb4f7f9f0bd9b78d4b5cc9e9c40813ba04dc0b — Zack Michener a month ago 6644240
add a camera
2 files changed, 93 insertions(+), 26 deletions(-)

M src/everything.h
M src/game.c
M src/everything.h => src/everything.h +30 -15
@@ 88,19 88,6 @@ typedef struct ClipPlanes {
	Plane z_pos;
} ClipPlanes;

typedef struct Renderer {
	Pixel *pixels;
	DepthVal *depthBuffer;
	int width;
	int height;
	Transform projectionTransform;
	Transform deviceTransform;
	Vertex *vertex_pool;
	int *polygon_pool;
	int *alt_polygon_pool;
	ClipPlanes clip_planes;
} Renderer;

typedef struct Model {
	Vector position;
	Transform transform;


@@ 132,13 119,38 @@ typedef struct Particle {
	Vector acceleration;
} Particle;

typedef struct Camera {
	Model *model;
	Physics *physics;
	Transform transform;
	double fov;
	double aspect;
	double x_cotan;
	double y_cotan;
	double near;
	double far;
} Camera;

typedef struct Renderer {
	Pixel *pixels;
	DepthVal *depthBuffer;
	int width;
	int height;
	Camera *camera;
	Transform deviceTransform;
	Vertex *vertex_pool;
	int *polygon_pool;
	int *alt_polygon_pool;
	ClipPlanes clip_planes;
} Renderer;

typedef struct Scene {
	Camera *camera;
	SceneObject *objects;
	Renderable *renderable_pool;
	Physics *physics_pool;
	Model *model_pool;
	Particle *particles;
	Renderer *renderer;
} Scene;

Scene *MoonWorld(void);


@@ 155,7 167,7 @@ SceneObject *NewSceneObject(SceneObject *pool, Model *model, Renderable *rendera
void InitParticleSystem(Scene *scene);
Particle *NewParticlePool(void);
Particle *AddParticle(Particle *pool, Vertex v);
Renderer *NewRenderer(Pixel *pixels, int width, int height);
Renderer *NewRenderer(Pixel *pixels, int width, int height, Camera *camera);
void ClearScreen(Renderer *renderer);
DepthVal *NewDepthBuffer(int width, int height);
Transform PerspectiveTransform(double fov, double aspect, double near, double far);


@@ 197,3 209,6 @@ void PlaceObject(SceneObject *obj, Vector p);
Model *NewModel(Model *pool);
void DumpMesh(Mesh *mesh);
void SpinObject(SceneObject *obj, double rx, double ry, double rz);
Camera *NewCamera(double fov, double aspect, double near, double far, Model *model, Physics *physics);
void SetCamera(Camera *camera, double fov, double aspect, double near, double far);
void ZoomIn(Camera *camera, double amt);

M src/game.c => src/game.c +63 -11
@@ 39,7 39,7 @@ int main(void)
			SDL_bool done = SDL_FALSE;

			Scene *scene = MoonWorld();
			Renderer *gameRenderer = NewRenderer(pixels, SCREEN_WIDTH, SCREEN_HEIGHT);
			Renderer *gameRenderer = NewRenderer(pixels, SCREEN_WIDTH, SCREEN_HEIGHT, scene->camera);

			long frames = 0;
			long start = SDL_GetTicks();


@@ 85,6 85,7 @@ int main(void)
Scene *MoonWorld(void)
{
	Scene *scene = NewScene();
	Translate(&(scene->camera->transform), V(0, 0, -5));
	SceneObject *cube = CreateSceneObject(scene, "assets/cube.obj", BLACK);
	// ScaleObject(cube, 10, 10, 10);
	SpinObject(cube, 0, 0.1, 0);


@@ 113,6 114,10 @@ Scene *NewScene(void)
	scene->physics_pool = NewPool(Physics, MAX_SCENE_OBJECTS);
	scene->model_pool = NewPool(Model, MAX_SCENE_OBJECTS);
	scene->particles = NULL;
	Model *cameraModel = NewModel(scene->model_pool);
	Physics *cameraPhysics = NewPhysics(scene->physics_pool, cameraModel,
			V(0, 0, 0), V(0, 0, 0), V(0, 0, 0));
	scene->camera = NewCamera(20, 1, 1, 100, cameraModel, cameraPhysics);
	return scene;
}



@@ 276,17 281,18 @@ Particle *AddParticle(Particle *pool, Vertex v)
	return p;
}

Renderer *NewRenderer(Pixel *pixels, int width, int height)
Renderer *NewRenderer(Pixel *pixels, int width, int height, Camera *camera)
{
	Renderer *r = malloc(sizeof(Renderer));
	r->pixels = pixels;
	r->depthBuffer = NewDepthBuffer(width, height);
	r->width = width;
	r->height = height;

	r->projectionTransform = PerspectiveTransform(20, (double)width/(double)height, 1, 100);
	r->camera = camera;
	/* update aspect ratio */
	SetCamera(camera, camera->fov, (float)width/(float)height, camera->near, camera->far);
	r->deviceTransform = Translation(V(1, 1, 0));
	// Scale to viewport size
	/* scale to viewport size */
	Scale(&(r->deviceTransform), 0.5*(width-1), 0.5*(height-1), 1);

	r->vertex_pool = NewPool(Vertex, MAX_RENDER_VERTICES);


@@ 326,15 332,44 @@ DepthVal *NewDepthBuffer(int width, int height)
	return values;
}

Camera *NewCamera(double fov, double aspect, double near, double far, Model *model, Physics *physics)
{
	Camera *camera = malloc(sizeof(Camera));
	camera->model = model;
	camera->physics = physics;
	camera->transform = Identity();
	camera->fov = fov;
	camera->aspect = aspect;
	camera->x_cotan = 1/(aspect * tan(fov/2));
	camera->y_cotan = 1/tan(fov/2);
	camera->near = near;
	camera->far = far;
	return camera;
}

void SetCamera(Camera *camera, double fov, double aspect, double near, double far)
{
	camera->fov = fov;
	camera->aspect = aspect;
	camera->x_cotan = 1/(aspect * tan(fov/2));
	camera->y_cotan = 1/tan(fov/2);
	camera->near = near;
	camera->far = far;
}

void ZoomIn(Camera *camera, double amt)
{
	camera->fov *= 1/(amt/100000 + 1);
	camera->x_cotan = 1/(camera->aspect * tan(camera->fov/2));
	camera->y_cotan = 1/tan(camera->fov/2);
}

Transform PerspectiveTransform(double fov, double aspect, double near, double far)
{
	Transform op, t;

	t = Identity();

	// manual camera placement
	Translate(&t, V(0, 0, -5));

	// perspective transform into canonical view volume
	op = Identity();
	op.m[0][0] = 1/(aspect * tan(fov/2));


@@ 348,6 383,25 @@ Transform PerspectiveTransform(double fov, double aspect, double near, double fa
	return t;
}

Transform CameraTransform(Camera *camera)
{
	Transform op, t;

	t = FromTransform(camera->transform);

	/* perspective transform into canonical view volume */
	op = Identity();
	op.m[0][0] = camera->x_cotan;
	op.m[1][1] = camera->y_cotan;
	op.m[2][2] = (camera->far + camera->near) / (camera->far - camera->near);
	op.m[3][3] = 0;
	op.m[2][3] = (2*camera->far*camera->near) / (camera->far - camera->near);
	op.m[3][2] = -1;
	AddTransform(op, &t);

	return t;
}

Vertex *NewVertex(Vertex *pool)
{
	assert(PoolTotal(pool) < MAX_RENDER_VERTICES);


@@ 451,9 505,7 @@ void ModelVertex(Vertex *vertex, Model *model)

void ProjectVertex(Vertex *vertex, Renderer *renderer)
{
	// Transform camera_transform = CameraTransform(camera);
	// AddTransform(renderer->projectionTransform, &camera_transform);
	CommitTransform(renderer->projectionTransform, vertex);
	CommitTransform(CameraTransform(renderer->camera), vertex);
}

int *NewPolygon(int *pool)