Asset::Asset(Shape s, Texture* tex, Program* prog) { program = prog; texture = tex; shape = s; switch(shape){ case Triangle: LoadTriangle(); break; case Cube: LoadCube(); break; } }
void SkyWrapper::Init() { LoadCube("data/objects/sphere/dusk/", "px.jpg", "nx.jpg", "py.jpg", "ny.jpg", "pz.jpg", "nz.jpg"); }
bool Texture::Load(const std::string & path, const TextureInfo & info, std::ostream & error) { if (m_id) { error << "Tried to double load texture " << path << std::endl; return false; } if (!info.data && path.empty()) { error << "Tried to load a texture with an empty name" << std::endl; return false; } if (!info.data && LoadDDS(path, info, error)) return true; m_cube = info.cube; if (m_cube) { return LoadCube(path, info, error); } SDL_Surface * orig_surface = 0; if (info.data) { Uint32 rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif orig_surface = SDL_CreateRGBSurfaceFrom( info.data, info.width, info.height, info.bytespp * 8, info.width * info.bytespp, rmask, gmask, bmask, amask); } if (!orig_surface) { orig_surface = IMG_Load(path.c_str()); if (!orig_surface) { error << "Error loading texture file: " << path << std::endl; error << IMG_GetError() << std::endl; return false; } } SDL_Surface * surface = orig_surface; if (surface) { m_scale = Scale(info.maxsize, orig_surface->w, orig_surface->h); float scalew = m_scale; float scaleh = m_scale; // scale to power of two if necessary bool norescale = (IsPowerOfTwo(orig_surface->w) && IsPowerOfTwo(orig_surface->h)) || (info.npot && (GLEW_VERSION_2_0 || GLEW_ARB_texture_non_power_of_two)); if (!norescale) { int maxsize = 2048; int new_w = orig_surface->w; int new_h = orig_surface->h; if (!IsPowerOfTwo(orig_surface->w)) { for (new_w = 1; new_w <= maxsize && new_w <= orig_surface->w * m_scale; new_w = new_w * 2); } if (!IsPowerOfTwo(orig_surface->h)) { for (new_h = 1; new_h <= maxsize && new_h <= orig_surface->h * m_scale; new_h = new_h * 2); } scalew = ((float)new_w + 0.5) / orig_surface->w; scaleh = ((float)new_h + 0.5) / orig_surface->h; } // scale texture down if necessary if (scalew < 1.0 || scaleh < 1.0) { surface = zoomSurface(orig_surface, scalew, scaleh, SMOOTHING_ON); } // store dimensions m_w = surface->w; m_h = surface->h; GenTexture(surface, info, m_id, m_alpha, error); } // free the texture surface separately if it's a scaled copy of the original if (surface && surface != orig_surface ) { SDL_FreeSurface(surface); } // free the original surface if it's not a custom surface (used for the track map) if (!info.data && orig_surface) { SDL_FreeSurface(orig_surface); } return true; }
bool TEXTURE::Load(const std::string & path, const TEXTUREINFO & info, std::ostream & error) { if (id) { error << "Tried to double load texture " << path << std::endl; return false; } if (path.empty() && !info.data) { error << "Tried to load a texture with an empty name" << std::endl; return false; } id = 0; cube = info.cube; if (info.cube && info.verticalcross) { return LoadCubeVerticalCross(path, info, error); } else if (info.cube) { return LoadCube(path, info, error); } SDL_Surface * orig_surface = 0; if (info.data) { Uint32 rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif orig_surface = SDL_CreateRGBSurfaceFrom( info.data, info.width, info.height, info.bytespp * 8, info.width * info.bytespp, rmask, gmask, bmask, amask); } if (!orig_surface) { orig_surface = IMG_Load(path.c_str()); if (!orig_surface) { error << "Error loading texture file: " << path << std::endl; return false; } } SDL_Surface * texture_surface = orig_surface; if (orig_surface) { origw = texture_surface->w; origh = texture_surface->h; //scale to power of two if necessary bool norescale = (IsPowerOfTwo(orig_surface->w) && IsPowerOfTwo(orig_surface->h)) || (info.npot && (GLEW_VERSION_2_0 || GLEW_ARB_texture_non_power_of_two)); if (!norescale) { int maxsize = 2048; int newx = GetPowerOfTwo(orig_surface->w, maxsize); int newy = GetPowerOfTwo(orig_surface->h, maxsize); float scalew = ((float)newx+0.5) / orig_surface->w; float scaleh = ((float)newy+0.5) / orig_surface->h; SDL_Surface * pot_surface = zoomSurface(orig_surface, scalew, scaleh, SMOOTHING_ON); assert(IsPowerOfTwo(pot_surface->w)); assert(IsPowerOfTwo(pot_surface->h)); SDL_FreeSurface(orig_surface); orig_surface = pot_surface; texture_surface = orig_surface; } //scale texture down if necessary scale = Scale(info.maxsize, orig_surface->w, orig_surface->h); if (scale < 1.0) { texture_surface = zoomSurface(orig_surface, scale, scale, SMOOTHING_ON); } //store dimensions w = texture_surface->w; h = texture_surface->h; GenTexture(texture_surface, info, id, alpha, error); } //free the texture surface separately if it's a scaled copy of the original if (texture_surface != orig_surface && texture_surface) { SDL_FreeSurface(texture_surface); } //free the original surface if it's not a custom surface (used for the track map) if (!info.data && orig_surface) { SDL_FreeSurface(orig_surface); } return true; }
int main(int argc, char **argv) { try { glutInit(&argc, argv); InitGL(); if (glewIsSupported("GL_VERSION_3_1")) printf("Ready for OpenGL 3.1.\n"); else { printf("OpenGL 3.1 not supported\n"); exit(1); } gDC.AddLight(glm::vec3(100.f, 100.f, 100.f), glm::vec3(1.0f, 1.0f, 1.0f)); #if MODELLOADING gDC.AllocateMeshAccess("truck_color.bmp", "./models/L200-OBJ/", "L200-OBJ.obj"); #else std::vector<glm::vec3> verts; LoadCube(verts); #endif gDC.AllocateShader(); printOpenGLError(); if(gDC.fMeshes.size() > 99) { printf("too many meshes\n"); exit(-4); } glGenVertexArrays(gDC.fMeshes.size() + 1, gDC.fVAO_ID); gDC.fShader->UseProgram(Shader::EShaderKind::eShaderBasic); printOpenGLError(); glBindVertexArray(gDC.fVAO_ID[0]); GLuint vertexBuffer; glGenBuffers(1, &vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(gPlanes), gPlanes, GL_STATIC_DRAW); glGenBuffers(1, &gDC.fIndexBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gDC.fIndexBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(gPlaneInds), gPlaneInds, GL_STATIC_DRAW); glGenBuffers(1, &gDC.fNormalBuffer); glBindBuffer(GL_ARRAY_BUFFER, gDC.fNormalBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(gPlaneNormals), gPlaneNormals, GL_STATIC_DRAW); gDC.fVertexPos = glGetAttribLocation(gDC.fShader->GetProgram(), "inPositions"); gDC.fNormalPos = glGetAttribLocation(gDC.fShader->GetProgram(), "inNormals"); glEnableVertexAttribArray(gDC.fVertexPos); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glVertexAttribPointer(gDC.fVertexPos, 3, GL_FLOAT, GL_FALSE, 0, (void *)0); glEnableVertexAttribArray(gDC.fNormalPos); glBindBuffer(GL_ARRAY_BUFFER, gDC.fNormalBuffer); glVertexAttribPointer(gDC.fNormalPos, 3, GL_FLOAT, GL_FALSE, 0, (void *)0); glBindVertexArray(0); gDC.fShader->UseProgram(Shader::EShaderKind::eShaderTexture); printOpenGLError(); for(size_t i = 0 ; i < gDC.fMeshes.size() ; i++) { Mesh & mesh = gDC.fMeshes.at(i); Material & mat = mesh.fMat; // materials. glBindVertexArray(gDC.fVAO_ID[i + 1]); GLuint vertexBuffer; glGenBuffers(1, &vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glBufferData(GL_ARRAY_BUFFER, mesh.fVertices.size() * sizeof(glm::vec3), &mesh.fVertices[0], GL_STATIC_DRAW); glGenBuffers(1, &gDC.fIndexBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gDC.fIndexBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.fIndices.size() * sizeof(unsigned short), &mesh.fIndices[0], GL_STATIC_DRAW); glGenBuffers(1, &gDC.fNormalBuffer); glBindBuffer(GL_ARRAY_BUFFER, gDC.fNormalBuffer); glBufferData(GL_ARRAY_BUFFER, mesh.fNormals.size() * sizeof(glm::vec3), &mesh.fNormals[0], GL_STATIC_DRAW); glGenBuffers(1, &gDC.fUVBuffer); glBindBuffer(GL_ARRAY_BUFFER, gDC.fUVBuffer); glBufferData(GL_ARRAY_BUFFER, mesh.fUVs.size() * sizeof(glm::vec2), &mesh.fUVs[0], GL_STATIC_DRAW); /*GLuint colorBuffer; glGenBuffers(1, &colorBuffer); glBindBuffer(GL_ARRAY_BUFFER, colorBuffer); glBufferData(GL_ARRAY_BUFFER, gColors.size() * sizeof(glm::vec3), &gColors[0], GL_STATIC_DRAW); */ gDC.fVertexPos = glGetAttribLocation(gDC.fShader->GetProgram(), "inPositions"); gDC.fNormalPos = glGetAttribLocation(gDC.fShader->GetProgram(), "inNormals"); gDC.fUVPos = glGetAttribLocation(gDC.fShader->GetProgram(), "inUV"); //gColorPos = glGetAttribLocation(gDC.gShader->GetProgram(), "inColors"); glEnableVertexAttribArray(gDC.fVertexPos); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glVertexAttribPointer(gDC.fVertexPos, 3, GL_FLOAT, GL_FALSE, 0, (void *)0); glEnableVertexAttribArray(gDC.fNormalPos); glBindBuffer(GL_ARRAY_BUFFER, gDC.fNormalBuffer); glVertexAttribPointer(gDC.fNormalPos, 3, GL_FLOAT, GL_FALSE, 0, (void *)0); glEnableVertexAttribArray(gDC.fUVPos); glBindBuffer(GL_ARRAY_BUFFER, gDC.fUVBuffer); glVertexAttribPointer(gDC.fUVPos, 2, GL_FLOAT, GL_FALSE, 0, (void *)0); } glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); //glEnableVertexAttribArray(gColorPos); //glBindBuffer(GL_ARRAY_BUFFER, colorBuffer); //glVertexAttribPointer(gColorPos, 3, GL_FLOAT, GL_FALSE, 0, (void *)0); printOpenGLError(); UpdateRenderMat(gDC); glutMainLoop(); EndGL(); } catch(char * e) { std::cout << e << std::endl; } return 0; }
Boolean PreLoadCube (int dsp, char *ptr, float min, float max, Boolean str, Boolean setworld) /*********************************************************************** * *_Title PreLoadCube - Calculates auto stretch and creates display * *_Args Type Variable I/O Description *_Parm int dsp I Display number *_Parm char *ptr I File name of image *_Parm float min I Minimum value for stretch *_Parm float max I Maximum value for stretch *_Parm Boolean str I If True, calculate stretch * If False, don't calculate stretch *_Parm Boolean setworld * *_DESC Pre stretch image and create display. If successful it * will load the "f" structure associated with the display and * return False. If an error occurs it will return True. * * *_HIST Jan 1 1996 Jeff Anderson, Original version * Apr 25 1997 Tracie Sucharski, Allow display of more than * one image on the TAE command line and allow * min/max values to be entered on command line. * Jan 14 1998 TLS, Print error message if file can't be opened. * Mar 24 1998 TLS, Copy original min/max values to actual * min/max values. * Dec 15 2001 Janet Barrett, Modified to work with the pc2d * program. *_END ************************************************************************/ { int i; static int firstime=2; DSPINFO *d; GBLdsp.free = dsp; if (OpenCube (dsp,ptr)) { sprintf (GBLerr.string,"%s can not be opened",ptr); u_error ("OPENERR",GBLerr.string,-1,1); return True; } GBLdsp.used[dsp] = True; GBLdsp.linked[dsp] = True; d = &GBLdsp.d[dsp]; d->band[0] = 1; d->band[1] = 0; d->band[2] = 0; d->scs_sl = 1; d->scs_ss = 1; d->scs_el = d->f.nl; d->scs_es = d->f.ns; for (i=0; i<MAX_BANDS; i++) d->avalid[i] = False; if (str) { d->autostr = True; d->manstr = False; d->prestr_minper = GBLdefault.prestr_lowper; d->prestr_maxper = GBLdefault.prestr_hiper; QviewWatch (xinfo.topShell,True); CalcAutoStr (dsp); QviewWatch (xinfo.topShell,False); /* else { d->autostr = False; d->manstr = True; d->rmin = min; d->rmax = max; d->gmin = 0; d->gmax = 255; d->bmin = 0; d->bmax = 255; d->rmin_real = d->rmin; d->rmax_real = d->rmax; d->gmin_real = d->gmin; d->gmax_real = d->gmax; d->bmin_real = d->bmin; d->bmax_real = d->bmax; }*/ } if (!str) { for (i=0;i<3;i++) d->avalid[i] = False; XSync(xinfo.display,False); CalcAutoStr(dsp); StretchReset (dsp); } LoadStrLut (dsp); if (firstime) { CreateDisplay (); firstime = firstime - 1; } else { if (setworld) { d->world = True; d->ss = d->scs_ss; d->sl = d->scs_sl; d->inc = ((double) (d->scs_el-d->scs_sl+1))/340.0; if ((d->scs_es-d->scs_ss+1)>(d->scs_el-d->scs_sl+1)) d->inc = ((double) (d->scs_es-d->scs_ss+1))/340.0; } d->read_tmp = False; LoadCube (dsp); } return False; }
bool Texture::Load(const std::string & path, const TextureInfo & info, std::ostream & error) { if (texid) { error << "Tried to double load texture " << path << std::endl; return false; } if (!info.data && path.empty()) { error << "Tried to load a texture with an empty name" << std::endl; return false; } if (!info.data && LoadDDS(path, info, error)) { return true; } if (info.cube) { return LoadCube(path, info, error); } SDL_Surface * surface = 0; if (info.data) { Uint32 rmask, gmask, bmask, amask; #if SDL_BYTEORDER == SDL_BIG_ENDIAN rmask = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif surface = SDL_CreateRGBSurfaceFrom( info.data, info.width, info.height, info.bytespp * 8, info.width * info.bytespp, rmask, gmask, bmask, amask); } else { surface = IMG_Load(path.c_str()); } if (!surface) { error << "Error loading texture file: " << path << std::endl; error << IMG_GetError() << std::endl; return false; } const unsigned char * pixels = (const unsigned char *)surface->pixels; const unsigned bytespp = surface->format->BytesPerPixel; unsigned pitch = surface->pitch; unsigned w = surface->w; unsigned h = surface->h; // downsample if requested by application std::vector<unsigned char> pixelsd; unsigned wd = w; unsigned hd = h; if (info.maxsize == TextureInfo::SMALL) { if (w > 256) wd = w / 4; else if (w > 128) wd = w / 2; if (h > 256) hd = h / 4; else if (h > 128) hd = h / 2; } else if (info.maxsize == TextureInfo::MEDIUM) { if (w > 256) wd = w / 2; if (h > 256) hd = h / 2; } if (wd < w || hd < h) { pixelsd.resize(wd * hd * bytespp); SampleDownAvg( bytespp, w, h, pitch, pixels, wd, hd, wd * bytespp, &pixelsd[0]); pixels = &pixelsd[0]; pitch = wd * bytespp; w = wd; h = hd; } // store dimensions width = w; height = h; target = GL_TEXTURE_2D; // gen texture glGenTextures(1, &texid); CheckForOpenGLErrors("Texture ID generation", error); // setup texture glBindTexture(GL_TEXTURE_2D, texid); SetSampler(info); int internalformat, format; GetTextureFormat(surface, info, internalformat, format); // upload texture data glTexImage2D(GL_TEXTURE_2D, 0, internalformat, w, h, 0, format, GL_UNSIGNED_BYTE, pixels); CheckForOpenGLErrors("Texture creation", error); // If we support generatemipmap, go ahead and do it regardless of the info.mipmap setting. // In the GL3 renderer the sampler decides whether or not to do mip filtering, // so we conservatively make mipmaps available for all textures. if (GLC_ARB_framebuffer_object) glGenerateMipmap(GL_TEXTURE_2D); SDL_FreeSurface(surface); return true; }
// the program starts here void AppMain() { // initialise GLFW if(!glfwInit()) throw std::runtime_error("glfwInit failed"); // open a window with GLFW glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2); glfwOpenWindowHint(GLFW_WINDOW_NO_RESIZE, GL_TRUE); if(!glfwOpenWindow((int)SCREEN_SIZE.x, (int)SCREEN_SIZE.y, 8, 8, 8, 8, 16, 0, GLFW_WINDOW)) throw std::runtime_error("glfwOpenWindow failed. Can your hardware handle OpenGL 3.2?"); // GLFW settings glfwDisable(GLFW_MOUSE_CURSOR); glfwSetMousePos(0, 0); glfwSetMouseWheel(0); // initialise GLEW glewExperimental = GL_TRUE; //stops glew crashing on OSX :-/ if(glewInit() != GLEW_OK) throw std::runtime_error("glewInit failed"); // GLEW throws some errors, so discard all the errors so far while(glGetError() != GL_NO_ERROR) {} // print out some info about the graphics drivers std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; std::cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl; std::cout << "Vendor: " << glGetString(GL_VENDOR) << std::endl; std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl; // make sure OpenGL version 3.2 API is available if(!GLEW_VERSION_3_2) throw std::runtime_error("OpenGL 3.2 API is not available."); // OpenGL settings glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // load vertex and fragment shaders into opengl LoadShaders(); // load the texture LoadTexture(); // create buffer and fill it with the points of the triangle LoadCube(); // setup gCamera gCamera.setPosition(glm::vec3(0,0,4)); gCamera.setViewportAspectRatio(SCREEN_SIZE.x / SCREEN_SIZE.y); // run while the window is open double lastTime = glfwGetTime(); while(glfwGetWindowParam(GLFW_OPENED)){ // update the scene based on the time elapsed since last update double thisTime = glfwGetTime(); Update(thisTime - lastTime); lastTime = thisTime; // draw one frame Render(); // check for errors GLenum error = glGetError(); if(error != GL_NO_ERROR) std::cerr << "OpenGL Error " << error << ": " << (const char*)gluErrorString(error) << std::endl; //exit program if escape key is pressed if(glfwGetKey(GLFW_KEY_ESC)) glfwCloseWindow(); } // clean up and exit glfwTerminate(); }
// the program starts here void AppMain() { // initialise GLFW glfwSetErrorCallback(OnError); if(!glfwInit()) throw std::runtime_error("glfwInit failed"); // open a window with GLFW glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); gWindow = glfwCreateWindow((int)SCREEN_SIZE.x, (int)SCREEN_SIZE.y, "OpenGL Tutorial", NULL, NULL); if(!gWindow) throw std::runtime_error("glfwCreateWindow failed. Can your hardware handle OpenGL 3.2?"); // GLFW settings glfwMakeContextCurrent(gWindow); // initialise GLEW glewExperimental = GL_TRUE; //stops glew crashing on OSX :-/ if(glewInit() != GLEW_OK) throw std::runtime_error("glewInit failed"); // GLEW throws some errors, so discard all the errors so far while(glGetError() != GL_NO_ERROR) {} // print out some info about the graphics drivers std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl; std::cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl; std::cout << "Vendor: " << glGetString(GL_VENDOR) << std::endl; std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl; // make sure OpenGL version 3.2 API is available if(!GLEW_VERSION_3_2) throw std::runtime_error("OpenGL 3.2 API is not available."); // OpenGL settings glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // load vertex and fragment shaders into opengl LoadShaders(); // load the texture LoadTexture(); // create buffer and fill it with the points of the triangle LoadCube(); // run while the window is open double lastTime = glfwGetTime(); while(!glfwWindowShouldClose(gWindow)){ // process pending events glfwPollEvents(); // update the scene based on the time elapsed since last update double thisTime = glfwGetTime(); Update((float)(thisTime - lastTime)); lastTime = thisTime; // draw one frame Render(); // check for errors GLenum error = glGetError(); if(error != GL_NO_ERROR) std::cerr << "OpenGL Error " << error << std::endl; } // clean up and exit glfwTerminate(); }
bool TEXTURE::Load(const std::string & path, const TEXTUREINFO & info, std::ostream & error) { if (id) { error << "Tried to double load texture " << path << std::endl; return false; } if (path.empty() && !info.surface) { error << "Tried to load a texture with an empty name" << std::endl; return false; } id = 0; if (info.cube) { cube = true; return LoadCube(path, info, error); } SDL_Surface * orig_surface = info.surface; if (!orig_surface) { orig_surface = IMG_Load(path.c_str()); if (!orig_surface) { error << "Error loading texture file: " << path << std::endl; return false; } } SDL_Surface * texture_surface(orig_surface); if (orig_surface) { origw = texture_surface->w; origh = texture_surface->h; //scale to power of two if necessary bool norescale = (IsPowerOfTwo(orig_surface->w) && IsPowerOfTwo(orig_surface->h)) || (info.npot && (GLEW_VERSION_2_0 || GLEW_ARB_texture_non_power_of_two)); if (!norescale) { int newx = orig_surface->w; int maxsize = 2048; if (!IsPowerOfTwo(orig_surface->w)) { for (newx = 1; newx <= maxsize && newx <= orig_surface->w; newx = newx * 2) { } } int newy = orig_surface->h; if (!IsPowerOfTwo(orig_surface->h)) { for (newy = 1; newy <= maxsize && newy <= orig_surface->h; newy = newy * 2) { } } float scalew = ((float)newx+0.5) / orig_surface->w; float scaleh = ((float)newy+0.5) / orig_surface->h; SDL_Surface * pot_surface = zoomSurface (orig_surface, scalew, scaleh, SMOOTHING_ON); assert(IsPowerOfTwo(pot_surface->w)); assert(IsPowerOfTwo(pot_surface->h)); SDL_FreeSurface(orig_surface); orig_surface = pot_surface; texture_surface = orig_surface; } //scale texture down if necessary scale = Scale(info.size, orig_surface->w, orig_surface->h); if (scale < 1.0) { texture_surface = zoomSurface (orig_surface, scale, scale, SMOOTHING_ON); } //store dimensions w = texture_surface->w; h = texture_surface->h; GenTexture(texture_surface, info, id, alpha, error); } //free the texture surface separately if it's a scaled copy of the original if (texture_surface != orig_surface && texture_surface) { SDL_FreeSurface(texture_surface); } //free the original surface if it's not a custom surface (used for the track map) if (!info.surface && orig_surface) { SDL_FreeSurface(orig_surface); } return true; }