newpoly

changeset 0:224206bc554a tip

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 15 Dec 2017 09:24:39 +0200
parents
children
files .hgignore Makefile src/main.c src/mgl.c src/mgl.h src/poly.c src/poly.h
diffstat 7 files changed, 339 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgignore	Fri Dec 15 09:24:39 2017 +0200
     1.3 @@ -0,0 +1,4 @@
     1.4 +\.o$
     1.5 +\.swp$
     1.6 +\.d$
     1.7 +^test$
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/Makefile	Fri Dec 15 09:24:39 2017 +0200
     2.3 @@ -0,0 +1,23 @@
     2.4 +src = $(wildcard src/*.c)
     2.5 +obj = $(src:.c=.o)
     2.6 +dep = $(obj:.o=.d)
     2.7 +bin = test
     2.8 +
     2.9 +CFLAGS = -pedantic -Wall -g `sdl-config --cflags`
    2.10 +LDFLAGS = `sdl-config --libs`
    2.11 +
    2.12 +$(bin): $(obj)
    2.13 +	$(CC) -o $@ $(obj) $(LDFLAGS)
    2.14 +
    2.15 +-include $(dep)
    2.16 +
    2.17 +%.d: %.c
    2.18 +	@$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@
    2.19 +
    2.20 +.PHONY: clean
    2.21 +clean:
    2.22 +	rm -f $(obj) $(bin)
    2.23 +
    2.24 +.PHONY: cleandep
    2.25 +cleandep:
    2.26 +	rm -f $(dep)
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/main.c	Fri Dec 15 09:24:39 2017 +0200
     3.3 @@ -0,0 +1,154 @@
     3.4 +#include <stdio.h>
     3.5 +#include <stdlib.h>
     3.6 +#include <string.h>
     3.7 +#include <stdint.h>
     3.8 +#include <SDL/SDL.h>
     3.9 +#include "poly.h"
    3.10 +#include "mgl.h"
    3.11 +
    3.12 +int init(void);
    3.13 +void cleanup(void);
    3.14 +void draw(void);
    3.15 +void process_event(SDL_Event *ev);
    3.16 +void handle_key_event(int key, int pressed);
    3.17 +
    3.18 +int win_width, win_height;
    3.19 +int fb_width = 80, fb_height = 60;
    3.20 +int fb_scale = 16;
    3.21 +uint32_t *fb_pixels;
    3.22 +SDL_Surface *surf;
    3.23 +int quit;
    3.24 +
    3.25 +int opt_grid = 1;
    3.26 +
    3.27 +int main(int argc, char **argv)
    3.28 +{
    3.29 +	win_width = fb_width * fb_scale;
    3.30 +	win_height = fb_height * fb_scale;
    3.31 +
    3.32 +	if(SDL_Init(SDL_INIT_VIDEO) == -1) {
    3.33 +		return 1;
    3.34 +	}
    3.35 +
    3.36 +	if(!(surf = SDL_SetVideoMode(win_width, win_height, 32, SDL_SWSURFACE))) {
    3.37 +		fprintf(stderr, "failed to set video mode: %dx%d\n", win_width, win_height);
    3.38 +		return 1;
    3.39 +	}
    3.40 +	SDL_WM_SetCaption("anotherpoly", 0);
    3.41 +
    3.42 +	if(init() == -1) {
    3.43 +		return 1;
    3.44 +	}
    3.45 +
    3.46 +	for(;;) {
    3.47 +		SDL_Event ev;
    3.48 +		while(SDL_PollEvent(&ev)) {
    3.49 +			process_event(&ev);
    3.50 +			if(quit) goto done;
    3.51 +		}
    3.52 +
    3.53 +		draw();
    3.54 +	}
    3.55 +
    3.56 +done:
    3.57 +	cleanup();
    3.58 +	SDL_Quit();
    3.59 +	return 0;
    3.60 +}
    3.61 +
    3.62 +
    3.63 +int init(void)
    3.64 +{
    3.65 +	if(!(fb_pixels = malloc(fb_width * fb_height * sizeof *fb_pixels))) {
    3.66 +		perror("failed to allocate framebuffer");
    3.67 +		return -1;
    3.68 +	}
    3.69 +	if(polyfill_framebuffer(fb_pixels, fb_width, fb_height) == -1) {
    3.70 +		return -1;
    3.71 +	}
    3.72 +
    3.73 +	return 0;
    3.74 +}
    3.75 +
    3.76 +void cleanup(void)
    3.77 +{
    3.78 +	free(fb_pixels);
    3.79 +}
    3.80 +
    3.81 +void draw(void)
    3.82 +{
    3.83 +	int i, j;
    3.84 +	uint32_t *dest, *src;
    3.85 +
    3.86 +	memset(fb_pixels, 0, fb_width * fb_height * sizeof *fb_pixels);
    3.87 +
    3.88 +	mgl_begin(MGL_TRIANGLES);
    3.89 +	mgl_vertex3f(40, 8, 0);
    3.90 +	mgl_vertex3f(15, 35, 0);
    3.91 +	mgl_vertex3f(65, 50, 0);
    3.92 +	mgl_end();
    3.93 +
    3.94 +	if(SDL_MUSTLOCK(surf)) {
    3.95 +		SDL_LockSurface(surf);
    3.96 +	}
    3.97 +	dest = surf->pixels;
    3.98 +	src = fb_pixels;
    3.99 +
   3.100 +	for(i=0; i<win_height; i++) {
   3.101 +		if(opt_grid && (i % fb_scale) == 0) {
   3.102 +			memset(dest, 0x40, win_width * sizeof *dest);
   3.103 +			dest += win_width;
   3.104 +			continue;
   3.105 +		}
   3.106 +		for(j=0; j<win_width; j++) {
   3.107 +			if(opt_grid && (j % fb_scale) == 0) {
   3.108 +				*dest++ = 0x40404040;
   3.109 +			} else {
   3.110 +				*dest++ = src[j / fb_scale];
   3.111 +			}
   3.112 +		}
   3.113 +		if(i % fb_scale == fb_scale - 1) {
   3.114 +			src += fb_width;
   3.115 +		}
   3.116 +	}
   3.117 +
   3.118 +	if(SDL_MUSTLOCK(surf)) {
   3.119 +		SDL_UnlockSurface(surf);
   3.120 +	}
   3.121 +
   3.122 +	SDL_Flip(surf);
   3.123 +}
   3.124 +
   3.125 +void process_event(SDL_Event *ev)
   3.126 +{
   3.127 +	switch(ev->type) {
   3.128 +	case SDL_QUIT:
   3.129 +		quit = 1;
   3.130 +		break;
   3.131 +
   3.132 +	case SDL_KEYDOWN:
   3.133 +		handle_key_event(ev->key.keysym.sym, 1);
   3.134 +		break;
   3.135 +
   3.136 +	default:
   3.137 +		break;
   3.138 +	}
   3.139 +}
   3.140 +
   3.141 +void handle_key_event(int key, int pressed)
   3.142 +{
   3.143 +	if(pressed) {
   3.144 +		switch(key) {
   3.145 +		case SDLK_ESCAPE:
   3.146 +			quit = 1;
   3.147 +			break;
   3.148 +
   3.149 +		case 'g':
   3.150 +			opt_grid = !opt_grid;
   3.151 +			break;
   3.152 +
   3.153 +		default:
   3.154 +			break;
   3.155 +		}
   3.156 +	}
   3.157 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/mgl.c	Fri Dec 15 09:24:39 2017 +0200
     4.3 @@ -0,0 +1,75 @@
     4.4 +#include "mgl.h"
     4.5 +#include "poly.h"
     4.6 +
     4.7 +struct vertex {
     4.8 +	int32_t x, y, z;
     4.9 +	int32_t u, v;
    4.10 +};
    4.11 +
    4.12 +static void proc_prim(void);
    4.13 +
    4.14 +static int cur_prim;
    4.15 +static int vidx;
    4.16 +static struct vertex varr[4];
    4.17 +static int32_t cur_u, cur_v;
    4.18 +
    4.19 +void mgl_begin(int prim)
    4.20 +{
    4.21 +	cur_prim = prim;
    4.22 +	vidx = 0;
    4.23 +}
    4.24 +
    4.25 +void mgl_end(void)
    4.26 +{
    4.27 +	if(cur_prim) {
    4.28 +		proc_prim();
    4.29 +	}
    4.30 +	cur_prim = 0;
    4.31 +}
    4.32 +
    4.33 +void mgl_vertex3f(float x, float y, float z)
    4.34 +{
    4.35 +	mgl_vertex3x((int32_t)(x * 65536.0f), (int32_t)(y * 65536.0f), (int32_t)(z * 65536.0f));
    4.36 +}
    4.37 +
    4.38 +void mgl_vertex3x(int32_t x, int32_t y, int32_t z)
    4.39 +{
    4.40 +	varr[vidx].x = x;
    4.41 +	varr[vidx].y = y;
    4.42 +	varr[vidx].z = z;
    4.43 +	varr[vidx].u = cur_u;
    4.44 +	varr[vidx].v = cur_v;
    4.45 +
    4.46 +	if(++vidx >= cur_prim) {
    4.47 +		proc_prim();
    4.48 +		vidx = 0;
    4.49 +	}
    4.50 +}
    4.51 +
    4.52 +void mgl_texcoord2f(float u, float v)
    4.53 +{
    4.54 +	cur_u = (int32_t)(u * 65536.0);
    4.55 +	cur_v = (int32_t)(v * 65536.0);
    4.56 +}
    4.57 +
    4.58 +void mgl_texcoord2x(int32_t u, int32_t v)
    4.59 +{
    4.60 +	cur_u = u;
    4.61 +	cur_v = v;
    4.62 +}
    4.63 +
    4.64 +void proc_prim(void)
    4.65 +{
    4.66 +	int i;
    4.67 +	struct poly_vertex v[4];
    4.68 +
    4.69 +	for(i=0; i<cur_prim; i++) {
    4.70 +		v[i].x = varr[i].x;
    4.71 +		v[i].y = varr[i].y;
    4.72 +		v[i].z = varr[i].z;
    4.73 +		v[i].u = varr[i].u;
    4.74 +		v[i].v = varr[i].v;
    4.75 +	}
    4.76 +
    4.77 +	polyfill_flat(v, cur_prim);
    4.78 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/src/mgl.h	Fri Dec 15 09:24:39 2017 +0200
     5.3 @@ -0,0 +1,21 @@
     5.4 +#ifndef MGL_H_
     5.5 +#define MGL_H_
     5.6 +
     5.7 +#include <stdint.h>
     5.8 +
     5.9 +enum {
    5.10 +	MGL_POINTS = 1,
    5.11 +	MGL_LINES = 2,
    5.12 +	MGL_TRIANGLES = 3,
    5.13 +	MGL_QUADS = 4
    5.14 +};
    5.15 +
    5.16 +void mgl_begin(int prim);
    5.17 +void mgl_end(void);
    5.18 +
    5.19 +void mgl_vertex3f(float x, float y, float z);
    5.20 +void mgl_vertex3x(int32_t x, int32_t y, int32_t z);
    5.21 +void mgl_texcoord2f(float u, float v);
    5.22 +void mgl_texcoord2x(int32_t u, int32_t v);
    5.23 +
    5.24 +#endif	/* MGL_H_ */
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/poly.c	Fri Dec 15 09:24:39 2017 +0200
     6.3 @@ -0,0 +1,47 @@
     6.4 +#include <stdio.h>
     6.5 +#include <stdlib.h>
     6.6 +#include <string.h>
     6.7 +#include "poly.h"
     6.8 +
     6.9 +static uint32_t *fb_pixels;
    6.10 +static int fb_width, fb_height;
    6.11 +static unsigned int *scanoffs;
    6.12 +static int scanoffs_size;
    6.13 +
    6.14 +int polyfill_framebuffer(void *fb, int width, int height)
    6.15 +{
    6.16 +	int i;
    6.17 +	unsigned int offs = 0;
    6.18 +
    6.19 +	if(height > scanoffs_size) {
    6.20 +		free(scanoffs);
    6.21 +		scanoffs_size = height;
    6.22 +		if(!(scanoffs = malloc(scanoffs_size * sizeof *scanoffs))) {
    6.23 +			perror("failed to allocate scanline offset table");
    6.24 +			return -1;
    6.25 +		}
    6.26 +	}
    6.27 +
    6.28 +	for(i=0; i<height; i++) {
    6.29 +		scanoffs[i] = offs;
    6.30 +		offs += width;
    6.31 +	}
    6.32 +
    6.33 +	fb_pixels = fb;
    6.34 +	fb_width = width;
    6.35 +	fb_height = height;
    6.36 +
    6.37 +	return 0;
    6.38 +}
    6.39 +
    6.40 +void polyfill_flat(struct poly_vertex *varr, int vcount)
    6.41 +{
    6.42 +	int i;
    6.43 +
    6.44 +	for(i=0; i<vcount; i++) {
    6.45 +		int x = varr[i].x >> 16;
    6.46 +		int y = varr[i].y >> 16;
    6.47 +
    6.48 +		fb_pixels[scanoffs[y] + x] = 0xff0000;
    6.49 +	}
    6.50 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/poly.h	Fri Dec 15 09:24:39 2017 +0200
     7.3 @@ -0,0 +1,15 @@
     7.4 +#ifndef POLY_H_
     7.5 +#define POLY_H_
     7.6 +
     7.7 +#include <stdint.h>
     7.8 +
     7.9 +struct poly_vertex {
    7.10 +	int32_t x, y, z;	/* 16.16 */
    7.11 +	int32_t u, v;		/* 16.16 */
    7.12 +};
    7.13 +
    7.14 +int polyfill_framebuffer(void *fb, int width, int height);
    7.15 +
    7.16 +void polyfill_flat(struct poly_vertex *varr, int vcount);
    7.17 +
    7.18 +#endif	/* POLY_H_ */