void NativeImage::refreshTexture() { RasterImage::Ptr image = this->image.lock(); if (!image) { return; } RasterReadAccess access(image); if (textureStatus == TEXTURE_OK) { return; } size = access.size; if ((textureStatus & TEXTURE_CLEAR) != 0) { if (texture != 0) { glDeleteTextures(1, &texture); } texture = 0; } if ((textureStatus & TEXTURE_RESIZE) != 0 && !size.isZero()) { glGenTextures(1, &texture); glEnable(GL_TEXTURE_RECTANGLE_ARB); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, getGLFormat(access.components), size.width, size.height, 0, getGLFormat(access.components), GL_UNSIGNED_BYTE, 0); glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glDisable(GL_TEXTURE_RECTANGLE_ARB); } if ((textureStatus & TEXTURE_UPDATE) != 0 && !size.isZero()) { GLint prevAlignment; glGetIntegerv(GL_UNPACK_ALIGNMENT, &prevAlignment); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glEnable(GL_TEXTURE_RECTANGLE_ARB); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, size.width, size.height, getGLFormat(access.components), GL_UNSIGNED_BYTE, access.data); glDisable(GL_TEXTURE_RECTANGLE_ARB); glPixelStorei(GL_UNPACK_ALIGNMENT, prevAlignment); } textureStatus = TEXTURE_OK; }
void GLTexture::alloc( const Image& img, bool copy ) { GLenum glformat, gltype/*, internalformat*/; size_t stride; const uint8_t* ptr; getGLFormat( glformat, gltype, img.format() ); _width = img.width(); _height = img.height(); _internalFormat = glformat; glBindTexture( GL_TEXTURE_2D, _tex ); // FIXME: move outside glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if( copy ) { ptr = img.map( &stride ); // FIXME: we assume that image memory is always aligned - at least to 4 bytes //glPixelStorei( GL_UNPACK_ALIGNMENT, ) glPixelStorei( GL_UNPACK_ROW_LENGTH, ( GLint ) ( stride / ( img.format().bpp ) ) ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, ( GLsizei ) _width, ( GLsizei ) _height, 0, glformat, gltype, ptr ); glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 ); img.unmap( ptr ); } else { glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, ( GLsizei ) _width, ( GLsizei ) _height, 0, glformat, gltype, NULL ); } }
void SDLFontGL::createTexture() { // Create Big GL texture: glGenTextures(1,&GlyphCache); glBindTexture(GL_TEXTURE_2D, GlyphCache); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Set size of the texture, but no data. // We want 1 extra row of pixel data // so we can draw solid colors as part // of the same operations. texW = nextPowerOfTwo(nChars*nWidth); texH = nextPowerOfTwo(nFonts*nHeight + 1); int nMode = getGLFormat(); glTexImage2D(GL_TEXTURE_2D, 0, nMode, texW, texH, 0, nMode, GL_UNSIGNED_BYTE, NULL); // Put a single white pixel at bottom of texture. // We use this as the 'texture' data for blitting // solid backgrounds. char whitepixel[] = { 255, 255, 255, 255 }; assert(nFonts && nHeight); glTexSubImage2D(GL_TEXTURE_2D, 0, 0,nFonts*nHeight, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, whitepixel); checkGLError(); }
const Texture* Texture::load(const std::string& fileName) { if (sTextureMap.find(fileName) != sTextureMap.end()) { unload(sTextureMap[fileName]); } const std::string path = sBasePath + fileName; FREE_IMAGE_FORMAT fif = FreeImage_GetFileType(path.c_str(), 0); if (fif == FIF_UNKNOWN) { fif = FreeImage_GetFIFFromFilename(path.c_str()); } if (fif == FIF_UNKNOWN) { return nullptr; } FIBITMAP* dib = nullptr; if (FreeImage_FIFSupportsReading(fif)) { dib = FreeImage_Load(fif, path.c_str()); } if (!dib) { return nullptr; } BYTE* bits = FreeImage_GetBits(dib); unsigned int width = FreeImage_GetWidth(dib); unsigned int height = FreeImage_GetHeight(dib); if (bits == 0 || width == 0 || height == 0) { return nullptr; } FREE_IMAGE_COLOR_TYPE colorType = FreeImage_GetColorType(dib); FREE_IMAGE_TYPE imageType = FreeImage_GetImageType(dib); GLenum glFormat = getGLFormat(colorType); Texture tex; tex.mName = fileName; glGenTextures(1, &tex.mId); assert(tex.mId); glBindTexture(GL_TEXTURE_2D, tex.mId); glTexImage2D(GL_TEXTURE_2D, 0, glFormat, width, height, 0, glFormat, GL_UNSIGNED_BYTE, bits); glGenerateMipmap(GL_TEXTURE_2D); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); sTextureMap[fileName] = tex; FreeImage_Unload(dib); return &sTextureMap[fileName]; }
OGLplusExampleGLWidget::OGLplusExampleGLWidget( QWidget *parent_widget, int argn, char **args, const char* ss_path ) : QGLWidget(getGLFormat(), parent_widget) , argc(argn) , argv(args) , screenshot_path(ss_path) { setMouseTracking(true); }
bool OpenGLTextureBuilder::createNewTexture(IND_Surface *pNewSurface, IND_Image *pImage, int pBlockSizeX, int pBlockSizeY) { #ifdef _DEBUG GLboolean enabled; glGetBooleanv(GL_TEXTURE_2D,&enabled); if (GL_FALSE == enabled){ g_debug->header("GL Textures not enabled!!", DebugApi::LogHeaderError); return false; } #endif // ----- Cutting blocks ----- INFO_SURFACE mI; _cutter->fillInfoSurface(pImage, &mI, pBlockSizeX, pBlockSizeY); pNewSurface->freeTextureData(); //Guard against using same texture data all over again in same surface pNewSurface->_surface = new SURFACE(mI._numBlocks,mI._numVertices); pNewSurface->_surface->_attributes._type = mI._type; pNewSurface->_surface->_attributes._quality = mI._quality; pNewSurface->_surface->_attributes._blocksX = mI._blocksX; pNewSurface->_surface->_attributes._blocksY = mI._blocksY; pNewSurface->_surface->_attributes._spareX = mI._spareX; pNewSurface->_surface->_attributes._spareY = mI._spareY; pNewSurface->_surface->_attributes._numBlocks = mI._numBlocks; pNewSurface->_surface->_attributes._numTextures = mI._numBlocks; pNewSurface->_surface->_attributes._isHaveGrid = 0; pNewSurface->_surface->_attributes._widthBlock = mI._widthBlock; pNewSurface->_surface->_attributes._heightBlock = mI._heightBlock; pNewSurface->_surface->_attributes._width = mI._widthImage; pNewSurface->_surface->_attributes._height = mI._heightImage; pNewSurface->_surface->_attributes._isHaveSurface = 1; assert(pNewSurface->_surface->_texturesArray); //Should have allocated textures array! glGenTextures(mI._numBlocks,pNewSurface->_surface->_texturesArray); GLenum glerror = glGetError(); if (glerror) { g_debug->header("OpenGL error while creating textures ", DebugApi::LogHeaderError); return false; } GLint mInternalFormat, mFormat, mType; //Get format and type of surface (image) in GL types (and check for compatibilities) getGLFormat(pNewSurface,pImage,&mInternalFormat,&mFormat,&mType); // ----- Vertex creation ----- // Current position of the vertex int mPosX = 0; int mPosY = mI._heightImage; int mPosZ = 0; // Position in wich we are storing a vertex int mPosVer = 0; // Position in wich we are storing a texture int mCont = 0; // Image pointer unsigned char *mPtrBlock = pImage->getPointer(); // Vars int mActualWidthBlockX (0); int mActualHeightBlockY (0); float mActualU (0); float mActualV (0); int mActualSpareX (0); int mActualSpareY (0); int mSrcBytespp = pImage->getBytespp(); // ----- Cutting blocks ----- // We iterate the blocks starting from the lower row // We MUST draw the blocks in this order, because the image starts drawing from the lower-left corner //LOOP - All blocks (Y coords) for (int i = mI._blocksY; i > 0; i--) { //LOOP - All blocks (X coords) for (int j = 1; j < mI._blocksX + 1; j++) { // ----- Vertices position of the block ----- // There are 4 types of blocks: the ones of the right column, the ones of the upper row, // the one of the upper-right corner and the rest of blocks. // Depending on the block, we store the vertices one way or another. // Normal block if (i != 1 && j != mI._blocksX) { mActualWidthBlockX = mI._widthBlock; mActualHeightBlockY = mI._heightBlock; mActualU = 1.0f; mActualV = 1.0f; mActualSpareX = 0; mActualSpareY = 0; } // The ones of the right column if (i != 1 && j == mI._blocksX) { mActualWidthBlockX = mI._widthSpareImage; mActualHeightBlockY = mI._heightBlock; mActualU = (float) mI._widthSpareImage / mI._widthBlock; mActualV = 1.0f; mActualSpareX = mI._spareX; mActualSpareY = 0; } // The ones of the upper row if (i == 1 && j != mI._blocksX) { mActualWidthBlockX = mI._widthBlock; mActualHeightBlockY = mI._heightSpareImage; mActualU = 1.0f; mActualV = (float) mI._heightSpareImage / mI._heightBlock; mActualSpareX = 0; mActualSpareY = mI._spareY; } // The one of the upper-right corner if (i == 1 && j == mI._blocksX) { mActualWidthBlockX = mI._widthSpareImage; mActualHeightBlockY = mI._heightSpareImage; mActualU = (float) mI._widthSpareImage / mI._widthBlock; mActualV = (float) mI._heightSpareImage / mI._heightBlock; mActualSpareX = mI._spareX; mActualSpareY = mI._spareY; } // ----- Block creation (using the position, uv coordiantes and texture) ----- // We push into the buffer the 4 vertices of the block push4Vertices(pNewSurface->_surface->_vertexArray, // Pointer to the buffer mPosVer, // Position in wich we are storing a vertex mPosX, // x mPosY, // y mPosZ, // z mActualWidthBlockX, // Block width mActualHeightBlockY, // Block height mActualU, // U mapping coordinate mActualV); // V mapping coordinate // Cuts a block from the image (bitmap) unsigned char *mTempBlock = 0; _cutter->cutBlock(mPtrBlock, mI._widthImage, mI._widthBlock, mI._heightBlock, mActualSpareX, mActualSpareY, mSrcBytespp, &mTempBlock); // We create a texture using the cut bitmap block glBindTexture(GL_TEXTURE_2D,pNewSurface->_surface->_texturesArray[mCont]); glTexImage2D(GL_TEXTURE_2D, 0, mInternalFormat, mI._widthBlock, mI._heightBlock, 0, mFormat, mType, mTempBlock); // Free the bitmap cutted block DISPOSEARRAY(mTempBlock); GLenum glerror = glGetError(); if (glerror) { g_debug->header("OpenGL error while assigning texture to buffer", DebugApi::LogHeaderError); //TODO: Test error and mem. leaks return false; } // ----- Advance ----- // Increase in 4 vertices the position (we have already stored a quad) mPosVer += 4; // Increase the texture counter (we have alread stored one texture) mCont++; // ----- Column change ----- // We point to the next block (memory and screen) mPosX += mI._widthBlock; mPtrBlock += mI._widthBlock * mSrcBytespp; }//LOOP END - All blocks (Y coords) // ----- Row change ----- // We point to the next block (memory and screen) mPosX = 0; mPtrBlock -= mI._spareX * mSrcBytespp; // If this block is in the last row, we take in count the spare areas. if (i == 1) { mPosY -= mI._spareY; mPtrBlock += (mI._widthImage * mSrcBytespp) * (mI._spareY - 1); } else { mPosY -= mI._heightBlock; mPtrBlock += (mI._widthImage * mSrcBytespp) * (mI._heightBlock - 1); } } //LOOP END - All blocks (Y coords) return true; }
void SDLFontGL::ensureFontLine(int fnt) { assert(fnt >= 0 && fnt < nFonts); assert(fnts && cols && GlyphCache && haveFontLine); bool & have = haveFontLine[fnt]; if (have) { return; } have = true; // Lookup requested font TTF_Font * font = fnts[fnt]; assert(font); // Grab the native video surface (so we can match its bpp) SDL_Surface* videoSurface = SDL_GetVideoSurface(); assert(videoSurface); assert(videoSurface->format->BitsPerPixel == 32); // Create a surface for all the characters Uint32 rmask, gmask, bmask, amask; getRGBAMask(rmask, gmask, bmask, amask); SDL_Surface* mainSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, nChars*nWidth, nHeight, videoSurface->format->BitsPerPixel, rmask, gmask, bmask, amask); assert(mainSurface); // Render font in white, will colorize on-the-fly SDL_Color fg = { 255, 255, 255 }; // Set texture to entirely clear // TODO: Needed? Uint32 fillColor = SDL_MapRGBA(mainSurface->format, 0, 0, 0, SDL_ALPHA_TRANSPARENT); SDL_FillRect(mainSurface, NULL, fillColor); // For each character, render the glyph, and put in the appropriate location for(int i = 0; i < nChars; ++i) { // Make a little string out of the character char buf[2] = { printableChars[i], 0 }; SDL_Surface* surface = TTF_RenderText_Blended(font, (const char*)buf, fg); SDL_SetAlpha(surface, 0, 0); SDL_Rect dstRect = { 0, 0, nWidth, nHeight }; dstRect.x = i*nWidth; SDL_BlitSurface(surface, 0, mainSurface, &dstRect); SDL_FreeSurface(surface); } // Now upload the big set of characters as a single texture: { int nMode = getGLFormat(); glBindTexture(GL_TEXTURE_2D, GlyphCache); // Upload this font to its place in the big texture glTexSubImage2D(GL_TEXTURE_2D, 0, 0, fnt*nHeight, mainSurface->w, mainSurface->h, nMode, GL_UNSIGNED_BYTE, mainSurface->pixels); glFlush(); } SDL_FreeSurface(mainSurface); }