struct Texture {
SDL_Surface* tex;
GLuint texHandle;
GLint colorNum;
GLenum format;
};
//class render holds a tilesheet and manages it
class renderer {
private:
short width, height;
SDL_Surface* tilesheet;
std::vector<Texture*> tile;
//null will render to the screen
SDL_Surface* destination;
SDL_Surface* loadOptimized(std::string filename);
bool divideTilesheet();
public:
//regular loaded constructor
renderer(std::string filename, SDL_Surface* udestination);
//for creating a renderer with a procedurally generated tilesheet
renderer(SDL_Surface* utilesheet, SDL_Surface* udestination);
//tilex and tiley are both zero-based, so the upper-left tile would be (0, 0)
void render(int tilex, int tiley, int locx, int locy);
SDL_Surface* getResult() {return destination;}
};
renderer::renderer(std::string filename, SDL_Surface* udestination) {
tilesheet = loadOptimized(filename);
destination = udestination;
width = tilesheet->w/tileSize;
height = tilesheet->h/tileSize;
divideTilesheet();
}
renderer::renderer(SDL_Surface* utilesheet, SDL_Surface* udestination) {
tilesheet = utilesheet;
destination = udestination;
width = tilesheet->w/tileSize;
height = tilesheet->h/tileSize;
divideTilesheet();
}
bool renderer::divideTilesheet() {
//make sure we don't leave any previous tiles
tile.clear();
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
SDL_Surface* newTile = NULL;
newTile = SDL_CreateRGBSurface(0, tileSize, tileSize, tileSize, 0, 0, 0, 0);
SDL_Rect clip;
clip.x = x*tileSize;
clip.y = y*tileSize;
clip.w = tileSize;
clip.h = tileSize;
SDL_Rect dest;
dest.x = 0;
dest.y = 0;
SDL_BlitSurface(tilesheet, &clip, newTile, &dest);
//the texture is created, so now we have to register it
Texture* newTex = new Texture();
newTex->tex = newTile;
newTex->colorNum = newTex->tex->format->BytesPerPixel;
if(newTex->colorNum == 4) {
if(newTex->tex->format->Rmask == 0x000000ff)
newTex->format = GL_RGBA;
else
newTex->format = GL_BGRA;
}
else if(newTex->colorNum == 3) {
if(newTex->tex->format->Rmask == 0x000000ff)
newTex->format = GL_RGB;
else
newTex->format = GL_BGR;
}
glGenTextures(1, &(newTex->texHandle));
glBindTexture(GL_TEXTURE_2D, newTex->texHandle);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
SDL_LockSurface(newTex->tex);
glTexImage2D(GL_TEXTURE_2D, 0, newTex->colorNum, newTex->tex->w, newTex->tex->h, 0, newTex->format, GL_UNSIGNED_BYTE, newTex->tex->pixels);
SDL_UnlockSurface(newTex->tex);
tile.push_back(newTex);
}
}
return true;
}
SDL_Surface* renderer::loadOptimized(std::string filename) {
SDL_Surface* loaded = NULL;
SDL_Surface* optimized = NULL;
loaded = SDL_LoadBMP(filename.c_str());
if(loaded != NULL) {
optimized = SDL_DisplayFormat(loaded);
SDL_FreeSurface(loaded);
}
else return NULL;
return optimized;
}
void renderer::render(int tilex, int tiley, int locx, int locy) {
if(destination) {
SDL_Rect dest;
dest.x = locx;
dest.y = locy;
SDL_BlitSurface(tile[tiley*width + tilex]->tex, NULL, destination, &dest);
}
else {
//render to the screen with opengl
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tile[tiley*width + tilex]->texHandle);
glBegin(GL_QUADS);
glTexCoord2f(0, 0);
glVertex2f(float(locx), float(locy));
glTexCoord2f(1, 0);
glVertex2f(float(locx + tileSize), float(locy));
glTexCoord2f(1, 1);
glVertex2f(float(locx + tileSize), float(locy + tileSize));
glTexCoord2f(0, 1);
glVertex2f(float(locx), float(locy + tileSize));
glEnd();
glDisable(GL_TEXTURE_2D);
}
}
It looks like the problem is somewhere in renderer::divideTilesheet.











