Example #1
0
bool Gui_SetScreenTexture(void *data, int w, int h, int bpp)
{
    GLenum       texture_format;
    GLuint       color_depth;

    if(bpp == 32)        // Contains an alpha channel
    {
        texture_format = GL_RGBA;
        color_depth = GL_RGBA;
    }
    else if(bpp == 24)   // No alpha channel
    {
        texture_format = GL_RGB;
        color_depth = GL_RGB;
    }
    else
    {
        return false;
    }

    // Bind the texture object
    qglBindTexture(GL_TEXTURE_2D, load_screen_tex);

    // Set the texture's stretching properties
    qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    // Edit the texture object's image data using the information SDL_Surface gives us
    qglTexImage2D(GL_TEXTURE_2D, 0, color_depth, w, h, 0,
                 texture_format, GL_UNSIGNED_BYTE, data);
    qglBindTexture(GL_TEXTURE_2D, 0);

    return true;
}
Example #2
0
void RE_UploadCinematic (int w2, int h2, 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, 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 );	

		qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
		qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_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 );
		qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
		qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
	} 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 );
		}
	}
}
Example #3
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;
}
Example #4
0
/*
** GL_SetDefaultState
*/
void GL_SetDefaultState( void )
{
	qglClearColor (1.0f, 0.0f, 0.5f, 0.5f);
	qglCullFace(GL_FRONT);
	qglEnable(GL_TEXTURE_2D);

	qglEnable(GL_ALPHA_TEST);
	qglAlphaFunc(GL_GREATER, 0.666f);

	qglDisable (GL_DEPTH_TEST);
	qglDisable (GL_CULL_FACE);
	qglDisable (GL_BLEND);

	qglColor4fv(colorWhite);

	qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
	qglShadeModel (GL_FLAT);

	GL_TextureMode( gl_texturemode->string );
	GL_TextureAlphaMode( gl_texturealphamode->string );
	GL_TextureSolidMode( gl_texturesolidmode->string );

	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);

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

	qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	GL_TexEnv( GL_REPLACE );

	if ( qglPointParameterfEXT && FLOAT_NE_ZERO(gl_ext_pointparameters->value))
	{
		float attenuations[3];

		attenuations[0] = gl_particle_att_a->value;
		attenuations[1] = gl_particle_att_b->value;
		attenuations[2] = gl_particle_att_c->value;

		qglEnable( GL_POINT_SMOOTH );
		qglPointParameterfEXT( GL_POINT_SIZE_MIN_EXT, gl_particle_min_size->value );
		qglPointParameterfEXT( GL_POINT_SIZE_MAX_EXT, gl_particle_max_size->value );
		qglPointParameterfvEXT( GL_DISTANCE_ATTENUATION_EXT, attenuations );
	}

	gl_swapinterval->modified = true;
	GL_UpdateSwapInterval();
}
Example #5
0
/**
 * @brief RB_RenderToTexture
 * @param[in] data
 * @return
 */
const void *RB_RenderToTexture(const void *data)
{
	const renderToTextureCommand_t *cmd = ( const renderToTextureCommand_t * ) data;

	//ri.Printf( PRINT_ALL, "RB_RenderToTexture\n" );

	GL_Bind(cmd->image);
	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR);
	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_LINEAR);
	qglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
	qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, cmd->x, cmd->y, cmd->w, cmd->h, 0);
	//qglCopyTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cmd->x, cmd->y, cmd->w, cmd->h );

	return ( const void * ) (cmd + 1);
}
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;
}
Example #7
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);
}
static inline void drawCharTex(GLTexture_t * tex, SDL_Rect * src, SDL_Rect * dest, 
	Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
	GLint cropRect[4];
	/*
	GLfloat texColor[4];
	static const float onediv255 = 1.0f / 255.0f;
	*/
	if( !dest->h || !dest->w )
		return;

	qglBindTexture(GL_TEXTURE_2D, tex->id);

	qglColor4x(r * 0x100, g * 0x100, b * 0x100,  200 * 0x100 );

	//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);

	qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	qglEnable(GL_BLEND);
	qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	#if 0
	dest->x = dest->x*320/screen_width;
	dest->y = dest->y*200/screen_height;
	dest->w = dest->w*320/screen_width;
	dest->h = dest->h*200/screen_height;
	DrawQuad(dest->x, 200 - dest->y - dest->h, dest->w, dest->h, 
		0, 0, 1/*tex->w*/, 1/*tex->h*/);
#endif


	cropRect[0] = 0;
	cropRect[1] = tex->h;
	cropRect[2] = tex->w;
	cropRect[3] = -tex->h;
	if(src)
	{//left down width hight
		cropRect[0] = src->x;
		cropRect[1] = src->h; // TODO: check if height works as expected in inverted GL coords
		cropRect[2] = src->w;
		cropRect[3] = -src->h; // TODO: check if height works as expected in inverted GL coords
	}
	qglTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
	glDrawTexiOES(dest->x, screen_height - dest->y - dest->h, 0, dest->w, dest->h);
}
Example #9
0
void gld_SetTexClamp(GLTexture *gltexture, unsigned int flags)
{
  //if ((gltexture->flags & GLTEXTURE_CLAMPXY) != (flags & GLTEXTURE_CLAMPXY))
  /* sp1n0za 05/2010: simplify */
  if ((*gltexture->texflags_p ^ flags) & GLTEXTURE_CLAMPXY)
  {
    int need_clamp_x = (flags & GLTEXTURE_CLAMPX);
    int need_clamp_y = (flags & GLTEXTURE_CLAMPY);
    int has_clamp_x = (*gltexture->texflags_p & GLTEXTURE_CLAMPX);
    int has_clamp_y = (*gltexture->texflags_p & GLTEXTURE_CLAMPY);

    if (need_clamp_x)
    {
      if (!has_clamp_x)
      {
        *gltexture->texflags_p |= GLTEXTURE_CLAMPX;
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GLEXT_CLAMP_TO_EDGE);
      }
    }
    else
    {
      if (has_clamp_x)
      {
        *gltexture->texflags_p &= ~GLTEXTURE_CLAMPX;
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
      }
    }

    if (need_clamp_y)
    {
      if (!has_clamp_y)
      {
        *gltexture->texflags_p |= GLTEXTURE_CLAMPY;
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GLEXT_CLAMP_TO_EDGE);
      }
    }
    else
    {
      if (has_clamp_y)
      {
        *gltexture->texflags_p &= ~GLTEXTURE_CLAMPY;
        qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
      }
    }
  }
}
Example #10
0
/*
=============
Draw_StretchPic
=============
*/
void Draw_StretchPic (int x, int y, int w, int h, char *pic)
{
	image_t *gl;
	GLint previousMagFilter;

	gl = Draw_FindPic (pic);
	if (!gl)
	{
		ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", pic);
		return;
	}

	if (scrap_dirty)
		Scrap_Upload ();

	if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( gl_config.renderer & GL_RENDERER_RENDITION ) ) && !gl->has_alpha)
		qglDisable (GL_ALPHA_TEST);

	GL_Bind (gl->texnum);

	qglGetTexParameteriv( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &previousMagFilter );
	qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );

	qglBegin (GL_QUADS);
	{
		qglTexCoord2f (gl->sl, gl->tl);
		qglVertex2f (x, y);
		qglTexCoord2f (gl->sh, gl->tl);
		qglVertex2f (x+w, y);
		qglTexCoord2f (gl->sh, gl->th);
		qglVertex2f (x+w, y+h);
		qglTexCoord2f (gl->sl, gl->th);
		qglVertex2f (x, y+h);
	}
	qglEnd ();

	qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, previousMagFilter );

	if ( ( ( gl_config.renderer == GL_RENDERER_MCD ) || ( gl_config.renderer & GL_RENDERER_RENDITION ) ) && !gl->has_alpha)
		qglEnable (GL_ALPHA_TEST);
}
Example #11
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);
}
Example #12
0
void gld_SetTexFilters(GLTexture *gltexture)
{
  int mip, mag_filter, min_filter;
  float aniso_filter = 0.0f;

  switch (gltexture->textype)
  {
  case GLDT_TEXTURE:
  case GLDT_FLAT:
    mip = MIP_TEXTURE;
    break;
  case GLDT_PATCH:
    mip = ((gltexture->flags & GLTEXTURE_SPRITE) ? MIP_SPRITE : MIP_PATCH);
    break;
  default:
    mip = MIP_TEXTURE;
    break;
  }

  if (render_usedetail && gltexture->detail)
    mag_filter = GL_LINEAR;
  else
    mag_filter = tex_filter[mip].mag_filter;

  if ((gltexture->flags & GLTEXTURE_MIPMAP) && tex_filter[mip].mipmap)
  {
    min_filter = tex_filter[mip].min_filter;
    if (gl_ext_texture_filter_anisotropic)
      aniso_filter = (GLfloat)(1<<gl_texture_filter_anisotropic);
  }
  else
  {
    min_filter =  tex_filter[mip].mag_filter;
  }

  qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
  qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
  if (aniso_filter > 0.0f)
    qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso_filter);
}
Example #13
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 );
}
Example #14
0
int gld_BuildTexture(GLTexture *gltexture, void *data, dboolean readonly, int width, int height)
{
  int result = false;

  int tex_width, tex_height, tex_buffer_size;
  unsigned char *tex_buffer = NULL;

  tex_width  = gld_GetTexDimension(width);
  tex_height = gld_GetTexDimension(height);
  tex_buffer_size = tex_width * tex_height * 4;

  //your video is modern
  if (gl_arb_texture_non_power_of_two)
  {
    qglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP,
      ((gltexture->flags & GLTEXTURE_MIPMAP) ? GL_TRUE : GL_FALSE));

    qglTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format,
      tex_width, tex_height,
      0, GL_RGBA, GL_UNSIGNED_BYTE, data);

    gld_RecolorMipLevels(data);

    gld_SetTexFilters(gltexture);

    result = true;
    goto l_exit;
  }

#ifdef USE_GLU_MIPMAP
  if (gltexture->flags & GLTEXTURE_MIPMAP)
  {
    gluBuild2DMipmaps(GL_TEXTURE_2D, gl_tex_format,
      width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);

    gld_RecolorMipLevels(data);

    gld_SetTexFilters(gltexture);

    result = true;
    goto l_exit;
  }
  else
#endif // USE_GLU_MIPMAP
  {
#ifdef USE_GLU_IMAGESCALE
    if ((width != tex_width) || (height != tex_height))
    {
      tex_buffer = malloc(tex_buffer_size);
      if (!tex_buffer)
      {
        goto l_exit;
      }

      gluScaleImage(GL_RGBA, width, height,
        GL_UNSIGNED_BYTE, data,
        tex_width, tex_height,
        GL_UNSIGNED_BYTE, tex_buffer);

      qglTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format,
        tex_width, tex_height,
        0, GL_RGBA, GL_UNSIGNED_BYTE, tex_buffer);
    }
    else
#endif // USE_GLU_IMAGESCALE
    {
      if ((width != tex_width) || (height != tex_height))
      {
        if (width == tex_width)
        {
          tex_buffer = malloc(tex_buffer_size);
          memcpy(tex_buffer, data, width * height * 4);
        }
        else
        {
          int y;
          tex_buffer = calloc(1, tex_buffer_size);
          for (y = 0; y < height; y++)          
          {
            memcpy(tex_buffer + y * tex_width * 4,
              ((unsigned char*)data) + y * width * 4, width * 4);
          }
        }
      }
      else
      {
        tex_buffer = data;
      }

      if (gl_paletted_texture) {
        gld_SetTexturePalette(GL_TEXTURE_2D);
        qglTexImage2D( GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT,
          tex_width, tex_height,
          0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, tex_buffer);
      } else {
        qglTexImage2D( GL_TEXTURE_2D, 0, gl_tex_format,
          tex_width, tex_height,
          0, GL_RGBA, GL_UNSIGNED_BYTE, tex_buffer);
      }
    }

    gltexture->flags &= ~GLTEXTURE_MIPMAP;
    gld_SetTexFilters(gltexture);
    result = true;
  }

l_exit:
  if (result)
  {
    qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  }

  if (tex_buffer && tex_buffer != data)
  {
    free(tex_buffer);
    tex_buffer = NULL;
  }

  if (!readonly)
  {
    free(data);
    data = NULL;
  }

  return result;
}
Example #15
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++;
    }
}
Example #16
0
/*
* R_RenderMeshGLSL_Shadowmap
*/
static void R_RenderMeshGLSL_Shadowmap( r_glslfeat_t programFeatures )
{
	int i;
	int state;
	int scissor[4], old_scissor[4];
	int program, object;
	vec3_t tdir, lightDir;
	shaderpass_t *pass = r_back.accumPasses[0];

	if( r_shadows_pcf->integer )
		programFeatures |= GLSL_SHADOWMAP_APPLY_PCF;
	if( r_shadows_dither->integer )
		programFeatures |= GLSL_SHADOWMAP_APPLY_DITHER;

	// update uniforms
	program = R_RegisterGLSLProgram( pass->program_type, pass->program, NULL, NULL, NULL, 0, programFeatures );
	object = R_GetProgramObject( program );
	if( !object )
		return;

	Vector4Copy( ri.scissor, old_scissor );

	for( i = 0, r_back.currentCastGroup = r_shadowGroups; i < r_numShadowGroups; i++, r_back.currentCastGroup++ )
	{
		if( !( r_back.currentShadowBits & r_back.currentCastGroup->bit ) )
			continue;

		// project the bounding box on to screen then use scissor test
		// so that fragment shader isn't run for unshadowed regions
		if( !R_ScissorForBounds( r_back.currentCastGroup->visCorners, 
			&scissor[0], &scissor[1], &scissor[2], &scissor[3] ) )
			continue;

		GL_Scissor( ri.refdef.x + scissor[0], ri.refdef.y + scissor[1], scissor[2], scissor[3] );

		R_BindShaderpass( pass, r_back.currentCastGroup->depthTexture, 0, NULL );

		GL_TexEnv( GL_MODULATE );

		qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB );
		qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL );

		// calculate the fragment color
		R_ModifyColor( pass, qfalse, qfalse );

		// set shaderpass state (blending, depthwrite, etc)
		state = r_back.currentShaderState | ( pass->flags & r_back.currentShaderPassMask ) | GLSTATE_BLEND_MTEX;
		GL_SetState( state );

		qglUseProgramObjectARB( object );

		VectorCopy( r_back.currentCastGroup->direction, tdir );
		Matrix_TransformVector( ri.currententity->axis, tdir, lightDir );

		R_UpdateProgramUniforms( program, ri.viewOrigin, vec3_origin, lightDir,
			r_back.currentCastGroup->lightAmbient, NULL, NULL, qtrue,
			r_back.currentCastGroup->depthTexture->upload_width, r_back.currentCastGroup->depthTexture->upload_height,
			r_back.currentCastGroup->projDist,
			0, 0, 
			colorArrayCopy[0], r_back.overBrightBits, r_back.currentShaderTime, r_back.entityColor );

		R_FlushArrays();

		qglUseProgramObjectARB( 0 );

		qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE );
	}

	GL_Scissor( old_scissor[0], old_scissor[1], old_scissor[2], old_scissor[3] );
}
Example #17
0
/*
========================
idImage::SetTexParameters
========================
*/
void idImage::SetTexParameters() {
	int target = GL_TEXTURE_2D;
	switch ( opts.textureType ) {
		case TT_2D:
			target = GL_TEXTURE_2D;
			break;
		case TT_CUBIC:
			target = GL_TEXTURE_CUBE_MAP_EXT;
			break;
		default:
			idLib::FatalError( "%s: bad texture type %d", GetName(), opts.textureType );
			return;
	}

	// ALPHA, LUMINANCE, LUMINANCE_ALPHA, and INTENSITY have been removed
	// in OpenGL 3.2. In order to mimic those modes, we use the swizzle operators
#if defined( USE_CORE_PROFILE )
	if ( opts.colorFormat == CFM_GREEN_ALPHA ) {
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_R, GL_ONE );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_G, GL_ONE );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_B, GL_ONE );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_A, GL_GREEN );
	} else if ( opts.format == FMT_LUM8 ) {
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_R, GL_RED );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_G, GL_RED );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_B, GL_RED );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_A, GL_ONE );
	} else if ( opts.format == FMT_L8A8 ) {
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_R, GL_RED );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_G, GL_RED );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_B, GL_RED );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_A, GL_GREEN );
	} else if ( opts.format == FMT_ALPHA ) {
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_R, GL_ONE );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_G, GL_ONE );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_B, GL_ONE );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_A, GL_RED );
	} else if ( opts.format == FMT_INT8 ) {
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_R, GL_RED );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_G, GL_RED );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_B, GL_RED );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_A, GL_RED );
	} else {
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_R, GL_RED );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_G, GL_GREEN );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_B, GL_BLUE );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_A, GL_ALPHA );
	}
#else
	if ( opts.colorFormat == CFM_GREEN_ALPHA ) {
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_R, GL_ONE );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_G, GL_ONE );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_B, GL_ONE );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_A, GL_GREEN );
	} else if ( opts.format == FMT_ALPHA ) {
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_R, GL_ONE );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_G, GL_ONE );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_B, GL_ONE );
		qglTexParameteri( target, GL_TEXTURE_SWIZZLE_A, GL_RED );
	}
#endif

	switch( filter ) {
		case TF_DEFAULT:
			if ( r_useTrilinearFiltering.GetBool() ) {
				qglTexParameterf( target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
			} else {
				qglTexParameterf( target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
			}
			qglTexParameterf( target, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
			break;
		case TF_LINEAR:
			qglTexParameterf( target, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
			qglTexParameterf( target, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
			break;
		case TF_NEAREST:
			qglTexParameterf( target, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
			qglTexParameterf( target, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
			break;
		default:
			common->FatalError( "%s: bad texture filter %d", GetName(), filter );
	}

	if ( glConfig.anisotropicFilterAvailable ) {
		// only do aniso filtering on mip mapped images
		if ( filter == TF_DEFAULT ) {
			int aniso = r_maxAnisotropicFiltering.GetInteger();
			if ( aniso > glConfig.maxTextureAnisotropy ) {
				aniso = glConfig.maxTextureAnisotropy;
			}
			if ( aniso < 0 ) {
				aniso = 0;
			}
			qglTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniso );
		} else {
			qglTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1 );
		}
	}
	if ( glConfig.textureLODBiasAvailable && ( usage != TD_FONT ) ) {
		// use a blurring LOD bias in combination with high anisotropy to fix our aliasing grate textures...
		qglTexParameterf(target, GL_TEXTURE_LOD_BIAS_EXT, r_lodBias.GetFloat() );
	}

	// set the wrap/clamp modes
	switch( repeat ) {
		case TR_REPEAT:
			qglTexParameterf( target, GL_TEXTURE_WRAP_S, GL_REPEAT );
			qglTexParameterf( target, GL_TEXTURE_WRAP_T, GL_REPEAT );
			break;
		case TR_CLAMP_TO_ZERO: {
			float color[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
			qglTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, color );
			qglTexParameterf( target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER );
			qglTexParameterf( target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER );
			}
			break;
		case TR_CLAMP_TO_ZERO_ALPHA: {
			float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
			qglTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, color );
			qglTexParameterf( target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER );
			qglTexParameterf( target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER );
			}
			break;
		case TR_CLAMP:
			qglTexParameterf( target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
			qglTexParameterf( target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
			break;
		default:
			common->FatalError( "%s: bad texture repeat %d", GetName(), repeat );
	}
}
Example #18
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();
}
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);
}
Example #20
0
GLvoid APIENTRY GLDSA_TextureParameteri(GLuint texture, GLenum target, GLenum pname, GLint param)
{
	GL_BindMultiTexture(glDsaState.texunit, target, texture);
	qglTexParameteri(target, pname, param);
}
Example #21
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;
		qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
		qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
	
		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_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
	} 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 );
	}

	if ( !backEnd.projection2D ) {
		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 ();
}