Example #1
0
bool Texture::Actual::createTile( SDL_Surface const* surface, int tileX, int tileY, int tileWidth, int tileHeight ) {
	// debug checks
	if ( _filename.compare( "" ) != 0 ) {
		cerr << "*** Texture::Actual::createTile() over (" << _filename << ") refused." << endl;
		return false;
	}

	_filename = "a tile";
	_width = tileWidth;
	_height = tileHeight;
	_hasAlpha = true;


	// The raw data of the source image.
	unsigned char * data = ( unsigned char * ) ( surface->pixels );
	// The destination image (a single tile)
	std::vector<GLubyte> image( tileWidth * tileHeight * 4 );

	int count = 0;
	// where the tile starts in a line
	int offs = tileX * tileWidth * 4;
	// where the tile ends in a line
	int rest = ( tileX + 1 ) * tileWidth * 4;
	// Current position in the source data
	int c = offs + ( tileY * tileHeight * surface->pitch );
	// the following lines extract R,G and B values from any bitmap

	for ( int i = 0; i < tileWidth * tileHeight; ++i ) {

		if ( i > 0 && i % tileWidth == 0 ) {
			// skip the rest of the line
			c += ( surface->pitch - rest );
			// skip the offset (go to where the tile starts)
			c += offs;
		}

		for ( int p = 0; p < 4; p++ ) {
			image[count++] = data[c++];
		}
	}

	Preferences *prefs = Session::instance->getPreferences();

	// Create The Texture
	glGenTextures( 1, &_id );

	// Typical Texture Generation Using Data From The Bitmap
	glBindTexture( GL_TEXTURE_2D, _id );

	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

	gluBuild2DMipmaps( GL_TEXTURE_2D, ( prefs->getBpp() > 16 ? GL_RGBA : GL_RGBA4 ), tileWidth, tileHeight, GL_RGBA, GL_UNSIGNED_BYTE, &image[0] );

	assert( _id != INVALID && _id != INPROGRESS );  
	_isComplete = true;
	return true;
}
Example #2
0
GLuint Texture::saveAreaUnder( int x, int y, int w, int h, GLuint *tex ) {
	// Copy to a texture the original image
	glLoadIdentity();

	glsEnable( GLS_TEXTURE_2D );

	GLuint background;

	if( !tex || *tex == 0 ) {
		glGenTextures( 1, &background );
	} else {
		background = *tex;
	}

	std::vector<unsigned char*> backgroundInMem( w * h * 4 );

	glBindTexture( GL_TEXTURE_2D, background );
	glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
	Preferences *prefs = Session::instance->getPreferences();
	glTexImage2D( GL_TEXTURE_2D, 0, ( prefs->getBpp() > 16 ? GL_RGBA : GL_RGBA4 ), w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, &backgroundInMem[0] );
	glBindTexture( GL_TEXTURE_2D, background );
	glCopyTexSubImage2D( GL_TEXTURE_2D,
	                     0,      // MIPMAP level
	                     0,      // x texture offset
	                     0,      // y texture offset
	                     0,              // x window coordinates
	                     Session::instance->getGameAdapter()->getScreenHeight() - h,   // y window coordinates
	                     w,    // width
	                     h     // height
	                   );
	return background;
}
Example #3
0
bool Texture::Actual::letsToBind() {
	if ( _isComplete ) return true;
	if ( _id == INVALID ) return false;

	if ( _width == -1 && !loadImage() ) {
		clear();
		return false;
	}

	assert( _surface != NULL );

	Preferences *prefs = Session::instance->getPreferences();

	GLuint destFormat;
	GLuint srcFormat;
	GLuint minFilter;
	GLuint magFilter;

	if ( _hasAlpha ) {
		srcFormat = GL_RGBA;
		destFormat = ( prefs->getBpp() > 16 ? GL_RGBA : GL_RGBA4 );
		minFilter = ( _isSprite ? GL_LINEAR : ( prefs->getBpp() > 16 ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST ) );
		magFilter = GL_LINEAR;
	} else {
		srcFormat = GL_RGB;
		destFormat = ( prefs->getBpp() > 16 ? GL_RGB : GL_RGB5 );
		minFilter = GL_LINEAR_MIPMAP_LINEAR;
		magFilter = prefs->getBpp() > 16 ? GL_LINEAR : GL_NEAREST;
	}

	glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
	glGenTextures( 1, &_id );
	glBindTexture( GL_TEXTURE_2D, _id );

	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter );

	// Enable anisotropic filtering if requested, mipmapping is enabled
	// and the hardware supports it.
	if ( _wantsAnisotropy && !_hasAlpha
	        && strstr( ( char* )glGetString( GL_EXTENSIONS ), "GL_EXT_texture_filter_anisotropic" )
	        && prefs->getAnisoFilter() ) {
		float maxAnisotropy;
		glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy );
		glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy );
	} else {
		glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f );
	}

	// lordthoran said glTexImage2D causes white textures
	// glTexImage2D( GL_TEXTURE_2D, 0, destFormat, _width, _height, 0, srcFormat, GL_UNSIGNED_BYTE, surface->pixels );

	gluBuild2DMipmaps( GL_TEXTURE_2D, destFormat, _width, _height, srcFormat, GL_UNSIGNED_BYTE, _surface->pixels );

	unloadImage();

	if ( _priority > 0 ) glPrioritizeTextures( 1, &_id, &_priority );

	assert( _id != INVALID && _id != INPROGRESS );  
	_isComplete = true;
	return true;
}
Example #4
0
bool Texture::Actual::createAlpha( Actual* alpha, Actual* sample[], int sampleCount, int textureSizeW, int textureSizeH, int width, int height ) {
	// debug checks
	if ( _filename.compare( "" ) != 0 ) {
		cerr << "*** Texture::Actual::createAlpha() over (" << _filename << ") refused." << endl;
		return false;
	}
	if ( alpha == NULL || !alpha->letsToBind() ) {
		cerr << "*** Texture::Actual::createAlpha() with missing alpha texture." << endl;
		return false;
	}
	for( int i = 0; i < sampleCount; i++ ) {
		if ( sample[i] == NULL || !sample[i]->letsToBind() ) {
			cerr << "*** Texture::Actual::createAlpha() with missing sample texture. i=" << i << endl;
			return false;
		}
	}
	
	Preferences *prefs = Session::instance->getPreferences();
	
	GLuint background = saveAreaUnder( 0, 0, textureSizeW, textureSizeH );

	_filename = "";
	for( int i = 0; i < sampleCount; i++ ) {
		if( i > 0 ) _filename += ",";
		_filename += sample[i]->_filename;
	}
	_filename += " with added alpha";
	
	_width = width; 
	_height = height;
	_hasAlpha = true;

	std::vector<unsigned char*> texInMem( textureSizeW * textureSizeH * 4 );
	//GLuint tex[1];

	glsDisable( GLS_CULL_FACE | GLS_DEPTH_TEST );
	glsEnable( GLS_TEXTURE_2D );

	glGenTextures( 1, &_id );
	glBindTexture( GL_TEXTURE_2D, _id );
	glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );

	/**
	 * This method should not create mip-maps. They don't work well with alpha-tested textures and cause flickering.
	 */
	//glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, isSprite ? GL_NEAREST : GL_LINEAR_MIPMAP_NEAREST );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
	glTexImage2D( GL_TEXTURE_2D, 0, ( prefs->getBpp() > 16 ? GL_RGBA : GL_RGBA4 ), textureSizeW, textureSizeH, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texInMem[0] );
	//if( !isSprite ) gluBuild2DMipmaps(GL_TEXTURE_2D, 4, textureSizeW, textureSizeH, GL_BGRA, GL_UNSIGNED_BYTE, texInMem);

	glPushMatrix();
	glLoadIdentity();

	glsDisable( GLS_TEXTURE_2D );

	glColor4f( 0.0f, 0.0f, 0.0f, 0.0f );

	glBegin( GL_TRIANGLE_STRIP );
	glVertex2i( 0, 0 );
	glVertex2i( textureSizeW, 0 );
	glVertex2i( 0, textureSizeH );
	glVertex2i( textureSizeW, textureSizeH );
	glEnd();

	glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );

	// draw the grass
	glsEnable( GLS_TEXTURE_2D );

	for( int i = 0; i < sampleCount; i++ ) {
		glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
		drawQuad( sample[i]->_id, width, height );
	}

	// draw the alpha pixels only
	glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE );

	glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );

	drawQuad( alpha->_id, width, height );

	glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );

	// Copy to a texture
	glLoadIdentity();

	glsEnable( GLS_TEXTURE_2D );

	glBindTexture( GL_TEXTURE_2D, _id );
	glCopyTexSubImage2D( GL_TEXTURE_2D,
	                     0,      // MIPMAP level
	                     0,      // x texture offset
	                     0,      // y texture offset
	                     0,              // x window coordinates
	                     Session::instance->getGameAdapter()->getScreenHeight() - textureSizeH,   // y window coordinates
	                     textureSizeW,    // width
	                     textureSizeH     // height
	                   );

	// cover with the original
	drawQuad( background, width, height );

	glPopMatrix();

	glDeleteTextures( 1, &background );

	glsDisable( GLS_BLEND );
	glsEnable( GLS_CULL_FACE | GLS_DEPTH_TEST );

	assert( _id != INVALID && _id != INPROGRESS );  
	_isComplete = true;
	return true;
}
Example #5
0
bool Texture::Actual::createEdgeBlended( const string& path, Actual* original, Actual* west, Actual* east, Actual* south, Actual* north,
                                         Actual* edge, Actual* corner, Actual* tip, Actual* hole ) {
	// debug checks
	if ( original == NULL || !original->letsToBind() ) {
		cerr << "*** Texture::Actual::createEdgeBlended() with missing original texture." << endl;
		return false;
	}
	if ( west == NULL || !west->letsToBind() ) {
//		cerr << "*** Texture::Actual::createEdgeBlended() with missing west texture." << endl;
//		return false;
	}
	if ( east == NULL || !east->letsToBind() ) {
//		cerr << "*** Texture::Actual::createEdgeBlended() with missing east texture." << endl;
//		return false;
	}
	if ( south == NULL || !south->letsToBind() ) {
//		cerr << "*** Texture::Actual::createEdgeBlended() with missing south texture." << endl;
//		return false;
	}
	if ( north == NULL || !north->letsToBind() ) {
//		cerr << "*** Texture::Actual::createEdgeBlended() with missing north texture." << endl;
//		return false;
	}
	if ( edge == NULL || !edge->letsToBind() ) {
		cerr << "*** Texture::Actual::createEdgeBlended() with missing edge texture." << endl;
		return false;
	}
	if ( corner == NULL || !corner->letsToBind() ) {
		cerr << "*** Texture::Actual::createEdgeBlended() with missing corner texture." << endl;
		return false;
	}
	if ( tip == NULL || !tip->letsToBind() ) {
		cerr << "*** Texture::Actual::createEdgeBlended() with missing tip texture." << endl;
		return false;
	}
	if ( hole == NULL || !hole->letsToBind() ) {
		cerr << "*** Texture::Actual::createEdgeBlended() with missing hole texture:" << hole->_filename << endl;
		return false;
	}
	
	_filename = path;
	
	Preferences *prefs = Session::instance->getPreferences();
	int textureSizeW = 256;
	int textureSizeH = 256;

//	cerr << "creating blended edge: " << _filename << endl;

	_width = textureSizeW;
	_height = textureSizeH;
	_isSprite = original->_isSprite;
	_wantsAnisotropy = original->_wantsAnisotropy;	
	_hasAlpha = true;
	
	std::vector<unsigned char*> texInMem( textureSizeW * textureSizeH * 4 );
			
	glGenTextures( 1, &_id );
	glBindTexture( GL_TEXTURE_2D, _id );
	glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
	
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
	
	glTexImage2D( GL_TEXTURE_2D, 0, ( prefs->getBpp() > 16 ? GL_RGBA : GL_RGBA4 ), textureSizeW, textureSizeH, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texInMem[0] );
	

	glPushMatrix();
	GLuint background = saveAreaUnder( 0, 0, textureSizeW, textureSizeH );

	// create a tmp alpha texture
	vector<float> angles;
	vector<Actual*> tmps;

//	cerr << "n=" << north->_id << " w=" << west->_id << " e=" << east->_id << " s=" << south->_id << endl;
	
	bool n = false;
	bool w = false;
	bool e = false;
	bool s = false;
	if( !north->matches( original ) && north->matches( east ) && north->matches( south ) && north->matches( west ) ) {
		Actual *tmp2 = new Actual;
		tmp2->createAlpha( hole, &north, 1, _width, _height, _width, _height );
		tmps.push_back( tmp2 );
		angles.push_back( 0.0f );
		n = e = s = w = true;
//		cerr << "\thole" << endl;
	} else if( !north->matches( original ) && north->matches( east ) && north->matches( south ) ) {
		Actual *tmp2 = new Actual;
		tmp2->createAlpha( tip, &north, 1, _width, _height, _width, _height );
		tmps.push_back( tmp2 );
		angles.push_back( 90.0f );
		n = e = s = true;
//		cerr << "\ttip 1" << endl;
	} else if( !east->matches( original ) && east->matches( south ) && east->matches( west ) ) {
		Actual *tmp2 = new Actual;
		tmp2->createAlpha( tip, &east, 1, _width, _height, _width, _height );
		tmps.push_back( tmp2 );
		angles.push_back( 0.0f );
		e = s = w = true;
//		cerr << "\ttip 2" << endl;
	} else if( !south->matches( original ) && south->matches( west ) && south->matches( north ) ) {
		Actual *tmp2 = new Actual;
		tmp2->createAlpha( tip, &south, 1, _width, _height, _width, _height );
		tmps.push_back( tmp2 );
		angles.push_back( 270.0f );
		s = w = n = true;
//		cerr << "\ttip 3" << endl;
	} else if( !west->matches( original ) && west->matches( north ) && west->matches( east ) ) {
		Actual *tmp2 = new Actual;
		tmp2->createAlpha( tip, &west, 1, _width, _height, _width, _height );
		tmps.push_back( tmp2 );
		angles.push_back( 180.0f );
		w = n = e = true;
//		cerr << "\ttip 4" << endl;
	} else {
		if( !north->matches( original ) && north->matches( east ) ) {
			Actual *tmp2 = new Actual;
			tmp2->createAlpha( corner, &north, 1, _width, _height, _width, _height );
			tmps.push_back( tmp2 );
			angles.push_back( 180.0f );
			n = e = true;
//			cerr << "\tcorner 1" << endl;
		}
		if( !east->matches( original ) && east->matches( south ) ) {
			Actual *tmp2 = new Actual;
			tmp2->createAlpha( corner, &east, 1, _width, _height, _width, _height );
			tmps.push_back( tmp2 );
			angles.push_back( 90.0f );
			e = s = true;
//			cerr << "\tcorner 2" << endl;
		}
		if( !south->matches( original ) && south->matches( west ) ) {
			Actual *tmp2 = new Actual;
			tmp2->createAlpha( corner, &south, 1, _width, _height, _width, _height );
			tmps.push_back( tmp2 );
			angles.push_back( 0.0f );
			s = w = true;
//			cerr << "\tcorner 3" << endl;
		}	
		if( !west->matches( original ) && west->matches( north ) ) {
			Actual *tmp2 = new Actual;
			tmp2->createAlpha( corner, &west, 1, _width, _height, _width, _height );
			tmps.push_back( tmp2 );
			angles.push_back( 270.0f );
			w = n = true;
//			cerr << "\tcorner 4" << endl;
		}	
	}
	
	if( !n && !north->matches( original ) && north->_id != INVALID ) {
		Actual *tmp2 = new Actual;
		tmp2->createAlpha( edge, &north, 1, _width, _height, _width, _height );
		tmps.push_back( tmp2 );
		angles.push_back( 270.0f );
//		cerr << "\tedge 1" << endl;
	}
	if( !w && !west->matches( original ) && west->_id != INVALID ) {
		Actual *tmp2 = new Actual;
		tmp2->createAlpha( edge, &west, 1, _width, _height, _width, _height );
		tmps.push_back( tmp2 );
		angles.push_back( 0.0f );
//		cerr << "\tedge 2" << endl;
	}
	if( !e && !east->matches( original ) && east->_id != INVALID ) {
		Actual *tmp2 = new Actual;
		tmp2->createAlpha( edge, &east, 1, _width, _height, _width, _height );
		tmps.push_back( tmp2 );
		angles.push_back( 180.0f );
//		cerr << "\tedge 3" << endl;
	}	
	if( !s && !south->matches( original ) && south->_id != INVALID ) {
		Actual *tmp2 = new Actual;
		tmp2->createAlpha( edge, &south, 1, _width, _height, _width, _height );
		tmps.push_back( tmp2 );
		angles.push_back( 90.0f );
//		cerr << "\tedge 4" << endl;
	}		
		
	glsDisable( GLS_BLEND | GLS_DEPTH_TEST | GLS_CULL_FACE );
	glsEnable( GLS_TEXTURE_2D );
	
	glLoadIdentity();
	
	glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
	
	// draw the original
	drawQuad( original->_id, _width, _height );

	// blend in the tmp
	glsDisable( GLS_DEPTH_MASK );
	glsEnable( GLS_BLEND );
	glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
	
	for( unsigned int i = 0; i < tmps.size(); i++ ) {
		glPushMatrix();
		glLoadIdentity();
		glTranslatef( _width / 2.0f, _height / 2.0f, 0.0f );
		glRotatef( angles[i], 0.0f, 0.0f, 1.0f );
		glTranslatef( -_width / 2.0f, -_height / 2.0f, 0.0f );
		drawQuad( tmps[i]->_id, _width, _height );
		glPopMatrix();
	}
	
	glsDisable( GLS_BLEND );
	glsEnable( GLS_TEXTURE_2D | GLS_DEPTH_MASK );
	
	// Copy to a texture
	glLoadIdentity();

	glBindTexture( GL_TEXTURE_2D, _id );

	glCopyTexSubImage2D( GL_TEXTURE_2D,
	                     0,      // MIPMAP level
	                     0,      // x texture offset
	                     0,      // y texture offset
	                     0,              // x window coordinates
	                     Session::instance->getGameAdapter()->getScreenHeight() - textureSizeH,   // y window coordinates
	                     textureSizeW,    // width
	                     textureSizeH     // height
	                   );
	
	// delete the tmps
	for( unsigned int i = 0; i < tmps.size(); i++ ) {
		delete tmps[i];
	}

	// cover with the original
	drawQuad( background, _width, _height );

	glPopMatrix();

	glDeleteTextures( 1, &background );

	glsDisable( GLS_BLEND );
	glsEnable( GLS_CULL_FACE | GLS_DEPTH_TEST );

	assert( _id != INVALID && _id != INPROGRESS );  
	_isComplete = true;
	return true;

}