1
0
Fork 0
blockofighter/src/graphics.cpp

239 lines
6.7 KiB
C++

#include "graphics.h"
#include <stdlib.h>
#include "texture.h"
GraphicsDruid *GraphicsDruid::instance = 0;
GraphicsDruid::GraphicsDruid(void) { this->reserved = 0; }
GraphicsDruid::~GraphicsDruid(void) {}
void GraphicsDruid::init(void) {
instance->textureCount = 0;
instance->reserved = ID_ARRAY_INIT_SIZE;
instance->idArray = (int *)calloc(ID_ARRAY_INIT_SIZE, sizeof(int));
for (int i = 0; i < instance->reserved; i++) {
instance->idArray[i] = -1;
}
}
void GraphicsDruid::destroy(void) {
if (instance->textureCount > 0) {
glDeleteTextures(GL_TEXTURE_2D, (const unsigned int *)instance->idArray);
}
free(instance->idArray);
instance->idArray = 0;
delete instance;
instance = 0;
}
GraphicsDruid &GraphicsDruid::getInstance(void) {
if (!instance) {
instance = new GraphicsDruid;
init();
}
return *instance;
}
int GraphicsDruid::loadTexture(SDL_Surface *texture, int id, int format) {
int textureID = id == -1 ? getNewTextureID(id) : id;
// register texture in OpenGL
glBindTexture(GL_TEXTURE_2D, textureID);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR); //_MIPMAP_NEAREST);
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
// printf("w: %i, h: %i, format: %i, RGBA: %i, pixels: %p\n",
// texture->w, texture->h, format, GL_RGBA, texture->pixels);
// printf("Pitch: %i, Bpp: %i\n", texture->pitch,
// texture->format->BytesPerPixel);
/*gluBuild2DMipmaps(GL_TEXTURE_2D,
4,
texture->w,
texture->h,
format,
GL_UNSIGNED_BYTE,
texture->pixels);*/
int w = texture->w;
int h = texture->h;
/*int i;
while (w > 0){
w >>= 1;
i++;
}
w = 1;
for (;i > 1; i--) w <<= 1;
while (h > 0){
h >>= 1;
i++;
}
h = 1;
for (;i > 1; i--) h <<= 1;*/
// glTexImage2D(GL_TEXTURE_2D, 0, texture->format->BytesPerPixel, w, h, 0,
// format, GL_UNSIGNED_BYTE, texture->pixels);
if (texture->format->BytesPerPixel == 3) {
glTexImage2D(GL_TEXTURE_2D, 0, 3, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE,
texture->pixels);
} else if (texture->format->BytesPerPixel == 4) {
glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
texture->pixels);
}
// SDL_FreeSurface(texture);
// SDL_FreeSurface(alphaSurface);
return textureID;
}
int GraphicsDruid::loadTexture(char *path, int id) {
SDL_Surface *texture;
texture = IMG_Load(path);
if (!texture) {
#ifdef _DEBUG
printf("Error while loading image: %s\n", SDL_GetError());
#endif
return -1;
}
int textureID = getNewTextureID(id);
// register texture in OpenGL
glBindTexture(GL_TEXTURE_2D, textureID);
// glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
// NOTE : Making some assumptions about texture parameters
// glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
// GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// printf("w: %i, h: %i, RGBA: %i, pixels: %p\n",
// texture->w, texture->h, GL_RGBA, texture->pixels);
// printf("Pitch: %i, Bpp: %i\n", texture->pitch,
// texture->format->BytesPerPixel);
if (texture->format->BytesPerPixel == 3) {
/*gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB,
texture->w,
texture->h,
GL_RGB, GL_UNSIGNED_BYTE,
texture->pixels);*/
glTexImage2D(GL_TEXTURE_2D, 0, 3, texture->w, texture->h, 0, GL_RGB,
GL_UNSIGNED_BYTE, texture->pixels);
} else if (texture->format->BytesPerPixel == 4) {
/*gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA,
texture->w,
texture->h,
GL_RGBA, GL_UNSIGNED_BYTE,
texture->pixels);*/
glTexImage2D(GL_TEXTURE_2D, 0, 4, texture->w, texture->h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, texture->pixels);
}
/*
gluBuild2DMipmaps(GL_TEXTURE_2D,
0,
texture->w,
texture->h,
GL_RGBA,
GL_UNSIGNED_BYTE,
texture->pixels);
*/
SDL_FreeSurface(texture);
return textureID;
}
int GraphicsDruid::loadTranspTexture(char *path, float *transpColor, int id) {
SDL_Surface *texture;
texture = IMG_Load(path);
if (!texture) {
#ifdef _DEBUG
printf("Error while loading image: %s\n", SDL_GetError());
#endif
return -1;
}
Uint32 colorKey =
SDL_MapRGB(texture->format, (Uint8)(transpColor[0] * 255),
(Uint8)(transpColor[1] * 255), (Uint8)(transpColor[2] * 255));
// SDL_SetAlpha(texture, 0, SDL_ALPHA_OPAQUE);
SDL_SetColorKey(texture, SDL_TRUE, colorKey);
// SDL_Surface* alphaSurface = SDL_DisplayFormatAlpha(texture);
texture = SDL_DisplayFormatAlpha(texture);
return loadTexture(texture);
}
int GraphicsDruid::getNewTextureID(int id) {
if (id != -1) {
for (int i = 0; i < instance->reserved; i++) {
if (instance->idArray[i] == id) {
freeTexture(id);
instance->textureCount--;
break;
}
}
}
GLuint newId;
if (id == -1) {
glGenTextures(1, &newId);
} else
newId = id;
int index = 0;
while (instance->idArray[index] != -1 && index < instance->reserved) {
index++;
}
// out of space, make more
if (index >= instance->reserved) {
instance->idArray = (int *)realloc(
instance->idArray, (instance->reserved + ID_ARRAY_GROW) * sizeof(int));
for (int i = instance->reserved + 1; i < instance->reserved + ID_ARRAY_GROW;
i++)
instance->idArray[i] = -1;
instance->reserved += ID_ARRAY_GROW;
} else
instance->idArray[index] = newId;
instance->textureCount++;
return newId;
}
void GraphicsDruid::freeTexture(int id) {
if (id > -1 && id < instance->reserved) {
instance->idArray[id] = -1;
const unsigned int helpInt = id;
glDeleteTextures(1, &helpInt);
}
}