2019-10-20 06:07:12 +00:00
/*
* * gl_texture . cpp
* * high level GL texture interface
* *
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* * Copyright 2019 Christoph Oelckers
* * All rights reserved .
* *
* * Redistribution and use in source and binary forms , with or without
* * modification , are permitted provided that the following conditions
* * are met :
* *
* * 1. Redistributions of source code must retain the above copyright
* * notice , this list of conditions and the following disclaimer .
* * 2. Redistributions in binary form must reproduce the above copyright
* * notice , this list of conditions and the following disclaimer in the
* * documentation and / or other materials provided with the distribution .
* * 3. The name of the author may not be used to endorse or promote products
* * derived from this software without specific prior written permission .
* *
* * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* * IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* * INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* * NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* * DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* * THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* * ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* * THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
* * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* *
* *
*/
2019-10-20 06:02:45 +00:00
# include "palette.h"
2013-05-15 02:17:17 +00:00
# include "build.h"
# include "hightile.h"
# include "polymost.h"
2019-10-10 21:29:13 +00:00
# include "textures.h"
# include "bitmap.h"
2019-11-05 22:35:38 +00:00
# include "v_font.h"
2020-05-23 12:40:54 +00:00
# include "palettecontainer.h"
2019-10-10 21:29:13 +00:00
# include "../../glbackend/glbackend.h"
2020-05-27 20:54:20 +00:00
# include "texturemanager.h"
2020-05-29 13:55:08 +00:00
# include "v_video.h"
2019-03-01 08:51:50 +00:00
2019-10-23 19:11:37 +00:00
// Test CVARs.
2020-01-25 18:10:05 +00:00
CVAR ( Int , fixpalette , - 1 , 0 )
CVAR ( Int , fixpalswap , - 1 , 0 )
2019-10-17 22:20:27 +00:00
2019-10-18 09:37:07 +00:00
//===========================================================================
//
// Retrieve the texture to be used.
//
//===========================================================================
2020-05-29 13:55:08 +00:00
OpenGLRenderer : : FHardwareTexture * GLInstance : : LoadTexture ( FTexture * tex , int textype , int palid )
2019-10-18 09:37:07 +00:00
{
if ( textype = = TT_INDEXED ) palid = - 1 ;
2020-05-29 13:55:08 +00:00
auto phwtex = tex - > SystemTextures . GetHardwareTexture ( palid , false ) ;
2020-05-28 23:03:01 +00:00
if ( phwtex ) return ( OpenGLRenderer : : FHardwareTexture * ) phwtex ;
2019-10-18 09:37:07 +00:00
2020-05-29 13:55:08 +00:00
auto hwtex = static_cast < OpenGLRenderer : : FHardwareTexture * > ( screen - > CreateHardwareTexture ( textype = = TT_INDEXED ? 1 : 4 ) ) ;
if ( hwtex ) tex - > SystemTextures . AddHardwareTexture ( palid , false , hwtex ) ;
2019-10-18 09:37:07 +00:00
return hwtex ;
2019-10-17 22:20:27 +00:00
}
2019-10-17 19:44:34 +00:00
2019-10-17 22:20:27 +00:00
//===========================================================================
//
2019-10-18 12:04:32 +00:00
// Sets a texture for rendering. This should be the ONLY place to bind in-game textures
2019-10-17 22:20:27 +00:00
//
//===========================================================================
2019-10-17 19:44:34 +00:00
2020-05-23 12:40:54 +00:00
struct TexturePick
{
2020-05-25 21:59:07 +00:00
FGameTexture * texture ; // which texture to use
2020-05-23 12:40:54 +00:00
int translation ; // which translation table to use
int tintFlags ; // which shader tinting options to use
PalEntry tintColor ; // Tint color
PalEntry basepalTint ; // can the base palette be done with a global tint effect?
} ;
2020-05-24 06:47:45 +00:00
#if 0
2020-05-23 12:40:54 +00:00
TexturePick PickTexture ( int tilenum , int basepal , int palette )
{
TexturePick pick = { nullptr , 0 , - 1 , 0xffffff , 0xffffff } ;
int usepalette = fixpalette > = 0 ? fixpalette : basepal ;
int usepalswap = fixpalswap > = 0 ? fixpalswap : palette ;
auto & h = hictinting [ palette ] ;
auto tex = TileFiles . tiles [ tilenum ] ;
2020-05-24 06:47:45 +00:00
auto rep = ( hw_hightile & & ! ( h . f & HICTINT_ALWAYSUSEART ) ) ? TileFiles . FindReplacement ( tilenum , usepalswap ) : nullptr ;
2020-05-23 12:40:54 +00:00
// Canvas textures must be treated like hightile replacements in the following code.
2020-05-25 21:59:07 +00:00
bool truecolor = rep | | tex - > GetUseType ( ) = = FGameTexture : : Canvas ;
2020-05-23 12:40:54 +00:00
bool applytint = false ;
if ( truecolor )
{
if ( usepalette ! = 0 )
{
// This is a global setting for the entire scene, so let's do it here, right at the start. (Fixme: Store this in a static table instead of reusing the same entry for all palettes.)
auto & hh = hictinting [ MAXPALOOKUPS - 1 ] ;
// This sets a tinting color for global palettes, e.g. water or slime - only used for hires replacements (also an option for low-resource hardware where duplicating the textures may be problematic.)
pick . basepalTint = hh . tint ;
}
if ( rep )
{
tex = rep - > faces [ 0 ] ;
}
if ( ! rep | | rep - > palnum ! = palette | | ( h . f & HICTINT_APPLYOVERALTPAL ) ) applytint = true ;
}
else
{
// Tinting is not used on indexed textures, unless explicitly requested
if ( h . f & ( HICTINT_ALWAYSUSEART | HICTINT_USEONART ) )
{
applytint = true ;
if ( ! ( h . f & HICTINT_APPLYOVERPALSWAP ) ) usepalswap = 0 ;
}
pick . translation = TRANSLATION ( usepalette + 1 , usepalswap ) ;
}
pick . texture = tex ;
if ( applytint & & h . f )
{
pick . tintFlags = h . f ;
pick . tintColor = h . tint ;
}
return pick ;
}
2020-05-24 06:47:45 +00:00
# endif
2020-05-23 12:40:54 +00:00
2020-05-29 14:46:36 +00:00
bool GLInstance : : SetTextureInternal ( int picnum , FGameTexture * tex , int paletteid , int method , int sampleroverride , FGameTexture * det , float detscale , FGameTexture * glow )
2019-10-17 22:20:27 +00:00
{
2020-05-29 13:55:08 +00:00
if ( ! tex - > isValid ( ) | | tex - > GetTexelWidth ( ) < = 0 | | tex - > GetTexelHeight ( ) < = 0 ) return false ;
2020-05-29 14:46:36 +00:00
int curbasepal = GetTranslationType ( paletteid ) - Translation_Remap ;
int palette = GetTranslationIndex ( paletteid ) ;
2020-01-25 18:10:05 +00:00
int usepalette = fixpalette > = 0 ? fixpalette : curbasepal ;
int usepalswap = fixpalswap > = 0 ? fixpalswap : palette ;
2019-10-17 22:20:27 +00:00
GLInterface . SetPalette ( usepalette ) ;
GLInterface . SetPalswap ( usepalswap ) ;
2019-12-30 19:44:37 +00:00
bool texbound [ 3 ] = { } ;
2020-01-18 21:41:08 +00:00
int MatrixChange = 0 ;
2019-10-17 19:44:34 +00:00
2020-02-04 19:40:10 +00:00
TextureType = hw_int_useindexedcolortextures ? TT_INDEXED : TT_TRUECOLOR ;
2019-10-17 19:44:34 +00:00
2019-10-17 22:20:27 +00:00
int lookuppal = 0 ;
2020-05-29 13:55:08 +00:00
int bindflags = 0 ;
2019-10-17 22:20:27 +00:00
VSMatrix texmat ;
2019-10-17 19:44:34 +00:00
2020-02-11 19:55:47 +00:00
GLInterface . SetBasepalTint ( 0xffffff ) ;
2020-01-11 21:18:06 +00:00
auto & h = hictinting [ palette ] ;
bool applytint = false ;
2020-03-29 12:01:46 +00:00
// Canvas textures must be treated like hightile replacements in the following code.
2020-05-24 08:30:09 +00:00
if ( picnum < 0 ) picnum = TileFiles . GetTileIndex ( tex ) ; // Allow getting replacements also when the texture is not passed by its tile number.
2020-05-24 06:47:45 +00:00
auto rep = ( picnum > = 0 & & hw_hightile & & ! ( h . f & HICTINT_ALWAYSUSEART ) ) ? TileFiles . FindReplacement ( picnum , palette ) : nullptr ;
2020-05-25 21:59:07 +00:00
if ( rep | | tex - > GetTexture ( ) - > isHardwareCanvas ( ) )
2019-10-17 22:20:27 +00:00
{
2020-02-11 19:55:47 +00:00
if ( usepalette ! = 0 )
{
// This is a global setting for the entire scene, so let's do it here, right at the start. (Fixme: Store this in a static table instead of reusing the same entry for all palettes.)
auto & hh = hictinting [ MAXPALOOKUPS - 1 ] ;
// This sets a tinting color for global palettes, e.g. water or slime - only used for hires replacements (also an option for low-resource hardware where duplicating the textures may be problematic.)
GLInterface . SetBasepalTint ( hh . tint ) ;
}
2020-03-29 12:01:46 +00:00
if ( rep )
{
tex = rep - > faces [ 0 ] ;
}
if ( ! rep | | rep - > palnum ! = palette | | ( h . f & HICTINT_APPLYOVERALTPAL ) ) applytint = true ;
2019-10-17 22:20:27 +00:00
TextureType = TT_HICREPLACE ;
2020-05-29 13:55:08 +00:00
bindflags = CTF_Upscale ;
2019-10-17 22:20:27 +00:00
}
else
{
// Only look up the palette if we really want to use it (i.e. when creating a true color texture of an ART tile.)
2019-11-10 18:42:26 +00:00
if ( TextureType = = TT_TRUECOLOR )
{
2020-01-11 21:18:06 +00:00
// Tinting is not used on indexed textures
if ( h . f & ( HICTINT_ALWAYSUSEART | HICTINT_USEONART ) )
{
applytint = true ;
if ( ! ( h . f & HICTINT_APPLYOVERPALSWAP ) ) usepalswap = 0 ;
}
2020-05-24 22:08:59 +00:00
lookuppal = TRANSLATION ( usepalette + Translation_Remap , usepalswap ) ;
2020-05-29 13:55:08 +00:00
bindflags = CTF_Upscale ;
2019-11-10 18:42:26 +00:00
}
2020-05-29 13:55:08 +00:00
else bindflags = CTF_Indexed ;
2019-10-17 22:20:27 +00:00
}
2019-10-17 19:44:34 +00:00
2020-01-11 21:18:06 +00:00
// This is intentionally the same value for both parameters. The shader does not use the same uniform for modulation and overlay colors.
2020-02-05 19:02:50 +00:00
if ( applytint & & h . f )
GLInterface . SetTinting ( h . f , h . tint , h . tint ) ;
2020-01-11 21:18:06 +00:00
else GLInterface . SetTinting ( - 1 , 0xffffff , 0xffffff ) ;
2019-10-17 22:20:27 +00:00
// Load the main texture
2020-05-29 13:55:08 +00:00
auto mtex = LoadTexture ( tex - > GetTexture ( ) , TextureType , lookuppal ) ;
2019-10-17 22:20:27 +00:00
if ( mtex )
{
2019-10-19 18:25:58 +00:00
auto sampler = ( method & DAMETH_CLAMPED ) ? ( sampleroverride ! = - 1 ? sampleroverride : SamplerClampXY ) : SamplerRepeat ;
2019-10-19 22:31:27 +00:00
if ( TextureType = = TT_INDEXED )
{
sampler = sampler + SamplerNoFilterRepeat - SamplerRepeat ;
}
2020-05-28 21:48:50 +00:00
else if ( tex - > isHardwareCanvas ( ) )
{
sampler = CLAMP_CAMTEX ;
}
2019-12-30 19:44:37 +00:00
UseDetailMapping ( false ) ;
UseGlowMapping ( false ) ;
2019-11-10 18:42:26 +00:00
UseBrightmaps ( false ) ;
2019-10-17 19:44:34 +00:00
2020-05-29 13:55:08 +00:00
mtex - > BindOrCreate ( tex - > GetTexture ( ) , 0 , sampler , lookuppal , bindflags ) ;
2019-10-17 22:20:27 +00:00
BindTexture ( 0 , mtex , sampler ) ;
2020-01-18 21:41:08 +00:00
// Needs a) testing and b) verification for correctness. This doesn't look like it makes sense.
if ( rep & & ( rep - > scale . x ! = 1.0f | | rep - > scale . y ! = 1.0f ) )
2019-10-17 22:20:27 +00:00
{
2020-01-18 21:41:08 +00:00
//texmat.loadIdentity();
//texmat.scale(rep->scale.x, rep->scale.y, 1.0f);
//GLInterface.SetMatrix(Matrix_Texture, &texmat);
2019-10-17 22:20:27 +00:00
}
2019-10-17 19:44:34 +00:00
2019-10-17 22:20:27 +00:00
// Also load additional layers needed for this texture.
2020-05-24 08:30:09 +00:00
if ( hw_detailmapping & & hw_hightile & & picnum > - 1 )
2019-10-17 22:20:27 +00:00
{
2019-10-18 12:04:32 +00:00
float detscalex = detscale , detscaley = detscale ;
if ( ! ( method & DAMETH_MODEL ) )
2019-10-17 22:20:27 +00:00
{
2020-05-24 06:47:45 +00:00
auto drep = TileFiles . FindReplacement ( picnum , DETAILPAL ) ;
2019-10-18 12:04:32 +00:00
if ( drep )
{
det = drep - > faces [ 0 ] ;
detscalex = drep - > scale . x ;
detscaley = drep - > scale . y ;
}
}
if ( det )
{
2020-05-29 13:55:08 +00:00
auto htex = LoadTexture ( det - > GetTexture ( ) , TT_HICREPLACE , 0 ) ;
2019-10-17 22:20:27 +00:00
UseDetailMapping ( true ) ;
2020-05-29 13:55:08 +00:00
htex - > BindOrCreate ( det - > GetTexture ( ) , 3 , CLAMP_NONE , 0 , 0 ) ;
2019-10-17 22:20:27 +00:00
BindTexture ( 3 , htex , SamplerRepeat ) ;
2019-12-30 19:44:37 +00:00
texbound [ 0 ] = true ;
2019-10-17 22:20:27 +00:00
2020-01-18 21:41:08 +00:00
/* todo: instead of a matrix, just pass a two-component uniform. Using a full matrix here is problematic.
2019-10-18 12:04:32 +00:00
if ( MatrixChange & 1 ) MatrixChange | = 2 ;
else texmat . loadIdentity ( ) ;
if ( ( detscalex ! = 1.0f ) | | ( detscaley ! = 1.0f ) )
2019-10-17 22:20:27 +00:00
{
2019-10-18 12:04:32 +00:00
texmat . scale ( detscalex , detscaley , 1.0f ) ;
2019-10-17 22:20:27 +00:00
MatrixChange | = 2 ;
}
if ( MatrixChange & 2 ) GLInterface . SetMatrix ( Matrix_Detail , & texmat ) ;
2020-01-18 21:41:08 +00:00
*/
2019-10-17 22:20:27 +00:00
}
}
2020-05-24 08:30:09 +00:00
if ( hw_glowmapping & & hw_hightile & & picnum > - 1 )
2019-10-17 22:20:27 +00:00
{
2019-10-18 12:04:32 +00:00
if ( ! ( method & DAMETH_MODEL ) )
2019-10-17 22:20:27 +00:00
{
2020-05-24 06:47:45 +00:00
auto drep = TileFiles . FindReplacement ( picnum , GLOWPAL ) ;
2019-10-18 12:04:32 +00:00
if ( drep )
{
glow = drep - > faces [ 0 ] ;
}
}
if ( glow )
{
2020-05-29 13:55:08 +00:00
auto htex = LoadTexture ( glow - > GetTexture ( ) , TT_HICREPLACE , 0 ) ;
2019-10-17 22:20:27 +00:00
UseGlowMapping ( true ) ;
2020-05-29 13:55:08 +00:00
htex - > BindOrCreate ( glow - > GetTexture ( ) , 4 , sampler , 0 , CTF_Upscale ) ;
2019-10-17 22:20:27 +00:00
BindTexture ( 4 , htex , SamplerRepeat ) ;
2019-12-30 19:44:37 +00:00
texbound [ 1 ] = true ;
2019-10-17 22:20:27 +00:00
}
}
2019-11-15 19:51:02 +00:00
# if 1
2020-05-29 13:55:08 +00:00
if ( picnum > - 1 & & ! ( TileFiles . tiledata [ picnum ] . picanm . sf & PICANM_NOFULLBRIGHT_BIT ) & & ! ( globalflags & GLOBAL_NO_GL_FULLBRIGHT ) )
2019-10-17 22:20:27 +00:00
{
2019-10-18 09:37:07 +00:00
if ( TextureType = = TT_HICREPLACE )
{
2020-05-24 06:47:45 +00:00
auto brep = TileFiles . FindReplacement ( picnum , BRIGHTPAL ) ;
2019-10-18 09:37:07 +00:00
if ( brep )
{
2020-05-29 13:55:08 +00:00
auto mtex = LoadTexture ( brep - > faces [ 0 ] - > GetTexture ( ) , TT_HICREPLACE , 0 ) ;
2019-11-10 18:42:26 +00:00
UseBrightmaps ( true ) ;
2020-05-29 13:55:08 +00:00
mtex - > BindOrCreate ( brep - > faces [ 0 ] - > GetTexture ( ) , 5 , sampler , 0 , CTF_Upscale ) ;
2019-10-18 09:37:07 +00:00
BindTexture ( 5 , mtex , sampler ) ;
2019-12-30 19:44:37 +00:00
texbound [ 2 ] = true ;
2019-10-18 09:37:07 +00:00
}
}
else if ( TextureType = = TT_TRUECOLOR )
{
2020-05-29 13:55:08 +00:00
auto btex = tex - > GetBrightmap ( ) ;
if ( btex )
2019-10-18 09:37:07 +00:00
{
2020-05-29 13:55:08 +00:00
auto htex = LoadTexture ( btex , TT_BRIGHTMAP , lookuppal ) ;
if ( htex ! = nullptr )
2019-11-10 18:42:26 +00:00
{
UseBrightmaps ( true ) ;
2020-05-29 13:55:08 +00:00
htex - > BindOrCreate ( btex , 5 , sampler , 0 , CTF_Upscale ) ;
2019-11-11 22:54:09 +00:00
BindTexture ( 5 , htex , sampler ) ;
2019-12-30 19:44:37 +00:00
texbound [ 2 ] = true ;
2019-11-10 18:42:26 +00:00
}
2019-10-18 09:37:07 +00:00
}
}
2019-10-17 22:20:27 +00:00
}
2019-12-30 19:44:37 +00:00
if ( ! texbound [ 0 ] ) UnbindTexture ( 3 ) ;
if ( ! texbound [ 1 ] ) UnbindTexture ( 4 ) ;
if ( ! texbound [ 2 ] ) UnbindTexture ( 5 ) ;
2019-11-15 19:51:02 +00:00
# endif
2019-10-17 22:20:27 +00:00
}
2019-10-18 17:06:57 +00:00
else return false ;
2019-10-17 19:44:34 +00:00
2019-10-19 22:31:27 +00:00
float al = 0.5f ;
2019-10-17 22:20:27 +00:00
if ( TextureType = = TT_HICREPLACE )
{
2020-05-24 17:12:22 +00:00
al = ( ( unsigned ) picnum < MAXTILES & & alphahackarray [ picnum ] ! = 0 ) ? alphahackarray [ picnum ] * ( 1.f / 255.f ) :
2019-11-10 09:01:31 +00:00
( tex - > alphaThreshold > = 0 ? tex - > alphaThreshold * ( 1.f / 255.f ) : 0.f ) ;
2019-10-17 22:20:27 +00:00
}
2019-10-17 19:44:34 +00:00
GLInterface . SetAlphaThreshold ( al ) ;
2019-10-18 17:06:57 +00:00
return true ;
2019-10-17 19:44:34 +00:00
}
2017-06-27 02:24:34 +00:00
2013-05-15 02:18:27 +00:00
2019-11-05 22:35:38 +00:00
//===========================================================================
//
2020-05-29 13:55:08 +00:00
// stand-ins for the texture system. Nothing of this is used right now, but needs to be present to satisfy the linker
2019-11-05 22:35:38 +00:00
//
//===========================================================================
2020-05-24 19:19:33 +00:00
int PalCheck ( int tex )
{
return tex ;
}
void InitBuildTiles ( )
{
}
TArray < UserShaderDesc > usershaders ;