Exemple #1
0
GLuint CaptureScreenAsTexID(void)
{
  GLuint id;

  gld_EnableTexture2D(GL_TEXTURE0_ARB, true);
 
  qglGenTextures(1, &id);
  qglBindTexture(GL_TEXTURE_2D, id);
  
  qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

#ifdef ANDROID
  qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
#else
  qglTexImage2D(GL_TEXTURE_2D, 0, 3,
#endif
    gld_GetTexDimension(SCREENWIDTH), gld_GetTexDimension(SCREENHEIGHT), 
    0, GL_RGB, GL_UNSIGNED_BYTE, 0);

  qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, SCREENWIDTH, SCREENHEIGHT);

  return id;
}
Exemple #2
0
/*
===============
CreateDSTTex_ARB

Create the texture which warps texture shaders
===============
*/
void CreateDSTTex_ARB (void)
{
	unsigned char	dist[DST_SIZE][DST_SIZE][4];
	int				x,y;

	srand(GetTickCount());
	for (x=0; x<DST_SIZE; x++)
		for (y=0; y<DST_SIZE; y++) {
			dist[x][y][0] = rand()%255;
			dist[x][y][1] = rand()%255;
			dist[x][y][2] = rand()%48;
			dist[x][y][3] = rand()%48;
		}

	qglGenTextures(1,&dst_texture_ARB);
	qglBindTexture(GL_TEXTURE_2D, dst_texture_ARB);
	qglTexImage2D (GL_TEXTURE_2D, 0, 4, DST_SIZE, DST_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, dist);

	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	qglHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
	qglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
}
Exemple #3
0
void gld_BindFlat(GLTexture *gltexture, unsigned int flags)
{
  const unsigned char *flat;
  unsigned char *buffer;
  int w, h;

  if (!gltexture || gltexture->textype != GLDT_FLAT)
  {
    qglBindTexture(GL_TEXTURE_2D, 0);
    last_glTexID = NULL;
    return;
  }

#ifdef HAVE_LIBSDL_IMAGE
  if (gld_LoadHiresTex(gltexture, CR_DEFAULT))
  {
    gld_SetTexClamp(gltexture, flags);
    last_glTexID = gltexture->texid_p;
    return;
  }
#endif

  gld_GetTextureTexID(gltexture, CR_DEFAULT); 

  if (last_glTexID == gltexture->texid_p)
  {
    gld_SetTexClamp(gltexture, flags);
    return;
  }

  last_glTexID = gltexture->texid_p;

  if (*gltexture->texid_p != 0)
  {
    qglBindTexture(GL_TEXTURE_2D, *gltexture->texid_p);
    gld_SetTexClamp(gltexture, flags);
    return;
  }

  flat=W_CacheLumpNum(gltexture->index);
  buffer=(unsigned char*)Z_Malloc(gltexture->buffer_size,PU_STATIC,0);
  if (!(gltexture->flags & GLTEXTURE_MIPMAP) && gl_paletted_texture)
    memset(buffer,transparent_pal_index,gltexture->buffer_size);
  else
    memset(buffer,0,gltexture->buffer_size);
  gld_AddFlatToTexture(gltexture, buffer, flat, !(gltexture->flags & GLTEXTURE_MIPMAP) && gl_paletted_texture);
  if (*gltexture->texid_p == 0)
    qglGenTextures(1, gltexture->texid_p);
  qglBindTexture(GL_TEXTURE_2D, *gltexture->texid_p);

  buffer = gld_HQResize(gltexture, buffer, gltexture->buffer_width, gltexture->buffer_height, &w, &h);

  gld_BuildTexture(gltexture, buffer, false, w, h);

  gld_SetTexClamp(gltexture, flags);

  W_UnlockLumpNum(gltexture->index);
}
Exemple #4
0
void Gui_Init()
{
    Gui_InitBars();
    Gui_InitNotifier();

    qglGenBuffersARB(1, &crosshairBuffer);
    qglGenBuffersARB(1, &backgroundBuffer);
    qglGenBuffersARB(1, &rectBuffer);
    qglGenTextures(1, &load_screen_tex);
    Gui_FillCrosshairBuffer();
    Gui_FillBackgroundBuffer();

    main_inventory_manager = new gui_InventoryManager();
}
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;
}
Exemple #6
0
/*
===============
CreateDSTTex_NV

Create the texture which warps texture shaders
===============
*/
void CreateDSTTex_NV (void)
{
	char	data[DST_SIZE][DST_SIZE][2];
	int		x,y;

	for (x=0; x<DST_SIZE; x++)
		for (y=0; y<DST_SIZE; y++) {
			data[x][y][0]=rand()%255-128;
			data[x][y][1]=rand()%255-128;
		}

	qglGenTextures(1,&dst_texture_NV);
	qglBindTexture(GL_TEXTURE_2D, dst_texture_NV);
	qglTexImage2D(GL_TEXTURE_2D, 0, GL_DSDT8_NV, DST_SIZE, DST_SIZE, 0, GL_DSDT_NV,
				GL_BYTE, data);
	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
Exemple #7
0
/*
========================
idImage::AllocImage

Every image will pass through this function. Allocates all the necessary MipMap levels for the 
Image, but doesn't put anything in them.

This should not be done during normal game-play, if you can avoid it.
========================
*/
void idImage::AllocImage() {
	GL_CheckErrors();
	PurgeImage();

	switch ( opts.format ) {
	case FMT_RGBA8:
		internalFormat = GL_RGBA8;
		dataFormat = GL_RGBA;
		dataType = GL_UNSIGNED_BYTE;
		break;
	case FMT_XRGB8:
		internalFormat = GL_RGB;
		dataFormat = GL_RGBA;
		dataType = GL_UNSIGNED_BYTE;
		break;
	case FMT_RGB565:
		internalFormat = GL_RGB;
		dataFormat = GL_RGB;
		dataType = GL_UNSIGNED_SHORT_5_6_5;
		break;
	case FMT_ALPHA:
#if defined( USE_CORE_PROFILE )
		internalFormat = GL_R8;
		dataFormat = GL_RED;
#else
		internalFormat = GL_ALPHA8;
		dataFormat = GL_ALPHA;
#endif
		dataType = GL_UNSIGNED_BYTE;
		break;
	case FMT_L8A8:
#if defined( USE_CORE_PROFILE )
		internalFormat = GL_RG8;
		dataFormat = GL_RG;
#else
		internalFormat = GL_LUMINANCE8_ALPHA8;
		dataFormat = GL_LUMINANCE_ALPHA;
#endif
		dataType = GL_UNSIGNED_BYTE;
		break;
	case FMT_LUM8:
#if defined( USE_CORE_PROFILE )
		internalFormat = GL_R8;
		dataFormat = GL_RED;
#else
		internalFormat = GL_LUMINANCE8;
		dataFormat = GL_LUMINANCE;
#endif
		dataType = GL_UNSIGNED_BYTE;
		break;
	case FMT_INT8:
#if defined( USE_CORE_PROFILE )
		internalFormat = GL_R8;
		dataFormat = GL_RED;
#else
		internalFormat = GL_INTENSITY8;
		dataFormat = GL_LUMINANCE;
#endif
		dataType = GL_UNSIGNED_BYTE;
		break;
	case FMT_DXT1:
		internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
		dataFormat = GL_RGBA;
		dataType = GL_UNSIGNED_BYTE;
		break;
	case FMT_DXT5:
		internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
		dataFormat = GL_RGBA;
		dataType = GL_UNSIGNED_BYTE;
		break;
	case FMT_DEPTH:
		internalFormat = GL_DEPTH_COMPONENT;
		dataFormat = GL_DEPTH_COMPONENT;
		dataType = GL_UNSIGNED_BYTE;
		break;
	case FMT_X16:
		internalFormat = GL_INTENSITY16;
		dataFormat = GL_LUMINANCE;
		dataType = GL_UNSIGNED_SHORT;
		break;
	case FMT_Y16_X16:
		internalFormat = GL_LUMINANCE16_ALPHA16;
		dataFormat = GL_LUMINANCE_ALPHA;
		dataType = GL_UNSIGNED_SHORT;
		break;
	default:
		idLib::Error( "Unhandled image format %d in %s\n", opts.format, GetName() );
	}

	// if we don't have a rendering context, just return after we
	// have filled in the parms.  We must have the values set, or
	// an image match from a shader before OpenGL starts would miss
	// the generated texture
	if ( !R_IsInitialized() ) {
		return;
	}

	// generate the texture number
	qglGenTextures( 1, (GLuint *)&texnum );
	assert( texnum != TEXTURE_NOT_LOADED );

	//----------------------------------------------------
	// allocate all the mip levels with NULL data
	//----------------------------------------------------

	int numSides;
	int target;
	int uploadTarget;
	if ( opts.textureType == TT_2D ) {
		target = uploadTarget = GL_TEXTURE_2D;
		numSides = 1;
	} else if ( opts.textureType == TT_CUBIC ) {
		target = GL_TEXTURE_CUBE_MAP_EXT;
		uploadTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT;
		numSides = 6;
	} else {
		assert( !"opts.textureType" );
		target = uploadTarget = GL_TEXTURE_2D;
		numSides = 1;
	}

	qglBindTexture( target, texnum );

	for ( int side = 0; side < numSides; side++ ) {
		int w = opts.width;
		int h = opts.height;
		if ( opts.textureType == TT_CUBIC ) {
			h = w;
		}
		for ( int level = 0; level < opts.numLevels; level++ ) {

			// clear out any previous error
			GL_CheckErrors();

			if ( IsCompressed() ) {
				int compressedSize = ( ((w+3)/4) * ((h+3)/4) * int64( 16 ) * BitsForFormat( opts.format ) ) / 8;

				// Even though the OpenGL specification allows the 'data' pointer to be NULL, for some
				// drivers we actually need to upload data to get it to allocate the texture.
				// However, on 32-bit systems we may fail to allocate a large block of memory for large
				// textures. We handle this case by using HeapAlloc directly and allowing the allocation
				// to fail in which case we simply pass down NULL to glCompressedTexImage2D and hope for the best.
				// As of 2011-10-6 using NVIDIA hardware and drivers we have to allocate the memory with HeapAlloc
				// with the exact size otherwise large image allocation (for instance for physical page textures)
				// may fail on Vista 32-bit.
				void * data = HeapAlloc( GetProcessHeap(), 0, compressedSize );
				qglCompressedTexImage2DARB( uploadTarget+side, level, internalFormat, w, h, 0, compressedSize, data );
				if ( data != NULL ) {
					HeapFree( GetProcessHeap(), 0, data );
				}
			} else {
				qglTexImage2D( uploadTarget + side, level, internalFormat, w, h, 0, dataFormat, dataType, NULL );
			}

			GL_CheckErrors();

			w = Max( 1, w >> 1 );
			h = Max( 1, h >> 1 );
		}
	}

	qglTexParameteri( target, GL_TEXTURE_MAX_LEVEL, opts.numLevels - 1 );

	// see if we messed anything up
	GL_CheckErrors();

	SetTexParameters();

	GL_CheckErrors();
}
Exemple #8
0
void gld_BindTexture(GLTexture *gltexture, unsigned int flags)
{
  const rpatch_t *patch;
  unsigned char *buffer;
  int w, h;

  if (!gltexture || gltexture->textype != GLDT_TEXTURE)
  {
    qglBindTexture(GL_TEXTURE_2D, 0);
    last_glTexID = NULL;
    return;
  }

#ifdef HAVE_LIBSDL_IMAGE
  if (gld_LoadHiresTex(gltexture, CR_DEFAULT))
  {
    gld_SetTexClamp(gltexture, flags);
    last_glTexID = gltexture->texid_p;
    return;
  }
#endif

  gld_GetTextureTexID(gltexture, CR_DEFAULT);

  if (last_glTexID == gltexture->texid_p)
  {
    gld_SetTexClamp(gltexture, flags);
    return;
  }

  last_glTexID = gltexture->texid_p;

  if (*gltexture->texid_p != 0)
  {
    qglBindTexture(GL_TEXTURE_2D, *gltexture->texid_p);
    gld_SetTexClamp(gltexture, flags);
    return;
  }

  buffer=(unsigned char*)Z_Malloc(gltexture->buffer_size,PU_STATIC,0);
  if (!(gltexture->flags & GLTEXTURE_MIPMAP) && gl_paletted_texture)
    memset(buffer,transparent_pal_index,gltexture->buffer_size);
  else
    memset(buffer,0,gltexture->buffer_size);
  patch=R_CacheTextureCompositePatchNum(gltexture->index);
  gld_AddPatchToTexture(gltexture, buffer, patch, 0, 0,
                        CR_DEFAULT, !(gltexture->flags & GLTEXTURE_MIPMAP) && gl_paletted_texture);
  R_UnlockTextureCompositePatchNum(gltexture->index);
  if (*gltexture->texid_p == 0)
    qglGenTextures(1, gltexture->texid_p);
  qglBindTexture(GL_TEXTURE_2D, *gltexture->texid_p);
  
  if (gltexture->flags & GLTEXTURE_HASHOLES)
  {
    SmoothEdges(buffer, gltexture->buffer_width, gltexture->buffer_height);
  }

  buffer = gld_HQResize(gltexture, buffer, gltexture->buffer_width, gltexture->buffer_height, &w, &h);

  gld_BuildTexture(gltexture, buffer, false, w, h);

  gld_SetTexClamp(gltexture, flags);
}
Exemple #9
0
void gld_BindPatch(GLTexture *gltexture, int cm)
{
  const rpatch_t *patch;
  unsigned char *buffer;
  int w, h;

  if (!gltexture || gltexture->textype != GLDT_PATCH)
  {
    qglBindTexture(GL_TEXTURE_2D, 0);
    last_glTexID = NULL;
    return;
  }

#ifdef HAVE_LIBSDL_IMAGE
  if (gld_LoadHiresTex(gltexture, cm))
  {
    gld_SetTexClamp(gltexture, GLTEXTURE_CLAMPXY);
    last_glTexID = gltexture->texid_p;
    return;
  }
#endif

  gld_GetTextureTexID(gltexture, cm);

  if (last_glTexID == gltexture->texid_p)
  {
    gld_SetTexClamp(gltexture, GLTEXTURE_CLAMPXY);
    return;
  }

  last_glTexID = gltexture->texid_p;

  if (*gltexture->texid_p != 0)
  {
    qglBindTexture(GL_TEXTURE_2D, *gltexture->texid_p);
    gld_SetTexClamp(gltexture, GLTEXTURE_CLAMPXY);
    return;
  }

  patch=R_CachePatchNum(gltexture->index);
  buffer=(unsigned char*)Z_Malloc(gltexture->buffer_size,PU_STATIC,0);
  if (gl_paletted_texture)
    memset(buffer,transparent_pal_index,gltexture->buffer_size);
  else
    memset(buffer,0,gltexture->buffer_size);
  gld_AddPatchToTexture(gltexture, buffer, patch, 0, 0, cm, gl_paletted_texture);

  // e6y
  // Post-process the texture data after the buffer has been created.
  // Smooth the edges of transparent fields in the texture.
  //
  // It is a workaround to set the color of all transparent pixels
  // that border on a non-transparent pixel to the color
  // of one bordering non-transparent pixel.
  // It is necessary for textures that are not power of two
  // to avoid the lines (boxes) around the elements that change
  // on the intermission screens in Doom1 (E2, E3)
  
//  if ((gltexture->flags & (GLTEXTURE_HASHOLES | GLTEXTURE_SPRITE)) ==
//    (GLTEXTURE_HASHOLES | GLTEXTURE_SPRITE))
  if ((gltexture->flags & GLTEXTURE_HASHOLES))
  {
    SmoothEdges(buffer, gltexture->buffer_width, gltexture->buffer_height);
  }

  if (*gltexture->texid_p == 0)
    qglGenTextures(1, gltexture->texid_p);
  qglBindTexture(GL_TEXTURE_2D, *gltexture->texid_p);

  buffer = gld_HQResize(gltexture, buffer, gltexture->buffer_width, gltexture->buffer_height, &w, &h);

  gld_BuildTexture(gltexture, buffer, false, w, h);

  gld_SetTexClamp(gltexture, GLTEXTURE_CLAMPXY);

  R_UnlockPatchNum(gltexture->index);
}
Exemple #10
0
/*
* RB_AllocTextureNum
*/
void RB_AllocTextureNum( image_t *tex )
{
	qglGenTextures( 1, &tex->texnum );
}
Exemple #11
0
// will free all GL binded qtextures and shaders
// NOTE: doesn't make much sense out of Radiant exit or called during a reload
void WINAPI QERApp_FreeShaders()
{
	int i;
	brush_t	*b;

	// store the shader names used by the patches
	for(i=0; i<PatchShaders.GetSize(); i++)
		delete PatchShaders.GetAt(i);
	PatchShaders.RemoveAll();
	for (b=active_brushes.next ; b != NULL && b != &active_brushes ; b=b->next)
  {
    if (b->patchBrush)
			PushPatch(b->pPatch);
  }
	for (b=selected_brushes.next ; b != NULL && b != &selected_brushes ; b=b->next)
  {
    if (b->patchBrush)
			PushPatch(b->pPatch);
  }

	// reload shaders
	// empty the actives shaders list
	g_ActiveShaders.ReleaseAll();
	g_Shaders.ReleaseAll();
	// empty the main g_qeglobals.d_qtextures list
	// FIXME: when we reload later on, we need to have the shader names
	// for brushes it's stored in the texdef
	// but patches don't have texdef
	// see bug 104655 for details
	// so the solution, build an array of patchMesh_t* and their shader names
#ifdef _DEBUG
	Sys_Printf("FIXME: bug 104655 workaround\n");
#endif

	// NOTE: maybe before we'd like to set all qtexture_t in the shaders list to notex?
	// NOTE: maybe there are some qtexture_t we don't want to erase? For plain color faces maybe?
	// NOTE: the GL textures are freed later on
  if (g_qeglobals.d_qtextures)
  {
	  qtexture_t* pTex = g_qeglobals.d_qtextures->next;
    while (pTex != NULL && pTex != g_qeglobals.d_qtextures)
    {
      qtexture_t* pNextTex = pTex->next;
  	  if (g_qeglobals.bSurfacePropertiesPlugin)
	    {
		    // Timo
		    // Surface properties plugin
#ifdef _DEBUG
  		  if ( !pTex->pData )
	  		  Sys_Printf("WARNING: found a qtexture_t* with no IPluginQTexture\n");
#endif
  		  if ( pTex->pData )
	  		  GETPLUGINTEXDEF(pTex)->DecRef();
  	  }
	    free(pTex);
      pTex = pNextTex;
    }
  }
	// free GL bindings
  GLuint* pGln = new GLuint[texture_extension_number-1];
  qglGenTextures(texture_extension_number-1, pGln);
  QE_CheckOpenGLForErrors();
  qglDeleteTextures(texture_extension_number-1, pGln);
  QE_CheckOpenGLForErrors();
  delete []pGln;
  texture_extension_number = 1;
	g_qeglobals.d_qtextures = NULL;
  // free the map
  g_qeglobals.d_qtexmap->RemoveAll();
}
Exemple #12
0
void glf_resize(gl_tex_font_p glf, uint16_t font_size)
{
    if((glf != NULL) && (glf->ft_face != NULL))
    {
        const GLint padding = 2;
        GLubyte *buffer;
        GLint chars_in_row, chars_in_column;
        size_t buffer_size;
        int x, y, xx, yy;
        int i, ii, i0 = 0;

        // clear old atlas, if exists
        if(glf->gl_tex_indexes != NULL)
        {
            if(glf->gl_tex_indexes_count > 0)
            {
                qglDeleteTextures(glf->gl_tex_indexes_count, glf->gl_tex_indexes);
            }
            free(glf->gl_tex_indexes);
        }
        glf->gl_tex_indexes = NULL;
        glf->gl_real_tex_indexes_count = 0;

        // resize base font
        glf->font_size = font_size;
        FT_Set_Char_Size(glf->ft_face, font_size << 6, font_size << 6, 0, 0);

        // calculate texture atlas size
        chars_in_row = 1 + sqrt(glf->glyphs_count);
        glf->gl_tex_width = (font_size + padding) * chars_in_row;
        glf->gl_tex_width = NextPowerOf2(glf->gl_tex_width);
        if(glf->gl_tex_width > glf->gl_max_tex_width)
        {
            glf->gl_tex_width = glf->gl_max_tex_width;
        }

        // create new atlas
        chars_in_row = glf->gl_tex_width / (font_size + padding);
        chars_in_column = glf->glyphs_count / chars_in_row + 1;
        glf->gl_tex_indexes_count = (chars_in_column * (font_size + padding)) / glf->gl_tex_width + 1;
        glf->gl_tex_indexes = (GLuint*)malloc(glf->gl_tex_indexes_count * sizeof(GLuint));
        qglGenTextures(glf->gl_tex_indexes_count, glf->gl_tex_indexes);

        buffer_size = glf->gl_tex_width * glf->gl_tex_width * sizeof(GLubyte);
        buffer = (GLubyte*)malloc(buffer_size);
        memset(buffer, 0x00, buffer_size);

        for(i = 0, x = 0, y = 0; i < glf->glyphs_count; i++)
        {
            FT_GlyphSlot g;
            glf->glyphs[i].tex_index = 0;

            /* load glyph image into the slot (erase previous one) */
            if(FT_Load_Glyph(glf->ft_face, i, FT_LOAD_RENDER))
            {
                continue;
            }
            /* convert to an anti-aliased bitmap */
            if(FT_Render_Glyph(((FT_Face)glf->ft_face)->glyph, FT_RENDER_MODE_NORMAL))
            {
                continue;
            }

            g = ((FT_Face)glf->ft_face)->glyph;
            glf->glyphs[i].width = g->bitmap.width;
            glf->glyphs[i].height = g->bitmap.rows;
            glf->glyphs[i].advance_x_pt = g->advance.x;
            glf->glyphs[i].advance_y_pt = g->advance.y;
            glf->glyphs[i].left = g->bitmap_left;
            glf->glyphs[i].top = g->bitmap_top;

            if((g->bitmap.width == 0) || (g->bitmap.rows == 0))
            {
                continue;
            }

            if(x + g->bitmap.width > glf->gl_tex_width)
            {
                x = 0;
                y += glf->font_size + padding;
                if(y + glf->font_size > glf->gl_tex_width)
                {
                    int ii;
                    qglBindTexture(GL_TEXTURE_2D, glf->gl_tex_indexes[glf->gl_real_tex_indexes_count]);
                    qglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
                    qglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
                    qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
                    qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
                    qglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, glf->gl_tex_width, glf->gl_tex_width, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer);
                    for(ii = i0; ii < i; ii++)
                    {
                        glf->glyphs[ii].tex_x0 /= (GLfloat)glf->gl_tex_width;
                        glf->glyphs[ii].tex_x1 /= (GLfloat)glf->gl_tex_width;
                        glf->glyphs[ii].tex_y0 /= (GLfloat)glf->gl_tex_width;
                        glf->glyphs[ii].tex_y1 /= (GLfloat)glf->gl_tex_width;
                    }
                    memset(buffer, 0x00, buffer_size);
                    y = 0;
                    i0 = i;
                    glf->gl_real_tex_indexes_count++;
                }
            }

            glf->glyphs[i].tex_x0 = (GLfloat)x;
            glf->glyphs[i].tex_y0 = (GLfloat)y;
            glf->glyphs[i].tex_x1 = (GLfloat)(x + g->bitmap.width);
            glf->glyphs[i].tex_y1 = (GLfloat)(y + g->bitmap.rows);

            glf->glyphs[i].tex_index = glf->gl_tex_indexes[glf->gl_real_tex_indexes_count];
            for(xx = 0; xx < g->bitmap.width; xx++)
            {
                for(yy = 0; yy < g->bitmap.rows; yy++)
                {
                    buffer[(y+yy)*glf->gl_tex_width + (x+xx)] = g->bitmap.buffer[yy * g->bitmap.width + xx];
                }
            }

            x += (g->bitmap.width + padding);
        }

        qglBindTexture(GL_TEXTURE_2D, glf->gl_tex_indexes[glf->gl_real_tex_indexes_count]);
        qglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
        qglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        chars_in_column = NextPowerOf2(y + font_size + padding);
        qglTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, glf->gl_tex_width, chars_in_column, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer);
        for(ii = i0; ii < glf->glyphs_count; ii++)
        {
            glf->glyphs[ii].tex_x0 /= (GLfloat)glf->gl_tex_width;
            glf->glyphs[ii].tex_x1 /= (GLfloat)glf->gl_tex_width;
            glf->glyphs[ii].tex_y0 /= (GLfloat)chars_in_column;
            glf->glyphs[ii].tex_y1 /= (GLfloat)chars_in_column;
        }
        free(buffer);
        glf->gl_real_tex_indexes_count++;
    }
}
void bordered_texture_atlas::createTextures(GLuint *textureNames)
{
    GLubyte *data = (GLubyte *) malloc(4 * result_page_width * result_page_width);

    qglGenTextures((GLsizei) number_result_pages, textureNames);

    textures_indexes = textureNames;

    for (unsigned long page = 0; page < number_result_pages; page++)
    {
        for (unsigned long texture = 0; texture < number_canonical_object_textures; texture++)
        {
            const canonical_object_texture &canonical = canonical_object_textures[texture];
            if (canonical.new_page != page)
                continue;

            if(canonical.original_page == WHITE_TEXTURE_INDEX)
            {
                uint32_t white_pixels[1] = {0xFFFFFFFFU};
                // Add top border
                for (int border = 0; border < border_width; border++)
                {
                    unsigned x = canonical.new_x_with_border;
                    unsigned y = canonical.new_y_with_border + border;

                    // expand top-left pixel
                    memset_pattern4(&data[(y*result_page_width + x) * 4],
                           white_pixels, 4 * border_width);
                    // copy top line
                    memset_pattern4(&data[(y*result_page_width + x + border_width) * 4],
                           white_pixels, canonical.width * 4);
                    // expand top-right pixel
                    memset_pattern4(&data[(y*result_page_width + x + border_width + canonical.width) * 4],
                           white_pixels, 4 * border_width);
                }

                // Copy main content
                for (int line = 0; line < canonical.height; line++)
                {
                    unsigned x = canonical.new_x_with_border;
                    unsigned y = canonical.new_y_with_border + border_width + line;

                    // expand left pixel
                    memset_pattern4(&data[(y*result_page_width + x) * 4],
                           white_pixels, 4 * border_width);
                    // copy line
                    memset_pattern4(&data[(y*result_page_width + x + border_width) * 4],
                           white_pixels, canonical.width * 4);
                    // expand right pixel
                    memset_pattern4(&data[(y*result_page_width + x + border_width + canonical.width) * 4],
                           white_pixels, 4 * border_width);
                }

                // Add bottom border
                for (int border = 0; border < border_width; border++)
                {
                    unsigned x = canonical.new_x_with_border;
                    unsigned y = canonical.new_y_with_border + canonical.height + border_width + border;

                    // expand bottom-left pixel
                    memset_pattern4(&data[(y*result_page_width + x) * 4],
                           white_pixels, 4 * border_width);
                    // copy bottom line
                    memset_pattern4(&data[(y*result_page_width + x + border_width) * 4],
                           white_pixels, canonical.width * 4);
                    // expand bottom-right pixel
                    memset_pattern4(&data[(y*result_page_width + x + border_width + canonical.width) * 4],
                           white_pixels, 4 * border_width);
                }
            }
            else
            {
                const char *original = (char *) original_pages[canonical.original_page].pixels;
                // Add top border
                for (int border = 0; border < border_width; border++)
                {
                    unsigned x = canonical.new_x_with_border;
                    unsigned y = canonical.new_y_with_border + border;
                    unsigned old_x = canonical.original_x;
                    unsigned old_y = canonical.original_y;

                    // expand top-left pixel
                    memset_pattern4(&data[(y*result_page_width + x) * 4],
                           &(original[(old_y * 256 + old_x) * 4]),
                           4 * border_width);
                    // copy top line
                    memcpy(&data[(y*result_page_width + x + border_width) * 4],
                           &original[(old_y * 256 + old_x) * 4],
                           canonical.width * 4);
                    // expand top-right pixel
                    memset_pattern4(&data[(y*result_page_width + x + border_width + canonical.width) * 4],
                           &(original[(old_y * 256 + old_x + canonical.width) * 4]),
                           4 * border_width);
                }

                // Copy main content
                for (int line = 0; line < canonical.height; line++)
                {
                    unsigned x = canonical.new_x_with_border;
                    unsigned y = canonical.new_y_with_border + border_width + line;
                    unsigned old_x = canonical.original_x;
                    unsigned old_y = canonical.original_y + line;

                    // expand left pixel
                    memset_pattern4(&data[(y*result_page_width + x) * 4],
                           &(original[(old_y * 256 + old_x) * 4]),
                           4 * border_width);
                    // copy line
                    memcpy(&data[(y*result_page_width + x + border_width) * 4],
                           &original[(old_y * 256 + old_x) * 4],
                           canonical.width * 4);
                    // expand right pixel
                    memset_pattern4(&data[(y*result_page_width + x + border_width + canonical.width) * 4],
                           &(original[(old_y * 256 + old_x + canonical.width) * 4]),
                           4 * border_width);
                }

                // Add bottom border
                for (int border = 0; border < border_width; border++)
                {
                    unsigned x = canonical.new_x_with_border;
                    unsigned y = canonical.new_y_with_border + canonical.height + border_width + border;
                    unsigned old_x = canonical.original_x;
                    unsigned old_y = canonical.original_y + canonical.height;

                    // expand bottom-left pixel
                    memset_pattern4(&data[(y*result_page_width + x) * 4],
                           &(original[(old_y * 256 + old_x) * 4]),
                           4 * border_width);
                    // copy bottom line
                    memcpy(&data[(y*result_page_width + x + border_width) * 4],
                           &original[(old_y * 256 + old_x) * 4],
                           canonical.width * 4);
                    // expand bottom-right pixel
                    memset_pattern4(&data[(y*result_page_width + x + border_width + canonical.width) * 4],
                           &(original[(old_y * 256 + old_x + canonical.width) * 4]),
                           4 * border_width);
                }
            }
        }

        qglBindTexture(GL_TEXTURE_2D, textureNames[page]);
        qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)result_page_width, (GLsizei) result_page_height[page], 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
        if(qglGenerateMipmap != NULL)
        {
            qglGenerateMipmap(GL_TEXTURE_2D);
        }
        else
        {
            int mip_level = 1;
            int w = result_page_width / 2;
            int h = result_page_height[page] / 2;
            GLubyte *mip_data = (GLubyte *) malloc(4 * w * h);

            assert(w > 0 && h > 0);
            for(int i = 0; i < h; i++)
            {
                for(int j = 0; j < w; j++)
                {
                    mip_data[i * w * 4 + j * 4 + 0] = 0.25 * ((int)data[i * w * 16 + j * 8 + 0] + (int)data[i * w * 16 + j * 8 + 4 + 0] + (int)data[i * w * 16 + w * 8 + j * 8 + 0] + (int)data[i * w * 16 + w * 8 + j * 8 + 4 + 0]);
                    mip_data[i * w * 4 + j * 4 + 1] = 0.25 * ((int)data[i * w * 16 + j * 8 + 1] + (int)data[i * w * 16 + j * 8 + 4 + 1] + (int)data[i * w * 16 + w * 8 + j * 8 + 1] + (int)data[i * w * 16 + w * 8 + j * 8 + 4 + 1]);
                    mip_data[i * w * 4 + j * 4 + 2] = 0.25 * ((int)data[i * w * 16 + j * 8 + 2] + (int)data[i * w * 16 + j * 8 + 4 + 2] + (int)data[i * w * 16 + w * 8 + j * 8 + 2] + (int)data[i * w * 16 + w * 8 + j * 8 + 4 + 2]);
                    mip_data[i * w * 4 + j * 4 + 3] = 0.25 * ((int)data[i * w * 16 + j * 8 + 3] + (int)data[i * w * 16 + j * 8 + 4 + 3] + (int)data[i * w * 16 + w * 8 + j * 8 + 3] + (int)data[i * w * 16 + w * 8 + j * 8 + 4 + 3]);
                }
            }

            //char tgan[128];
            //WriteTGAfile("mip_00.tga", data, result_page_width, result_page_height[page], 0);
            //sprintf(tgan, "mip_%0.2d.tga", mip_level);
            //WriteTGAfile(tgan, mip_data, w, h, 0);
            qglTexImage2D(GL_TEXTURE_2D, mip_level, GL_RGBA, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip_data);

            while((w > 1) && (h > 1) /*&& (mip_level < 4)*/)
            {
                mip_level++;
                w /= 2; w = (w==0)?1:w;
                h /= 2; h = (h==0)?1:h;
                for(int i = 0; i < h; i++)
                {
                    for(int j = 0; j < w; j++)
                    {
                        mip_data[i * w * 4 + j * 4 + 0] = 0.25 * ((int)mip_data[i * w * 16 + j * 8 + 0] + (int)mip_data[i * w * 16 + j * 8 + 4 + 0] + (int)mip_data[i * w * 16 + w * 8 + j * 8 + 0] + (int)mip_data[i * w * 16 + w * 8 + j * 8 + 4 + 0]);
                        mip_data[i * w * 4 + j * 4 + 1] = 0.25 * ((int)mip_data[i * w * 16 + j * 8 + 1] + (int)mip_data[i * w * 16 + j * 8 + 4 + 1] + (int)mip_data[i * w * 16 + w * 8 + j * 8 + 1] + (int)mip_data[i * w * 16 + w * 8 + j * 8 + 4 + 1]);
                        mip_data[i * w * 4 + j * 4 + 2] = 0.25 * ((int)mip_data[i * w * 16 + j * 8 + 2] + (int)mip_data[i * w * 16 + j * 8 + 4 + 2] + (int)mip_data[i * w * 16 + w * 8 + j * 8 + 2] + (int)mip_data[i * w * 16 + w * 8 + j * 8 + 4 + 2]);
                        mip_data[i * w * 4 + j * 4 + 3] = 0.25 * ((int)mip_data[i * w * 16 + j * 8 + 3] + (int)mip_data[i * w * 16 + j * 8 + 4 + 3] + (int)mip_data[i * w * 16 + w * 8 + j * 8 + 3] + (int)mip_data[i * w * 16 + w * 8 + j * 8 + 4 + 3]);
                    }
                }
                //sprintf(tgan, "mip_%0.2d.tga", mip_level);
                //WriteTGAfile(tgan, mip_data, w, h, 0);
                qglTexImage2D(GL_TEXTURE_2D, mip_level, GL_RGBA, (GLsizei)w, (GLsizei)h, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip_data);
            }
            free(mip_data);
        }
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    }

    free(data);
}
Exemple #14
0
void InitGlslShadersAndPrograms( void ) {
	void *shaderSource;
	GLenum target;
	float bloomTextureScale;
	int ret;

	if ( !r_enablePostProcess->integer || !glsl ) {
		return;
	}

	GL_SelectTexture(0);
	qglDisable( GL_TEXTURE_2D );
	qglEnable( GL_TEXTURE_RECTANGLE_ARB );

	bloomTextureScale = r_BloomTextureScale->value;
	if ( bloomTextureScale < 0.01 ) {
		bloomTextureScale = 0.01;
	} else if ( bloomTextureScale > 1 ) {
		bloomTextureScale = 1;
	}
	target = GL_TEXTURE_RECTANGLE_ARB;
	tr.bloomWidth = glConfig.vidWidth * bloomTextureScale;
	tr.bloomHeight = glConfig.vidHeight * bloomTextureScale;
	qglGenTextures(1, &tr.bloomTexture);
	qglBindTexture(target, tr.bloomTexture);
	qglTexImage2D(target, 0, GL_RGBA8, tr.bloomWidth, tr.bloomHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
	qglTexParameteri(target, GL_TEXTURE_WRAP_S, r_glClampToEdge->integer ? GL_CLAMP_TO_EDGE : GL_CLAMP);
	qglTexParameteri(target, GL_TEXTURE_WRAP_T, r_glClampToEdge->integer ? GL_CLAMP_TO_EDGE : GL_CLAMP);
	qglTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	qglTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	target = GL_TEXTURE_RECTANGLE_ARB;
	qglGenTextures(1, &tr.backBufferTexture);
	qglBindTexture(target, tr.backBufferTexture);

	qglTexImage2D(target, 0, GL_RGB8, glConfig.vidWidth, glConfig.vidHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
	qglTexParameteri(target, GL_TEXTURE_WRAP_S, r_glClampToEdge->integer ? GL_CLAMP_TO_EDGE : GL_CLAMP);
	qglTexParameteri(target, GL_TEXTURE_WRAP_T, r_glClampToEdge->integer ? GL_CLAMP_TO_EDGE : GL_CLAMP);
	qglTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	qglTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	qglDisable(GL_TEXTURE_RECTANGLE_ARB);
	qglEnable(GL_TEXTURE_2D);

	GL_SelectTexture(0);

	Com_VPrintf("^5scripts/posteffect.vs ->\n");
	ret = ri.FS_ReadFile("scripts/posteffect.vs", &shaderSource);

	if (ret > 0) {
		tr.mainVs = qglCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
		qglShaderSourceARB(tr.mainVs, 1, (const char **)&shaderSource, NULL);
		qglCompileShaderARB(tr.mainVs);
		printGlslLog(tr.mainVs);
		ri.FS_FreeFile(shaderSource);
	} else if ( strlen(fallbackShader_posteffect) ) {
		Com_VPrintf("^1file not found, using fallback shader\n");
		//ri.FS_FreeFile(shaderSource);
		tr.mainVs = qglCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
		qglShaderSourceARB(tr.mainVs, 1, &fallbackShader_posteffect, NULL);
		qglCompileShaderARB(tr.mainVs);
		printGlslLog(tr.mainVs);
	} else {
		Com_VPrintf("^1file not found\n");
		glsl = qfalse;
		R_DeleteGlslShadersAndPrograms();
	}

	R_InitFragmentShader( "scripts/colorcorrect.fs", &tr.colorCorrectFs, &tr.colorCorrectSp, tr.mainVs, fallbackShader_colorcorrect );
	R_InitFragmentShader( "scripts/blurhoriz.fs", &tr.blurHorizFs, &tr.blurHorizSp, tr.mainVs, fallbackShader_blurhoriz );
	R_InitFragmentShader( "scripts/blurvertical.fs", &tr.blurVerticalFs, &tr.blurVerticalSp, tr.mainVs, fallbackShader_blurvertical );
	R_InitFragmentShader( "scripts/brightpass.fs", &tr.brightPassFs, &tr.brightPassSp, tr.mainVs, fallbackShader_brightpass );
	R_InitFragmentShader( "scripts/combine.fs", &tr.combineFs, &tr.combineSp, tr.mainVs, fallbackShader_combine );
	R_InitFragmentShader( "scripts/downsample1.fs", &tr.downSample1Fs, &tr.downSample1Sp, tr.mainVs, fallbackShader_downsample1 );
}
Exemple #15
0
/*********
SP_DrawTexture
*********/
void SP_DrawTexture(void* pixels, float width, float height, float vShift)
{
	if (!pixels)
	{
		// Ug.  We were not even able to load the error message texture.
		return;
	}
	
	// Create a texture from the buffered file
	GLuint texid;
	qglGenTextures(1, &texid);
	qglBindTexture(GL_TEXTURE_2D, texid);
	qglTexImage2D(GL_TEXTURE_2D, 0, GL_DDS1_EXT, width, height, 0, GL_DDS1_EXT, GL_UNSIGNED_BYTE, pixels);

	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 );

	// Reset every GL state we've got.  Who knows what state
	// the renderer could be in when this function gets called.
	qglColor3f(1.f, 1.f, 1.f);
	qglViewport(0, 0, 640, 480);

	GLboolean alpha = qglIsEnabled(GL_ALPHA_TEST);
	qglDisable(GL_ALPHA_TEST);

	GLboolean blend = qglIsEnabled(GL_BLEND);
	qglDisable(GL_BLEND);

	GLboolean cull = qglIsEnabled(GL_CULL_FACE);
	qglDisable(GL_CULL_FACE);

	GLboolean depth = qglIsEnabled(GL_DEPTH_TEST);
	qglDisable(GL_DEPTH_TEST);

	GLboolean fog = qglIsEnabled(GL_FOG);
	qglDisable(GL_FOG);

	GLboolean lighting = qglIsEnabled(GL_LIGHTING);
	qglDisable(GL_LIGHTING);

	GLboolean offset = qglIsEnabled(GL_POLYGON_OFFSET_FILL);
	qglDisable(GL_POLYGON_OFFSET_FILL);

	GLboolean scissor = qglIsEnabled(GL_SCISSOR_TEST);
	qglDisable(GL_SCISSOR_TEST);

	GLboolean stencil = qglIsEnabled(GL_STENCIL_TEST);
	qglDisable(GL_STENCIL_TEST);

	GLboolean texture = qglIsEnabled(GL_TEXTURE_2D);
	qglEnable(GL_TEXTURE_2D);

	qglMatrixMode(GL_MODELVIEW);
	qglLoadIdentity();
	qglMatrixMode(GL_PROJECTION);
	qglLoadIdentity();
	qglOrtho(0, 640, 0, 480, 0, 1);
	
	qglMatrixMode(GL_TEXTURE0);
	qglLoadIdentity();
	qglMatrixMode(GL_TEXTURE1);
	qglLoadIdentity();

	qglActiveTextureARB(GL_TEXTURE0_ARB);
	qglClientActiveTextureARB(GL_TEXTURE0_ARB);

	memset(&tess, 0, sizeof(tess));

	// Draw the error message
	qglBeginFrame();

	if (!SP_LicenseDone)
	{
		// clear the screen if we haven't done the
		// license yet...
		qglClearColor(0, 0, 0, 1);
		qglClear(GL_COLOR_BUFFER_BIT);
	}

	float x1 = 320 - width / 2;
	float x2 = 320 + width / 2;
	float y1 = 240 - height / 2;
	float y2 = 240 + height / 2;

	y1 += vShift;
	y2 += vShift;

	qglBeginEXT (GL_TRIANGLE_STRIP, 4, 0, 0, 4, 0);
		qglTexCoord2f( 0,  0 );
		qglVertex2f(x1, y1);
		qglTexCoord2f( 1 ,  0 );
		qglVertex2f(x2, y1);
		qglTexCoord2f( 0, 1 );
		qglVertex2f(x1, y2);
		qglTexCoord2f( 1, 1 );
		qglVertex2f(x2, y2);
	qglEnd();
	
	qglEndFrame();
	qglFlush();

	// Restore (most) of the render states we reset
	if (alpha) qglEnable(GL_ALPHA_TEST);
	else qglDisable(GL_ALPHA_TEST);

	if (blend) qglEnable(GL_BLEND);
	else qglDisable(GL_BLEND);

	if (cull) qglEnable(GL_CULL_FACE);
	else qglDisable(GL_CULL_FACE);

	if (depth) qglEnable(GL_DEPTH_TEST);
	else qglDisable(GL_DEPTH_TEST);

	if (fog) qglEnable(GL_FOG);
	else qglDisable(GL_FOG);

	if (lighting) qglEnable(GL_LIGHTING);
	else qglDisable(GL_LIGHTING);

	if (offset) qglEnable(GL_POLYGON_OFFSET_FILL);
	else qglDisable(GL_POLYGON_OFFSET_FILL);

	if (scissor) qglEnable(GL_SCISSOR_TEST);
	else qglDisable(GL_SCISSOR_TEST);

	if (stencil) qglEnable(GL_STENCIL_TEST);
	else qglDisable(GL_STENCIL_TEST);

	if (texture) qglEnable(GL_TEXTURE_2D);
	else qglDisable(GL_TEXTURE_2D);

	// Kill the texture
	qglDeleteTextures(1, &texid);
}