#include #include #include "opengl.h" #include "FrameSheet.h" #include "fifo.h" #include "report.h" #include "string.h" struct FrameSheet *newFrameSheet() { struct FrameSheet *sheet = malloc(sizeof(struct FrameSheet)); sheet->textures = NULL; sheet->surfaces = NULL; sheet->count = 0; sheet->state = 0; return sheet; } struct FrameSheet *loadFrameSheet(const char *name, const char *framedir) { if (framedir == NULL) return NULL; struct Dir *dir = openDir(framedir, 0); if (dir == NULL) { report(ERROR, "loadFrameSheet", "dir %s does not exist", framedir); return NULL; } struct FrameSheet *sheet = newFrameSheet(); struct DirEntry *entry; while ((entry = readDir(dir)) != NULL) { if (entry->d_type != F_REG) continue; char *filename = NULL; filename = setStringF(filename, "%s/%s", framedir, entry->d_name); SDL_Surface *surface = NULL; if ((surface = IMG_Load(filename)) == NULL) { report(ERROR, "loadFrameSheet", "error loading surface: %s", SDL_GetError()); free(filename); continue; } free(filename); // seems valid, let's add it as a frame sheet->count++; sheet->surfaces = realloc(sheet->surfaces, sheet->count*sizeof(SDL_Surface*)); if (sheet->surfaces == NULL) { report(ERROR, "loadFrameSheet", "could not realloc surfaces"); freeFrameSheet(sheet); return NULL; } sheet->surfaces[sheet->count-1] = surface; } sheet->textures = realloc(sheet->textures, sheet->count*sizeof(GLuint)); closeDir(dir); return sheet; } int freeFrameSheet(struct FrameSheet *sheet) { if (sheet == NULL) return 1; int i; if (sheet->surfaces != NULL) { for (i = 0; i < sheet->count; i++) { SDL_FreeSurface(sheet->surfaces[i]); } free(sheet->surfaces); } // clean up textures if open if (sheet->textures != NULL) { closeFrameSheet(sheet); free(sheet->textures); } free(sheet); return 0; } int openFrameSheet(struct FrameSheet *sheet) { if (sheet == NULL) return 1; if (sheet->state == 0) { int i; for (i = 0; i < sheet->count; i++) { sheet->textures[i] = createTexture(sheet->surfaces[i]); } } sheet->state = 1; return 0; } int closeFrameSheet(struct FrameSheet *sheet) { if (sheet == NULL) return 1; if (sheet->state == 1) { int i; for (i = 0; i < sheet->count; i++) { glDeleteTextures(1, &sheet->textures[i]); } } sheet->state = 0; return 0; } int renderFrame(struct FrameSheet *sheet, int frame, int x, int y) { if (sheet == NULL) return 1; if (frame < 0 || frame >= sheet->count) return 2; if (sheet->state == 0) { openFrameSheet(sheet); } x -= sheet->surfaces[frame]->w/2; y -= sheet->surfaces[frame]->h/2; float sx = sheet->surfaces[frame]->w; float sy = sheet->surfaces[frame]->h; // bind our texture glBindTexture(GL_TEXTURE_2D, sheet->textures[frame]); // make sure we're rendering textures glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // reset view glLoadIdentity(); // translate to a quad glTranslated(x, y, 1.0f); // draw ! glBegin(GL_QUADS); // top left glTexCoord2d(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); // top right glTexCoord2d(1.0, 0.0f); glVertex2f(sx, 0.0f); // bottom right glTexCoord2d(1.0f, 1.0f); glVertex2f(sx, sy); // bottom left glTexCoord2d(0.0f, 1.0f); glVertex2f(0.0f, sy); glEnd(); return 0; }