예제 #1
0
	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;
	}
예제 #2
0
	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 );
		}
	}
예제 #3
0
파일: sdlfontgl.cpp 프로젝트: Brybry/wTerm
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();
}
예제 #4
0
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];
}
예제 #5
0
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;
}
예제 #7
0
파일: sdlfontgl.cpp 프로젝트: Brybry/wTerm
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);
}