~rabbits/moogle

d97d2dea85e68c73d9a2114fed889a185d81297e — neauoire 11 months ago bed6c94
Fixed issue with export
3 files changed, 60 insertions(+), 104 deletions(-)

M README.md
M build.sh
M src/moogle.c
M README.md => README.md +2 -3
@@ 1,6 1,6 @@
# Moogle

A minimal wireframe viewer, written in ANSI C.
A minimal [wireframe renderer](https://wiki.xxiivv.com/site/moogle.html), written in ANSI C.

## Build



@@ 20,7 20,6 @@ cc moogle.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -L/usr/local/lib -lSDL2 -lm -o mo
### IO

- `E` Export(export.chr)
- `R` Render(render.bmp)
- `Z` Length Out
- `X` Length In



@@ 33,4 32,4 @@ cc moogle.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -L/usr/local/lib -lSDL2 -lm -o mo

## TODOs

- Add lathe effect.
\ No newline at end of file
- Add lathe effect.

M build.sh => build.sh +2 -2
@@ 10,10 10,10 @@ rm -f ./bin/moogle
mkdir -p bin

# debug(slow)
# cc -std=c89 -DDEBUG -Wall -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined src/moogle.c -L/usr/local/lib -lSDL2 -lm -o bin/moogle
cc -std=c89 -DDEBUG -Wall -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined src/moogle.c -L/usr/local/lib -lSDL2 -lm -o bin/moogle

# build(fast)
cc src/moogle.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -L/usr/local/lib -lSDL2 -lm -o bin/moogle
# cc src/moogle.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -L/usr/local/lib -lSDL2 -lm -o bin/moogle

# Size
echo "Size: $(du -sk ./bin/moogle)"

M src/moogle.c => src/moogle.c +56 -99
@@ 1,8 1,8 @@
#include <SDL2/SDL.h>
#include <stdio.h>
#include <math.h>
#include <stdio.h>

/* 
/*
Copyright (c) 2020 Devine Lu Linvega

Permission to use, copy, modify, and distribute this software for any


@@ 15,6 15,7 @@ WITH REGARD TO THIS SOFTWARE.

#define HOR 0x3c
#define VER 0x22
#define TITLE "out3cx22.icn"
#define SZ (HOR * VER * 8)

#define VLIMIT 256


@@ 51,10 52,8 @@ typedef struct {
	Mesh meshes[MLIMIT];
} Scene;

typedef enum {
	ISOMETRIC,
	PERSPECTIVE
} Projection;
typedef enum { ISOMETRIC,
	PERSPECTIVE } Projection;

typedef struct {
	double range;


@@ 68,8 67,8 @@ typedef struct {
} Mouse;

static int WIDTH = 8 * HOR;
static int HEIGHT = 8 * (VER + 2);
static int FPS = 30, GUIDES = 1, ZOOM = 1;
static int HEIGHT = 8 * VER;
static int FPS = 30, ZOOM = 1;

static Scene scn;
static Camera cam;


@@ 77,11 76,7 @@ static Mouse mouse;

/* interface */

static Uint32 theme[] = {
	0x000000,
	0XFFFFFF,
	0x72DEC2,
	0xFF0000};
static Uint32 theme[] = {0XFFFFFF, 0X000000, 0x55BBAA, 0xFF0000};

static SDL_Window *gWindow = NULL;
static SDL_Renderer *gRenderer = NULL;


@@ 344,7 339,7 @@ putpixel(Uint32 *dst, int x, int y, Uint32 color)
static Uint32
getpixel(Uint32 *src, int x, int y)
{
	if(x > 0 && y > 0 && x < WIDTH && y < HEIGHT)
	if(x < WIDTH && y < HEIGHT)
		return src[y * WIDTH + x];
	return 0;
}


@@ 378,8 373,7 @@ project(Camera *c, Point3d v)
{
	double r;
	if(c->projection == ISOMETRIC)
		return Pt2d(
			(WIDTH / 2) + v.x * (10 - c->range / 10),
		return Pt2d((WIDTH / 2) + v.x * (10 - c->range / 10),
			(HEIGHT / 2) + v.y * (10 - c->range / 10));
	r = 200 / (v.z + c->range);
	return Pt2d(WIDTH / 2 + r * v.x, HEIGHT / 2 + r * v.y);


@@ 398,10 392,7 @@ redraw(Uint32 *dst)
			Point3d b = add3d(edge->b, &m->position);
			rotate3d(&a, &cam.origin, &cam.rotation);
			rotate3d(&b, &cam.origin, &cam.rotation);
			line(dst,
				project(&cam, add3d(&cam.origin, &a)),
				project(&cam, add3d(&cam.origin, &b)),
				theme[edge->color]);
			line(dst, project(&cam, add3d(&cam.origin, &a)), project(&cam, add3d(&cam.origin, &b)), theme[edge->color]);
		}
	}
	SDL_UpdateTexture(gTexture, NULL, dst, WIDTH * sizeof(Uint32));


@@ 423,23 414,16 @@ static void
update(Camera *c, double speed)
{
	if(!equpt3d(c->rotation, c->trotation) || !equpt3d(c->origin, c->torigin)) {
		set3d(&c->rotation,
			interpolate(c->rotation.x, c->trotation.x, speed, 1),
			interpolate(c->rotation.y, c->trotation.y, speed, 1),
			interpolate(c->rotation.z, c->trotation.z, speed, 1));
		set3d(&c->origin,
			interpolate(c->origin.x, c->torigin.x, speed, 1),
			interpolate(c->origin.y, c->torigin.y, speed, 1),
			interpolate(c->origin.z, c->torigin.z, speed, 1));
		set3d(&c->rotation, interpolate(c->rotation.x, c->trotation.x, speed, 1), interpolate(c->rotation.y, c->trotation.y, speed, 1), interpolate(c->rotation.z, c->trotation.z, speed, 1));
		set3d(&c->origin, interpolate(c->origin.x, c->torigin.x, speed, 1), interpolate(c->origin.y, c->torigin.y, speed, 1), interpolate(c->origin.z, c->torigin.z, speed, 1));
		redraw(pixels);
	}
}

static void
modzoom(int mod)
setzoom(int val)
{
	if((mod > 0 && ZOOM < 4) || (mod < 0 && ZOOM > 1))
		ZOOM += mod;
	ZOOM = val;
	SDL_SetWindowSize(gWindow, WIDTH * ZOOM, HEIGHT * ZOOM);
	redraw(pixels);
}


@@ 452,13 436,6 @@ toggleprojection(Camera *c)
}

static void
setguides(int v)
{
	GUIDES = v;
	redraw(pixels);
}

static void
modrange(int mod)
{
	int res = cam.range + mod;


@@ 477,8 454,8 @@ export_icn(Uint32 *src, int width, int height, char *filename)
	for(i = 0; i < SZ; ++i)
		icnbuf[i] = 0;
	/* write pixels */
	for(y = 0; y < height; ++y) {
		for(x = 0; x < width; ++x) {
	for(y = 0; y < height; y++) {
		for(x = 0; x <= width; x++) {
			int color = getpixel(src, x, y);
			if(color) {
				int col = x & 7, row = y & 7;


@@ 496,19 473,6 @@ export_icn(Uint32 *src, int width, int height, char *filename)
}

static void
export_bmp(char *filename)
{
	int w, h;
	SDL_Surface *surface;
	SDL_GetRendererOutputSize(gRenderer, &w, &h);
	surface = SDL_CreateRGBSurfaceWithFormat(0, w, h, 24, SDL_PIXELFORMAT_RGB24);
	SDL_RenderReadPixels(gRenderer, NULL, SDL_PIXELFORMAT_RGB24, surface->pixels, surface->pitch);
	SDL_SaveBMP(surface, filename);
	SDL_FreeSurface(surface);
	fprintf(stderr, "Saved %s\n", filename);
}

static void
quit(void)
{
	free(pixels);


@@ 525,19 489,27 @@ quit(void)
static void
dokey(SDL_Event *event)
{
	int shift = SDL_GetModState() & KMOD_LSHIFT || SDL_GetModState() & KMOD_RSHIFT;
	int shift =
		SDL_GetModState() & KMOD_LSHIFT || SDL_GetModState() & KMOD_RSHIFT;
	switch(event->key.keysym.sym) {
	case SDLK_EQUALS:
	case SDLK_PLUS: modzoom(1); break;
	case SDLK_UNDERSCORE:
	case SDLK_MINUS: modzoom(-1); break;
	case SDLK_TAB: toggleprojection(&cam); break;
	case SDLK_1: set3d(&cam.trotation, VIEWFRONT.x, VIEWFRONT.y, VIEWFRONT.z); break;
	case SDLK_2: set3d(&cam.trotation, VIEWTOP.x, VIEWTOP.y, VIEWTOP.z); break;
	case SDLK_3: set3d(&cam.trotation, VIEWSIDE.x, VIEWSIDE.y, VIEWSIDE.z); break;
	case SDLK_e: export_icn(pixels, WIDTH, HEIGHT, "untitled.icn"); break;
	case SDLK_r: export_bmp("untitled.bmp"); break;
	case SDLK_h: setguides(!GUIDES); break;
	case SDLK_F1:
		setzoom((ZOOM == 1) + 1);
		break;
	case SDLK_TAB:
		toggleprojection(&cam);
		break;
	case SDLK_1:
		set3d(&cam.trotation, VIEWFRONT.x, VIEWFRONT.y, VIEWFRONT.z);
		break;
	case SDLK_2:
		set3d(&cam.trotation, VIEWTOP.x, VIEWTOP.y, VIEWTOP.z);
		break;
	case SDLK_3:
		set3d(&cam.trotation, VIEWSIDE.x, VIEWSIDE.y, VIEWSIDE.z);
		break;
	case SDLK_e:
		export_icn(pixels, WIDTH, HEIGHT, TITLE);
		break;
	case SDLK_UP:
	case SDLK_w:
		if(shift)


@@ 591,22 563,13 @@ init(void)
{
	if(SDL_Init(SDL_INIT_VIDEO) < 0)
		return error("Init", SDL_GetError());
	gWindow = SDL_CreateWindow("Moogle",
		SDL_WINDOWPOS_UNDEFINED,
		SDL_WINDOWPOS_UNDEFINED,
		WIDTH * ZOOM,
		HEIGHT * ZOOM,
		SDL_WINDOW_SHOWN);
	gWindow = SDL_CreateWindow("Moogle", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH * ZOOM, HEIGHT * ZOOM, SDL_WINDOW_SHOWN);
	if(gWindow == NULL)
		return error("Window", SDL_GetError());
	gRenderer = SDL_CreateRenderer(gWindow, -1, 0);
	if(gRenderer == NULL)
		return error("Renderer", SDL_GetError());
	gTexture = SDL_CreateTexture(gRenderer,
		SDL_PIXELFORMAT_ARGB8888,
		SDL_TEXTUREACCESS_STATIC,
		WIDTH,
		HEIGHT);
	gTexture = SDL_CreateTexture(gRenderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, WIDTH, HEIGHT);
	if(gTexture == NULL)
		return error("Texture", SDL_GetError());
	pixels = (Uint32 *)malloc(WIDTH * HEIGHT * sizeof(Uint32));


@@ 653,15 616,9 @@ extrude(Mesh *m, double x, double y, double z, int color)
{
	int i, vl = m->verticeslen, el = m->edgeslen;
	for(i = 0; i < vl; i++)
		addedge(m,
			&m->vertices[i],
			addvertex(m, m->vertices[i].x + x, m->vertices[i].y + y, m->vertices[i].z + z),
			color);
		addedge(m, &m->vertices[i], addvertex(m, m->vertices[i].x + x, m->vertices[i].y + y, m->vertices[i].z + z), color);
	for(i = 0; i < el; i++)
		addedge(m,
			&m->vertices[vl + m->edges[i].a - &m->vertices[0]],
			&m->vertices[vl + m->edges[i].b - &m->vertices[0]],
			color);
		addedge(m, &m->vertices[vl + m->edges[i].a - &m->vertices[0]], &m->vertices[vl + m->edges[i].b - &m->vertices[0]], color);
	return m;
}



@@ 670,13 627,11 @@ symmetry(Mesh *m, double x, double y, double z, int color)
{
	int i, el = m->edgeslen, vl = m->verticeslen;
	for(i = 0; i < vl; ++i)
		m->vertices[vl + i] = Pt3d(m->vertices[i].x * x, m->vertices[i].y * y, m->vertices[i].z * z);
		m->vertices[vl + i] =
			Pt3d(m->vertices[i].x * x, m->vertices[i].y * y, m->vertices[i].z * z);
	m->verticeslen += vl;
	for(i = 0; i < el; i++)
		addedge(m,
			&m->vertices[vl + m->edges[i].a - &m->vertices[0]],
			&m->vertices[vl + m->edges[i].b - &m->vertices[0]],
			color);
		addedge(m, &m->vertices[vl + m->edges[i].a - &m->vertices[0]], &m->vertices[vl + m->edges[i].b - &m->vertices[0]], color);
	return m;
}



@@ 753,15 708,9 @@ createplane(Scene *s, double width, double height, double xsegs, double ysegs, i
	int ix, iy;
	Mesh *m = addmesh(s);
	for(ix = 0; ix < xsegs + 1; ix++)
		addline(m,
			Pt3d(ix * (width / xsegs) - width / 2, height / 2, 0),
			Pt3d(ix * (width / xsegs) - width / 2, -height / 2, 0),
			color);
		addline(m, Pt3d(ix * (width / xsegs) - width / 2, height / 2, 0), Pt3d(ix * (width / xsegs) - width / 2, -height / 2, 0), color);
	for(iy = 0; iy < ysegs + 1; iy++)
		addline(m,
			Pt3d(width / 2, iy * (height / ysegs) - height / 2, 0),
			Pt3d(-width / 2, iy * (height / ysegs) - height / 2, 0),
			color);
		addline(m, Pt3d(width / 2, iy * (height / ysegs) - height / 2, 0), Pt3d(-width / 2, iy * (height / ysegs) - height / 2, 0), color);
	return m;
}



@@ 840,7 789,11 @@ main(void)
	cam = Cm3d(180, 0, 0, 30);
	if(!init())
		return error("Init", "Failure");

	createumbrella(&scn);

	/* Begin */

	redraw(pixels);
	while(1) {
		int tick = SDL_GetTicks();


@@ 851,7 804,9 @@ main(void)
		update(&cam, 5);
		while(SDL_PollEvent(&event) != 0) {
			switch(event.type) {
			case SDL_QUIT: quit(); break;
			case SDL_QUIT:
				quit();
				break;
			case SDL_MOUSEWHEEL:
				modrange(event.wheel.y / -1);
				break;


@@ 867,7 822,9 @@ main(void)
				if(mouse.down)
					addpt3d(&cam.trotation, (event.motion.y - mouse.y) / 4, (event.motion.x - mouse.x) / 4, 0);
				break;
			case SDL_KEYDOWN: dokey(&event); break;
			case SDL_KEYDOWN:
				dokey(&event);
				break;
			case SDL_WINDOWEVENT:
				if(event.window.event == SDL_WINDOWEVENT_EXPOSED)
					redraw(pixels);