237 lines
7.1 KiB
C++
237 lines
7.1 KiB
C++
#include "graphics.h"
|
|
#include <stdlib.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_SRCCOLORKEY, 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);
|
|
}
|
|
}
|
|
|