Beispiel #1
0
void RE_UploadCinematic(int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty)
{
	GL_Bind(tr.scratchImage[client]);

	// if the scratchImage isn't in the format we want, specify it as a new texture
	if (cols != tr.scratchImage[client]->width || rows != tr.scratchImage[client]->height)
	{
		tr.scratchImage[client]->width  = tr.scratchImage[client]->uploadWidth = cols;
		tr.scratchImage[client]->height = tr.scratchImage[client]->uploadHeight = rows;
		qglTexImage2D(GL_TEXTURE_2D, 0, 3, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	}
	else
	{
		if (dirty)
		{
			// otherwise, just subimage upload it so that drivers can tell we are going to be changing
			// it and don't try and do a texture compression
			qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data);
		}
	}
}
static int setupScreenKeyboardButton( int buttonID, Uint8 * charBuf )
{
	// TODO: softstretch with antialiasing
	int w, h,  format;
	GLTexture_t * data = NULL;
	int texture_w, texture_h;
	
	if( buttonID < 1 )
		data = &arrowImages;
	else
		data = &(buttonImages[buttonID-1]);


	memcpy(&w, charBuf, sizeof(int));
	memcpy(&h, charBuf + sizeof(int), sizeof(int));
	memcpy(&format, charBuf + 2*sizeof(int), sizeof(int));
	w = ntohl(w);
	h = ntohl(h);
	format = ntohl(format);
	
	texture_w = power_of_2(w);
	texture_h = power_of_2(h);
	data->w = texture_w;
	data->h = texture_h;
	LOGI("data w:%d, h:%d\n", w, h);

	qglEnable(GL_TEXTURE_2D);

	qglGenTextures(1, &data->id);
	
	qglBindTexture(GL_TEXTURE_2D, data->id);
	LOGI("On-screen keyboard generated OpenGL texture ID %x", data->id);

	qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_w, texture_h, 0, GL_RGBA,
					format ? GL_UNSIGNED_SHORT_4_4_4_4 : GL_UNSIGNED_SHORT_5_5_5_1, NULL);
	qglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	
	qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA,
						format ? GL_UNSIGNED_SHORT_4_4_4_4 : GL_UNSIGNED_SHORT_5_5_5_1,
						charBuf + 3*sizeof(int) );

	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

	qglDisable(GL_TEXTURE_2D);

	return 3*sizeof(int) + w * h * 2;
}
Beispiel #3
0
/*
=============
RE_StretchRaw

FIXME: not exactly backend
Stretches a raw 32 bit power of 2 bitmap image over the given screen rectangle.
Used for cinematics.
=============
*/
void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty) {
	int			i, j;
	int			start, end;

	if ( !tr.registered ) {
		return;
	}
	R_SyncRenderThread();

	// we definately want to sync every frame for the cinematics
	qglFinish();

	start = end = 0;
	if ( r_speeds->integer ) {
		start = ri.Milliseconds();
	}

	// make sure rows and cols are powers of 2
	for ( i = 0 ; ( 1 << i ) < cols ; i++ ) {
	}
	for ( j = 0 ; ( 1 << j ) < rows ; j++ ) {
	}
	if ( ( 1 << i ) != cols || ( 1 << j ) != rows) {
		ri.Error (ERR_DROP, "Draw_StretchRaw: size not a power of 2: %i by %i", cols, rows);
	}

	GL_Bind( tr.scratchImage[client] );

	// if the scratchImage isn't in the format we want, specify it as a new texture
	if ( cols != tr.scratchImage[client]->width || rows != tr.scratchImage[client]->height ) {
		tr.scratchImage[client]->width = tr.scratchImage[client]->uploadWidth = cols;
		tr.scratchImage[client]->height = tr.scratchImage[client]->uploadHeight = rows;
		qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
		qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
		qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
		qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
		qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );	
	} else {
		if (dirty) {
			// otherwise, just subimage upload it so that drivers can tell we are going to be changing
			// it and don't try and do a texture compression
			qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data );
		}
	}

	if ( r_speeds->integer ) {
		end = ri.Milliseconds();
		ri.Printf( PRINT_ALL, "qglTexSubImage2D %i, %i: %i msec\n", cols, rows, end - start );
	}

	RB_SetGL2D();

	qglColor3f( tr.identityLight, tr.identityLight, tr.identityLight );

	qglBegin (GL_QUADS);
	qglTexCoord2f ( 0.5f / cols,  0.5f / rows );
	qglVertex2f (x, y);
	qglTexCoord2f ( ( cols - 0.5f ) / cols ,  0.5f / rows );
	qglVertex2f (x+w, y);
	qglTexCoord2f ( ( cols - 0.5f ) / cols, ( rows - 0.5f ) / rows );
	qglVertex2f (x+w, y+h);
	qglTexCoord2f ( 0.5f / cols, ( rows - 0.5f ) / rows );
	qglVertex2f (x, y+h);
	qglEnd ();
}
Beispiel #4
0
GLvoid APIENTRY GLDSA_TextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset,
	GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
{
	GL_BindMultiTexture(glDsaState.texunit, target, texture);
	qglTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
}
	/*
	=============
	RE_StretchRaw

	FIXME: not exactly backend
	Stretches a raw 32 bit power of 2 bitmap image over the given screen rectangle.
	Used for cinematics.
	=============
	*/
	void RE_StretchRaw( int x, int y, int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty )
	{
		int i, j;
		int start, end;

		if ( !tr.registered )
		{
			return;
		}

		R_SyncRenderThread();

		// we definitely want to sync every frame for the cinematics
#if defined( USE_D3D10 )
		// TODO
#else
		qglFinish();
#endif

		start = end = 0;

		if ( r_speeds->integer )
		{
#if defined( USE_D3D10 )
			// TODO
#else
			qglFinish();
#endif
			start = ri.Milliseconds();
		}

		// make sure rows and cols are powers of 2
		for ( i = 0; ( 1 << i ) < cols; i++ )
		{
		}

		for ( j = 0; ( 1 << j ) < rows; j++ )
		{
		}

		if ( ( 1 << i ) != cols || ( 1 << j ) != rows )
		{
			ri.Error( ERR_DROP, "Draw_StretchRaw: size not a power of 2: %i by %i", cols, rows );
		}

#if defined( USE_D3D10 )
		// TODO
#else
		RB_SetGL2D();

		qglVertexAttrib4fARB( ATTR_INDEX_NORMAL, 0, 0, 1, 1 );
		qglVertexAttrib4fARB( ATTR_INDEX_COLOR, tr.identityLight, tr.identityLight, tr.identityLight, 1 );

		GL_BindProgram( &tr.genericSingleShader );

		// set uniforms
		GLSL_SetUniform_TCGen_Environment( &tr.genericSingleShader,  qfalse );
		GLSL_SetUniform_ColorGen( &tr.genericSingleShader, CGEN_VERTEX );
		GLSL_SetUniform_AlphaGen( &tr.genericSingleShader, AGEN_VERTEX );

		//GLSL_SetUniform_Color(&tr.genericSingleShader, colorWhite);
		if ( glConfig.vboVertexSkinningAvailable )
		{
			GLSL_SetUniform_VertexSkinning( &tr.genericSingleShader, qfalse );
		}

		GLSL_SetUniform_DeformGen( &tr.genericSingleShader, DGEN_NONE );
		GLSL_SetUniform_AlphaTest( &tr.genericSingleShader, 0 );
		GLSL_SetUniform_ModelViewProjectionMatrix( &tr.genericSingleShader, glState.modelViewProjectionMatrix[ glState.stackIndex ] );

		// bind u_ColorMap
		GL_SelectTexture( 0 );
		GL_Bind( tr.scratchImage[ client ] );
		GLSL_SetUniform_ColorTextureMatrix( &tr.genericSingleShader, matrixIdentity );

		// if the scratchImage isn't in the format we want, specify it as a new texture
		if ( cols != tr.scratchImage[ client ]->width || rows != tr.scratchImage[ client ]->height )
		{
			tr.scratchImage[ client ]->width = tr.scratchImage[ client ]->uploadWidth = cols;
			tr.scratchImage[ client ]->height = tr.scratchImage[ client ]->uploadHeight = rows;

			qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );

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

			qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
			qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
		}
		else
		{
			if ( dirty )
			{
				// otherwise, just subimage upload it so that drivers can tell we are going to be changing
				// it and don't try and do a texture compression
				qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data );
			}
		}

#endif // #if defined(USE_D3D10)

		if ( r_speeds->integer )
		{
#if defined( USE_D3D10 )
			// TODO
#else
			qglFinish();
#endif
			end = ri.Milliseconds();
			ri.Printf( PRINT_ALL, "qglTexSubImage2D %i, %i: %i msec\n", cols, rows, end - start );
		}

		tess.numVertexes = 0;
		tess.numIndexes = 0;

		tess.xyz[ tess.numVertexes ][ 0 ] = x;
		tess.xyz[ tess.numVertexes ][ 1 ] = y;
		tess.xyz[ tess.numVertexes ][ 2 ] = 0;
		tess.xyz[ tess.numVertexes ][ 3 ] = 1;
		tess.texCoords[ tess.numVertexes ][ 0 ] = 0.5f / cols;
		tess.texCoords[ tess.numVertexes ][ 1 ] = 0.5f / rows;
		tess.texCoords[ tess.numVertexes ][ 2 ] = 0;
		tess.texCoords[ tess.numVertexes ][ 3 ] = 1;
		tess.numVertexes++;

		tess.xyz[ tess.numVertexes ][ 0 ] = x + w;
		tess.xyz[ tess.numVertexes ][ 1 ] = y;
		tess.xyz[ tess.numVertexes ][ 2 ] = 0;
		tess.xyz[ tess.numVertexes ][ 3 ] = 1;
		tess.texCoords[ tess.numVertexes ][ 0 ] = ( cols - 0.5f ) / cols;
		tess.texCoords[ tess.numVertexes ][ 1 ] = 0.5f / rows;
		tess.texCoords[ tess.numVertexes ][ 2 ] = 0;
		tess.texCoords[ tess.numVertexes ][ 3 ] = 1;
		tess.numVertexes++;

		tess.xyz[ tess.numVertexes ][ 0 ] = x + w;
		tess.xyz[ tess.numVertexes ][ 1 ] = y + h;
		tess.xyz[ tess.numVertexes ][ 2 ] = 0;
		tess.xyz[ tess.numVertexes ][ 3 ] = 1;
		tess.texCoords[ tess.numVertexes ][ 0 ] = ( cols - 0.5f ) / cols;
		tess.texCoords[ tess.numVertexes ][ 1 ] = ( rows - 0.5f ) / rows;
		tess.texCoords[ tess.numVertexes ][ 2 ] = 0;
		tess.texCoords[ tess.numVertexes ][ 3 ] = 1;
		tess.numVertexes++;

		tess.xyz[ tess.numVertexes ][ 0 ] = x;
		tess.xyz[ tess.numVertexes ][ 1 ] = y + h;
		tess.xyz[ tess.numVertexes ][ 2 ] = 0;
		tess.xyz[ tess.numVertexes ][ 3 ] = 1;
		tess.texCoords[ tess.numVertexes ][ 0 ] = 0.5f / cols;
		tess.texCoords[ tess.numVertexes ][ 1 ] = ( rows - 0.5f ) / rows;
		tess.texCoords[ tess.numVertexes ][ 2 ] = 0;
		tess.texCoords[ tess.numVertexes ][ 3 ] = 1;
		tess.numVertexes++;

		tess.indexes[ tess.numIndexes++ ] = 0;
		tess.indexes[ tess.numIndexes++ ] = 1;
		tess.indexes[ tess.numIndexes++ ] = 2;
		tess.indexes[ tess.numIndexes++ ] = 0;
		tess.indexes[ tess.numIndexes++ ] = 2;
		tess.indexes[ tess.numIndexes++ ] = 3;

		Tess_UpdateVBOs( ATTR_POSITION | ATTR_TEXCOORD );

		Tess_DrawElements();

		tess.numVertexes = 0;
		tess.numIndexes = 0;

#if defined( USE_D3D10 )
		// TODO
#else
		GL_CheckErrors();
#endif
	}
Beispiel #6
0
/*
========================
idImage::SubImageUpload
========================
*/
void idImage::SubImageUpload( int mipLevel, int x, int y, int z, int width, int height, const void * pic, int pixelPitch ) const {
	assert( x >= 0 && y >= 0 && mipLevel >= 0 && width >= 0 && height >= 0 && mipLevel < opts.numLevels );

	int compressedSize = 0;

	if ( IsCompressed() ) {
		assert( !(x&3) && !(y&3) );

		// compressed size may be larger than the dimensions due to padding to quads
		int quadW = ( width + 3 ) & ~3;
		int quadH = ( height + 3 ) & ~3;
		compressedSize = quadW * quadH * BitsForFormat( opts.format ) / 8;

		int padW = ( opts.width + 3 ) & ~3;
		int padH = ( opts.height + 3 ) & ~3;
		(void)padH;
		(void)padW;
		assert( x + width <= padW && y + height <= padH );
		// upload the non-aligned value, OpenGL understands that there
		// will be padding
		if ( x + width > opts.width ) {
			width = opts.width - x;
		}
		if ( y + height > opts.height ) {
			height = opts.height - x;
		}
	} else {
		assert( x + width <= opts.width && y + height <= opts.height );
	}

	int target;
	int uploadTarget;
	if ( opts.textureType == TT_2D ) {
		target = GL_TEXTURE_2D;
		uploadTarget = GL_TEXTURE_2D;
	} else if ( opts.textureType == TT_CUBIC ) {
		target = GL_TEXTURE_CUBE_MAP_EXT;
		uploadTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT + z;
	} else {
		assert( !"invalid opts.textureType" );
		target = GL_TEXTURE_2D;
		uploadTarget = GL_TEXTURE_2D;
	}

	qglBindTexture( target, texnum );

	if ( pixelPitch != 0 ) {
		qglPixelStorei( GL_UNPACK_ROW_LENGTH, pixelPitch );
	}
	if ( opts.format == FMT_RGB565 ) {
		glPixelStorei( GL_UNPACK_SWAP_BYTES, GL_TRUE );
	}
#ifdef DEBUG
	GL_CheckErrors();
#endif
	if ( IsCompressed() ) {
		qglCompressedTexSubImage2DARB( uploadTarget, mipLevel, x, y, width, height, internalFormat, compressedSize, pic );
	} else {

		// make sure the pixel store alignment is correct so that lower mips get created
		// properly for odd shaped textures - this fixes the mip mapping issues with
		// fonts
		int unpackAlignment = width * BitsForFormat( (textureFormat_t)opts.format ) / 8;
		if ( ( unpackAlignment & 3 ) == 0 ) {
			qglPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
		} else {
			qglPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
		}

		qglTexSubImage2D( uploadTarget, mipLevel, x, y, width, height, dataFormat, dataType, pic );
	}
#ifdef DEBUG
	GL_CheckErrors();
#endif
	if ( opts.format == FMT_RGB565 ) {
		glPixelStorei( GL_UNPACK_SWAP_BYTES, GL_FALSE );
	}
	if ( pixelPitch != 0 ) {
		qglPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
	}
}
Beispiel #7
0
/*
 * RE_StretchRaw
 *
 * FIXME: not exactly backend
 * Stretches a raw 32 bit power of 2 bitmap image over the given screen rectangle.
 * Used for cinematics.
 */
void
RE_StretchRaw(int x, int y, int w, int h, int cols, int rows, const byte *data, int client, qbool dirty)
{
	int i, j;
	int start, end;
	shaderProgram_t *sp = &tr.textureColorShader;
	Vec4 color;

	if(!tr.registered){
		return;
	}
	R_SyncRenderThread();

	/* we definately want to sync every frame for the cinematics */
	qglFinish();

	start = 0;
	if(r_speeds->integer){
		start = ri.Milliseconds();
	}

	/* make sure rows and cols are powers of 2 */
	for(i = 0; (1 << i) < cols; i++){
	}
	for(j = 0; (1 << j) < rows; j++){
	}
	if((1 << i) != cols || (1 << j) != rows){
		ri.Error (ERR_DROP, "Draw_StretchRaw: size not a power of 2: %i by %i", cols, rows);
	}

	GL_Bind(tr.scratchImage[client]);

	/* if the scratchImage isn't in the format we want, specify it as a new texture */
	if(cols != tr.scratchImage[client]->width || rows != tr.scratchImage[client]->height){
		tr.scratchImage[client]->width	= tr.scratchImage[client]->uploadWidth = cols;
		tr.scratchImage[client]->height = tr.scratchImage[client]->uploadHeight = rows;
		qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	}else{
		if(dirty){
			/* otherwise, just subimage upload it so that drivers can tell we are going to be changing
			 * it and don't try and do a texture compression */
			qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data);
		}
	}

	if(r_speeds->integer){
		end = ri.Milliseconds();
		ri.Printf(PRINT_ALL, "qglTexSubImage2D %i, %i: %i msec\n", cols, rows, end - start);
	}

	/* FIXME: HUGE hack */
	if(glRefConfig.framebufferObject && !glState.currentFBO){
		if(backEnd.framePostProcessed){
			FBO_Bind(tr.screenScratchFbo);
		}else{
			FBO_Bind(tr.renderFbo);
		}
	}

	RB_SetGL2D();

	tess.numIndexes = 0;
	tess.numVertexes = 0;
	tess.firstIndex = 0;

	tess.xyz[tess.numVertexes][0]	= x;
	tess.xyz[tess.numVertexes][1]	= y;
	tess.xyz[tess.numVertexes][2]	= 0;
	tess.xyz[tess.numVertexes][3]	= 1;
	tess.texCoords[tess.numVertexes][0][0]	= 0.5f / cols;
	tess.texCoords[tess.numVertexes][0][1]	= 0.5f / rows;
	tess.texCoords[tess.numVertexes][0][2]	= 0;
	tess.texCoords[tess.numVertexes][0][3]	= 1;
	tess.numVertexes++;

	tess.xyz[tess.numVertexes][0]	= x + w;
	tess.xyz[tess.numVertexes][1]	= y;
	tess.xyz[tess.numVertexes][2]	= 0;
	tess.xyz[tess.numVertexes][3]	= 1;
	tess.texCoords[tess.numVertexes][0][0]	= (cols - 0.5f) / cols;
	tess.texCoords[tess.numVertexes][0][1]	= 0.5f / rows;
	tess.texCoords[tess.numVertexes][0][2]	= 0;
	tess.texCoords[tess.numVertexes][0][3]	= 1;
	tess.numVertexes++;

	tess.xyz[tess.numVertexes][0]	= x + w;
	tess.xyz[tess.numVertexes][1]	= y + h;
	tess.xyz[tess.numVertexes][2]	= 0;
	tess.xyz[tess.numVertexes][3]	= 1;
	tess.texCoords[tess.numVertexes][0][0]	= (cols - 0.5f) / cols;
	tess.texCoords[tess.numVertexes][0][1]	= (rows - 0.5f) / rows;
	tess.texCoords[tess.numVertexes][0][2]	= 0;
	tess.texCoords[tess.numVertexes][0][3]	= 1;
	tess.numVertexes++;

	tess.xyz[tess.numVertexes][0]	= x;
	tess.xyz[tess.numVertexes][1]	= y + h;
	tess.xyz[tess.numVertexes][2]	= 0;
	tess.xyz[tess.numVertexes][3]	= 1;
	tess.texCoords[tess.numVertexes][0][0]	= 0.5f / cols;
	tess.texCoords[tess.numVertexes][0][1]	= (rows - 0.5f) / rows;
	tess.texCoords[tess.numVertexes][0][2]	= 0;
	tess.texCoords[tess.numVertexes][0][3]	= 1;
	tess.numVertexes++;

	tess.indexes[tess.numIndexes++] = 0;
	tess.indexes[tess.numIndexes++] = 1;
	tess.indexes[tess.numIndexes++] = 2;
	tess.indexes[tess.numIndexes++] = 0;
	tess.indexes[tess.numIndexes++] = 2;
	tess.indexes[tess.numIndexes++] = 3;

	/* FIXME: A lot of this can probably be removed for speed, and refactored into a more convenient function */
	RB_UpdateVBOs(ATTR_POSITION | ATTR_TEXCOORD);

	sp = &tr.textureColorShader;

	GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD);

	GLSL_BindProgram(sp);

	GLSL_SetUniformMatrix16(sp, TEXTURECOLOR_UNIFORM_MODELVIEWPROJECTIONMATRIX,
		glState.modelviewProjection);
	setv34(color, 1, 1, 1, 1);
	GLSL_SetUniformVec4(sp, TEXTURECOLOR_UNIFORM_COLOR, color);

	qglDrawElements(GL_TRIANGLES, tess.numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(0));

	/* R_BindNullVBO();
	 * R_BindNullIBO(); */

	tess.numIndexes = 0;
	tess.numVertexes = 0;
	tess.firstIndex = 0;
}
Beispiel #8
0
/*
====================
UpdateTile

A local tile will only be mapped to globalTile[ localTile + X * TILE_PER_LEVEL ] for some x
====================
*/
void idTextureLevel::UpdateTile( int localX, int localY, int globalX, int globalY ) {
	idTextureTile	*tile = &tileMap[localX][localY];

	if ( tile->x == globalX && tile->y == globalY ) {
		return;
	}
	if ( (globalX & (TILE_PER_LEVEL-1)) != localX || (globalY & (TILE_PER_LEVEL-1)) != localY ) {
		common->Error( "idTextureLevel::UpdateTile: bad coordinate mod" );
	}

	tile->x = globalX;
	tile->y = globalY;

	byte	data[ TILE_SIZE * TILE_SIZE * 4 ];

	if ( globalX >= tilesWide || globalX < 0 || globalY >= tilesHigh || globalY < 0 ) {
		// off the map
		memset( data, 0, sizeof( data ) );
	} else {
		// extract the data from the full image (FIXME: background load from disk)
		int		tileNum = tileOffset + tile->y * tilesWide + tile->x;

		int		tileSize = TILE_SIZE * TILE_SIZE * 4;

		mega->fileHandle->Seek( tileNum * tileSize, FS_SEEK_SET );
		memset( data, 128, sizeof( data ) );
		mega->fileHandle->Read( data, tileSize );
	}

	if ( idMegaTexture::r_showMegaTextureLabels.GetBool() ) {
		// put a color marker in it
		byte	color[4] = { 255 * localX / TILE_PER_LEVEL, 255 * localY / TILE_PER_LEVEL, 0, 0 };
		for ( int x = 0 ; x < 8 ; x++ ) {
			for ( int y = 0 ; y < 8 ; y++ ) {
				*(int *)&data[ ( ( y + TILE_SIZE/2 - 4 ) * TILE_SIZE + x + TILE_SIZE/2 - 4 ) * 4 ] = *(int *)color;
			}
		}
	}

	// upload all the mip-map levels
	int	level = 0;
	int size = TILE_SIZE;
	while ( 1 ) {
		qglTexSubImage2D( GL_TEXTURE_2D, level, localX * size, localY * size, size, size, GL_RGBA, GL_UNSIGNED_BYTE, data );
		size >>= 1;
		level++;

		if ( size == 0 ) {
			break;
		}

		int	byteSize = size * 4;
		// mip-map in place
		for ( int y = 0 ; y < size ; y++ ) {
			byte	*in, *in2, *out;
			in = data + y * size * 16;
			in2 = in + size * 8;
			out = data + y * size * 4;
			for ( int x = 0 ; x < size ; x++ ) {
				out[x*4+0] = ( in[x*8+0] + in[x*8+4+0] + in2[x*8+0] + in2[x*8+4+0] ) >> 2;
				out[x*4+1] = ( in[x*8+1] + in[x*8+4+1] + in2[x*8+1] + in2[x*8+4+1] ) >> 2;
				out[x*4+2] = ( in[x*8+2] + in[x*8+4+2] + in2[x*8+2] + in2[x*8+4+2] ) >> 2;
				out[x*4+3] = ( in[x*8+3] + in[x*8+4+3] + in2[x*8+3] + in2[x*8+4+3] ) >> 2;
			}
		}
	}
}
Beispiel #9
0
/*
=============
RE_StretchRaw

FIXME: not exactly backend
Stretches a raw 32 bit power of 2 bitmap image over the given screen rectangle.
Used for cinematics.
=============
*/
void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty) {
	int			i, j;
	int			start, end;
#ifdef VCMODS_OPENGLES
	vec2_t		texcoords[4];
	vec2_t		verts[4];
	glIndex_t	indicies[6] = {0, 1, 2, 0, 3, 2};
#endif

	if ( !tr.registered ) {
		return;
	}
	R_SyncRenderThread();

	// we definately want to sync every frame for the cinematics
	qglFinish();

	start = end = 0;
	if ( r_speeds->integer ) {
		start = ri.Milliseconds();
	}

	// make sure rows and cols are powers of 2
	for ( i = 0 ; ( 1 << i ) < cols ; i++ ) {
	}
	for ( j = 0 ; ( 1 << j ) < rows ; j++ ) {
	}
	if ( ( 1 << i ) != cols || ( 1 << j ) != rows) {
		ri.Error (ERR_DROP, "Draw_StretchRaw: size not a power of 2: %i by %i", cols, rows);
	}

	GL_Bind( tr.scratchImage[client] );

	// if the scratchImage isn't in the format we want, specify it as a new texture
	if ( cols != tr.scratchImage[client]->width || rows != tr.scratchImage[client]->height ) {
		tr.scratchImage[client]->width = tr.scratchImage[client]->uploadWidth = cols;
		tr.scratchImage[client]->height = tr.scratchImage[client]->uploadHeight = rows;
#ifdef VCMODS_OPENGLES
      //don't do qglTexImage2D as this may end up doing a compressed image
      //on which we are not allowed to do further sub images
		glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
#else
		qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
#endif
		qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
		qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
		qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
		qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
	} else {
		if (dirty) {
			// otherwise, just subimage upload it so that drivers can tell we are going to be changing
			// it and don't try and do a texture compression
			qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data );
		}
	}

	if ( r_speeds->integer ) {
		end = ri.Milliseconds();
		ri.Printf( PRINT_ALL, "qglTexSubImage2D %i, %i: %i msec\n", cols, rows, end - start );
	}

	RB_SetGL2D();

#ifdef VCMODS_OPENGLES
	qglColor4f( tr.identityLight, tr.identityLight, tr.identityLight, 1.0f );

	verts[0][0] = x;  verts[0][1] = y;
	verts[1][0] = x+w;  verts[1][1] = y;
	verts[2][0] = x+w;  verts[2][1] = y+h;
	verts[3][0] = x;  verts[3][1] = y+h;

	texcoords[0][0] = 0.5f/cols;      texcoords[0][1] = 0.5f/rows;
	texcoords[1][0] = (cols-0.5f)/cols;   texcoords[1][1] = 0.5f/rows;
	texcoords[2][0] = (cols-0.5f)/cols;   texcoords[2][1] = (rows-0.5f)/rows;
	texcoords[3][0] = 0.5f/cols;      texcoords[3][1] = (rows-0.5f)/rows;

	qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
	qglTexCoordPointer( 2, GL_FLOAT, 0, texcoords );
	qglVertexPointer  ( 2, GL_FLOAT, 0, verts );
	qglDrawElements( GL_TRIANGLE_STRIP, 6, GL_INDEX_TYPE, indicies );
	qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
#else
	qglColor3f( tr.identityLight, tr.identityLight, tr.identityLight );

	qglBegin (GL_QUADS);
	qglTexCoord2f ( 0.5f / cols,  0.5f / rows );
	qglVertex2f (x, y);
	qglTexCoord2f ( ( cols - 0.5f ) / cols ,  0.5f / rows );
	qglVertex2f (x+w, y);
	qglTexCoord2f ( ( cols - 0.5f ) / cols, ( rows - 0.5f ) / rows );
	qglVertex2f (x+w, y+h);
	qglTexCoord2f ( 0.5f / cols, ( rows - 0.5f ) / rows );
	qglVertex2f (x, y+h);
	qglEnd ();
#endif
}
Beispiel #10
0
/*
=============
RE_StretchRaw

FIXME: not exactly backend
Stretches a raw 32 bit power of 2 bitmap image over the given screen rectangle.
Used for cinematics.
=============
*/
void RE_StretchRaw( int x, int y, int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty ) {
	int i, j;
	int start, end;

	if ( !tr.registered ) {
		return;
	}
	R_IssuePendingRenderCommands();

	if ( tess.numIndexes ) {
		RB_EndSurface();
	}

	// we definately want to sync every frame for the cinematics
	qglFinish();

	start = 0;
	if ( r_speeds->integer ) {
		start = ri.Milliseconds();
	}

	// make sure rows and cols are powers of 2
	for ( i = 0 ; ( 1 << i ) < cols ; i++ ) {
	}
	for ( j = 0 ; ( 1 << j ) < rows ; j++ ) {
	}
	if ( ( 1 << i ) != cols || ( 1 << j ) != rows ) {
		ri.Error( ERR_DROP, "Draw_StretchRaw: size not a power of 2: %i by %i", cols, rows );
	}

	GL_Bind( tr.scratchImage[client] );

	// if the scratchImage isn't in the format we want, specify it as a new texture
	if ( cols != tr.scratchImage[client]->width || rows != tr.scratchImage[client]->height ) {
		tr.scratchImage[client]->width = tr.scratchImage[client]->uploadWidth = cols;
		tr.scratchImage[client]->height = tr.scratchImage[client]->uploadHeight = rows;
#ifdef USE_OPENGLES
		qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
#else
		qglTexImage2D( GL_TEXTURE_2D, 0, 3, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
#endif
		qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
		qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
		qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
		qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
	} else {
		if ( dirty ) {
			// otherwise, just subimage upload it so that drivers can tell we are going to be changing
			// it and don't try and do a texture compression
			qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data );
		}
	}

	if ( r_speeds->integer ) {
		end = ri.Milliseconds();
		ri.Printf( PRINT_ALL, "qglTexSubImage2D %i, %i: %i msec\n", cols, rows, end - start );
	}

	RB_SetGL2D();

	qglColor3f( tr.identityLight, tr.identityLight, tr.identityLight );

#ifdef USE_OPENGLES
	GLfloat tex[] = {
	 0.5f / cols,  0.5f / rows,
	 ( cols - 0.5f ) / cols ,  0.5f / rows,
	 ( cols - 0.5f ) / cols, ( rows - 0.5f ) / rows,
	 0.5f / cols, ( rows - 0.5f ) / rows };
	GLfloat vtx[] = {
	 x, y,
	 x+w, y,
	 x+w, y+h,
	 x, y+h };
	GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
	GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
	if (glcol)
		qglDisableClientState(GL_COLOR_ARRAY);
	if (!text)
		qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
	qglTexCoordPointer( 2, GL_FLOAT, 0, tex );
	qglVertexPointer  ( 2, GL_FLOAT, 0, vtx );
	qglDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
	if (!text)
		qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
	if (glcol)
		qglEnableClientState(GL_COLOR_ARRAY);
#else
	qglBegin( GL_QUADS );
	qglTexCoord2f( 0.5f / cols,  0.5f / rows );
	qglVertex2f( x, y );
	qglTexCoord2f( ( cols - 0.5f ) / cols,  0.5f / rows );
	qglVertex2f( x + w, y );
	qglTexCoord2f( ( cols - 0.5f ) / cols, ( rows - 0.5f ) / rows );
	qglVertex2f( x + w, y + h );
	qglTexCoord2f( 0.5f / cols, ( rows - 0.5f ) / rows );
	qglVertex2f( x, y + h );
	qglEnd();
#endif
}