Mercurial > hg > dmlib
changeset 238:9643c517967d
Beginnings of a lines + sprites "3D" "model" renderer.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 09 Oct 2012 06:06:08 +0300 |
parents | 6d9d43bb68eb |
children | 07c4f1a7ddc6 |
files | vptest.c |
diffstat | 1 files changed, 318 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/vptest.c Tue Oct 09 04:43:03 2012 +0300 +++ b/vptest.c Tue Oct 09 06:06:08 2012 +0300 @@ -136,14 +136,296 @@ } +#define DM_DRAWLINE_NAME dmDrawLineSpec +#define DM_DRAWLINE_DST_BYTES 4 +#define DM_DRAWLINE_DST_TYPE DMRGBA32 +#define DM_DRAWLINE_ARGS , SDL_Surface *bmp +#define DM_DRAWLINE_INNER \ + dmUnscaledBlitSurface32to32Transparent(bmp, x0, y0, screen); +#define DM_DRAWLINE_SPEC +#include "dmdrawline.h" + + +typedef struct +{ + int v1, v2, type; +} DM3DLine; + +typedef struct +{ + int v, bitmap; +} DM3DSprite; + +typedef struct +{ + char name[64]; + SDL_Surface *img; +} DM3DBitmap; + +typedef struct +{ + int nvertices, nvertexalloc; + DMVector *vertices; + + int nlines, nlinesalloc; + DM3DLine *lines; + + int nbitmaps, nbitmapssalloc; + DM3DBitmap *bitmaps; + + int nsprites, nspritesalloc; + DM3DSprite *sprites; +} DM3DLineSpriteModel; + + +int dmFind3DSurface(int nitems, DM3DBitmap *items, DM3DBitmap *item) +{ + int i; + for (i = 0; i < nitems; i++) + if (strcmp(item->name, items[i].name) == 0) + return i; + return -1; +} + +#define DM_FIND_ITEM_FUNC(NAME, TYPE) \ +int dmFind3D ## NAME (int nitems, TYPE *items, TYPE *item) \ +{ \ + int i; \ + for (i = 0; i < nitems; i++) \ + if (memcmp(item, items+i, sizeof(TYPE)) == 0) \ + return i; \ + return -1; \ +} + +#define DM_ADD_ITEM_FUNC(NAME, TYPE) \ +int dmAdd3D ## NAME (int *nitems, int *nalloc, TYPE **items, TYPE *item, int *res) \ +{ \ + int tmp; \ + if ((tmp = dmFind3D ## NAME (*nitems, *items, item)) >= 0) \ + { \ + if (res != NULL) *res = tmp; \ + return DMERR_OK; \ + } \ + if ((*nitems) + 1 >= *nalloc) \ + { \ + (*nalloc) += 16; \ + if ((*items = dmRealloc(*items, *nalloc * sizeof(TYPE))) == NULL) \ + return DMERR_MALLOC; \ + } \ + memcpy((*items) + (*nitems), item, sizeof(TYPE)); \ + if (res != NULL) *res = *nitems; \ + (*nitems)++; \ + return DMERR_OK; \ +} + +DM_FIND_ITEM_FUNC(Vertex, DMVector) +DM_FIND_ITEM_FUNC(Line, DM3DLine) +DM_FIND_ITEM_FUNC(Sprite, DM3DSprite) + +DM_ADD_ITEM_FUNC(Vertex, DMVector) +DM_ADD_ITEM_FUNC(Line, DM3DLine) +DM_ADD_ITEM_FUNC(Sprite, DM3DSprite) +DM_ADD_ITEM_FUNC(Surface, DM3DBitmap) + +char *dmSkipWhitespace(char *line, BOOL invert) +{ + if (invert) + for (; *line && !isspace(*line); line++); + else + for (; *line && isspace(*line); line++); + return line; +} + +char *dmSkipUntil(char *line, char ch) +{ + for (; *line && *line != ch; line++); + return line; +} + +BOOL dmReadCoordinate(char **line, float *value, BOOL next) +{ + *line = dmSkipWhitespace(*line, FALSE); + if (sscanf(*line, "%f", value) != 1) return FALSE; + if (next) + { + *line = dmSkipUntil(*line, ','); + if (**line != ',') return FALSE; + *(*line)++; + } + else + *line = dmSkipWhitespace(*line, TRUE); + + return TRUE; +} + +BOOL dmReadLineSegments(char *line, DM3DLineSpriteModel *model) +{ + int nvertices, vertex, type; + int *indices = NULL; + if (sscanf(line+1, "%d", &nvertices) != 1) + { + dmError("No # of segments @ '%s'\n", line); + goto error; + } + + if ((indices = dmMalloc(sizeof(int) * (nvertices+1))) == NULL) + goto error; + + line = dmSkipWhitespace(line, TRUE); + for (vertex = 0; vertex <= nvertices; vertex++) + { + DMVector p; + if (!dmReadCoordinate(&line, &p.x, TRUE)) return FALSE; + if (!dmReadCoordinate(&line, &p.y, TRUE)) return FALSE; + if (!dmReadCoordinate(&line, &p.z, FALSE)) return FALSE; + if (dmAdd3DVertex(&model->nvertices, &model->nvertexalloc, + &model->vertices, &p, &indices[vertex]) != DMERR_OK) + goto error; + line = dmSkipWhitespace(line, FALSE); + } + + if (sscanf(line, "%d", &type) != 1) + { + dmError("No line type @ '%s'\n", line); + goto error; + } + + for (vertex = 1; vertex <= nvertices; vertex++) + { + DM3DLine line; + line.v1 = indices[vertex - 1]; + line.v2 = indices[vertex]; + line.type = type; + + if (dmAdd3DLine(&model->nlines, &model->nlinesalloc, + &model->lines, &line, NULL) != DMERR_OK) + goto error; + } + + return TRUE; +error: + dmFree(indices); + return FALSE; +} + +BOOL dmReadSprite(char *line, DM3DLineSpriteModel *model) +{ + DMVector pt; + DM3DSprite spr; + DM3DBitmap bmp, *rbmp; + + line++; + if (!dmReadCoordinate(&line, &pt.x, TRUE)) return FALSE; + if (!dmReadCoordinate(&line, &pt.y, TRUE)) return FALSE; + if (!dmReadCoordinate(&line, &pt.z, FALSE)) return FALSE; + line = dmSkipWhitespace(line, FALSE); + + if (dmAdd3DVertex(&model->nvertices, &model->nvertexalloc, + &model->vertices, &pt, &spr.v) != DMERR_OK) + return FALSE; + + strncpy(bmp.name, line, sizeof(bmp.name)); + bmp.img = NULL; + if (dmAdd3DSurface(&model->nbitmaps, &model->nbitmapssalloc, + &model->bitmaps, &bmp, &spr.bitmap) != DMERR_OK) + return FALSE; + + rbmp = &(model->bitmaps[spr.bitmap]); + if (rbmp->img == NULL) + { + DMResource *res = dmf_create_stdio(rbmp->name, "rb"); + if (res == NULL) + { + dmError("Could not open resource file '%s'.\n", rbmp->name); + return FALSE; + } + rbmp->img = dmLoadImage(res); + dmf_close(res); + if (rbmp->img == NULL) + { + dmError("Could not load image file '%s'.\n", rbmp->name); + return FALSE; + } + } + + if (dmAdd3DSprite(&model->nsprites, &model->nspritesalloc, + &model->sprites, &spr, NULL) != DMERR_OK) + return FALSE; + + return TRUE; +} + +int dmRead3DLineSpriteModel(DMResource *f, DM3DLineSpriteModel *model) +{ + char line[512]; + + memset(model, 0, sizeof(*model)); + + while (dmfgets(line, sizeof(line), f) != NULL) + { + char *start = dmSkipWhitespace(line, FALSE); + switch (*start) + { + case 0: + case '#': + break; + + case 'L': + if (!dmReadLineSegments(start, model)) + return DMERR_INVALID_DATA; + break; + + case 'S': + if (!dmReadSprite(start, model)) + return DMERR_INVALID_DATA; + break; + + default: + printf("'%s'\n", start); + break; + } + } + + return DMERR_OK; +} + + +void dmDraw3DLineSpriteModel(SDL_Surface *screen, DM3DLineSpriteModel *model, DMVector pos, SDL_Surface *fbmap, Uint32 lcol) +{ + int i; + for (i = 0; i < model->nlines; i++) + { + DM3DLine *line = &model->lines[i]; + DMVector *v1 = &model->vertices[line->v1], + *v2 = &model->vertices[line->v2]; + if (line->type > 1) + dmDrawLineSpec(screen, pos.x + v1->x, pos.y + v1->y, pos.x + v2->x, pos.y + v2->y, lcol, fbmap); + else + dmDrawLine32(screen, pos.x + v1->x, pos.y + v1->y, pos.x + v2->x, pos.y + v2->y, lcol); + } + + for (i = 0; i < model->nsprites; i++) + { + DM3DSprite *sprite = &model->sprites[i]; + DM3DBitmap *bmp = &model->bitmaps[sprite->bitmap]; + DMVector *v = &model->vertices[sprite->v]; + + dmUnscaledBlitSurface32to32Transparent( + bmp->img, + pos.x + v->x, pos.y + v->y, screen); + } +} + + int main(int argc, char *argv[]) { - SDL_Surface *screen = NULL, *bmap = NULL; + SDL_Surface *screen = NULL, *bmap = NULL, *fbmap = NULL; + SDL_Color fontcol = { 255, 155, 155, 0 }; + SDL_Event event; TTF_Font *font = NULL; - SDL_Color fontcol={255,155,155,0}; - SDL_Event event; int mouseX, mouseY, bx, by; BOOL initSDL = FALSE, initTTF = FALSE, exitFlag; + DM3DLineSpriteModel model; dmVerbosity = 5; if (!dmArgsProcess(argc, argv, optList, optListN, @@ -187,6 +469,31 @@ dmError("Could not load image file '%s'.\n", optBitmapFilename); goto error_exit; } + + res = dmf_create_stdio("trans6x6.png", "rb"); + if (res == NULL) + { + dmError("Could not open resource file '%s'.\n", optBitmapFilename); + goto error_exit; + } + fbmap = dmLoadImage(res); + dmf_close(res); + if (fbmap == NULL) + { + dmError("Could not load image file '%s'.\n", optBitmapFilename); + goto error_exit; + } + + + res = dmf_create_stdio("mole.3d", "r"); + if (res == NULL) + { + dmError("Could not open resource file '%s'.\n", optBitmapFilename); + goto error_exit; + } + dmRead3DLineSpriteModel(res, &model); + dmf_close(res); + if (optBenchmark) { @@ -279,23 +586,17 @@ DMD_SATURATE ); -#if 0 - dmScaledBlitSurfaceAny(bmap, bx*2-qw, by*2-qh, bmap->w+qw, bmap->h+qh, screen, -// DMD_NONE - DMD_TRANSPARENT -// DMD_SATURATE - ); -// fprintf(stderr, "%d -> %d : %d\n", bmap->format->BitsPerPixel, screen->format->BitsPerPixel, rt); -// exitFlag=TRUE; -#else dmScaledBlitSurface32to32TransparentGA(bmap, bx*2-qw, by*2-qh, bmap->w+qw, bmap->h+qh, screen, 128 + sin(f*0.1) * 120.0f); -#endif + - dmDrawLine32(screen, 30, 30, 600 + 200 * sin(f), 250 , lcol); - dmDrawLine32(screen, 20, 30, 100 , 250 + 100 * sin(f), lcol); - dmDrawLine32(screen, 100, 100, 100 + cos(f) * 50, 100 + sin(f) * 50, lcol); - dmDrawLine32(screen, 100, 100, 100 + cos(f+0.5) * 250, 100 + sin(f+0.5) * 250, lcol); + DMVector pos; + pos.x = 10; + pos.y = 10; + pos.z = 0; + + dmDraw3DLineSpriteModel(screen, &model, pos, fbmap, lcol); + if (!optBenchmark) {