2019-09-16 17:35:04 +00:00
# pragma once
# include <stdlib.h>
# include <algorithm>
2019-09-16 20:56:48 +00:00
# include <vector>
2019-09-17 17:03:42 +00:00
# include <map>
2019-09-16 21:28:26 +00:00
# include "gl_samplers.h"
2019-09-17 17:03:42 +00:00
# include "gl_hwtexture.h"
2019-10-05 10:28:08 +00:00
# include "gl_renderstate.h"
2019-10-04 16:12:03 +00:00
# include "matrix.h"
2019-10-06 17:32:35 +00:00
# include "palentry.h"
2019-09-16 20:56:48 +00:00
class FSamplerManager ;
2019-10-05 10:28:08 +00:00
class FShader ;
class PolymostShader ;
2019-10-05 11:09:15 +00:00
class SurfaceShader ;
2019-10-05 19:59:03 +00:00
class FTexture ;
2019-10-06 19:15:53 +00:00
class GLInstance ;
struct PaletteData
{
int32_t crc32 ;
PalEntry colors [ 256 ] ;
2019-10-06 22:07:45 +00:00
float shades [ 512 ] ; // two values (addshade and mulshade for each palswap.)
bool shadesdone ;
2019-10-07 20:11:09 +00:00
int whiteindex , blackindex ;
2019-10-06 19:15:53 +00:00
FHardwareTexture * paltexture ;
} ;
2019-10-06 22:07:45 +00:00
struct PalShade
{
int palindex ;
float mulshade , addshade ;
} ;
struct PalswapData
{
int32_t crc32 ;
2019-10-06 22:34:15 +00:00
const uint8_t * lookup ; // points to the original data. This is static so no need to copy
2019-10-07 23:08:08 +00:00
FHardwareTexture * swaptexture ;
2019-10-06 22:07:45 +00:00
} ;
enum
{
PALSWAP_TEXTURE_SIZE = 2048
} ;
2019-10-06 19:15:53 +00:00
class PaletteManager
{
// The current engine limit is 256 palettes and 256 palswaps.
uint32_t palettemap [ 256 ] = { } ;
uint32_t palswapmap [ 256 ] = { } ;
2019-10-06 22:34:15 +00:00
float addshade [ 256 ] = { } ;
float mulshade [ 256 ] = { } ;
2019-10-06 19:15:53 +00:00
uint32_t lastindex = ~ 0u ;
2019-10-07 23:08:08 +00:00
uint32_t lastsindex = ~ 0u ;
2019-10-06 22:34:15 +00:00
int numshades = 1 ;
2019-10-06 19:15:53 +00:00
// Keep the short lived movie palettes out of the palette list for ease of maintenance.
// Since it is transient this doesn't need to be preserved if it changes, unlike the other palettes which need to be preserved as references for the texture management.
PaletteData transientpalette = { - 1 } ;
// All data is being stored in contiguous blocks that can be used as uniform buffers as-is.
TArray < PaletteData > palettes ;
2019-10-06 22:07:45 +00:00
TArray < PalswapData > palswaps ;
FHardwareTexture * palswapTexture = nullptr ;
2019-10-06 19:15:53 +00:00
GLInstance * const inst ;
//OpenGLRenderer::GLDataBuffer* palswapBuffer = nullptr;
unsigned FindPalette ( const uint8_t * paldata ) ;
2019-10-06 22:07:45 +00:00
unsigned FindPalswap ( const uint8_t * paldata ) ;
2019-10-06 19:15:53 +00:00
public :
PaletteManager ( GLInstance * inst_ ) : inst ( inst_ )
{ }
~ PaletteManager ( ) ;
void DeleteAll ( ) ;
void SetPalette ( int index , const uint8_t * data , bool transient ) ;
2019-10-06 22:34:15 +00:00
void SetPalswapData ( int index , const uint8_t * data , int numshades ) ;
2019-10-06 19:15:53 +00:00
void BindPalette ( int index ) ;
2019-10-07 23:08:08 +00:00
void BindPalswap ( int index ) ;
2019-10-06 19:15:53 +00:00
} ;
2019-09-16 17:35:04 +00:00
2019-10-04 19:13:04 +00:00
struct glinfo_t {
const char * vendor ;
const char * renderer ;
const char * version ;
const char * extensions ;
float maxanisotropy ;
char bufferstorage ;
char dumped ;
} ;
2019-09-16 17:35:04 +00:00
struct BaseVertex
{
float x , y , z ;
float u , v ;
void SetVertex ( float _x , float _y , float _z = 0 )
{
x = _x ;
y = _y ;
z = _z ;
}
void SetTexCoord ( float _u = 0 , float _v = 0 )
{
u = _u ;
v = _v ;
}
2019-09-16 19:08:42 +00:00
void Set ( float _x , float _y , float _z = 0 , float _u = 0 , float _v = 0 )
{
x = _x ;
y = _y ;
z = _z ;
u = _u ;
v = _v ;
}
2019-09-16 17:35:04 +00:00
} ;
enum EDrawType
{
DT_TRIANGLES ,
DT_TRIANGLE_STRIP ,
DT_TRIANGLE_FAN ,
DT_QUADS ,
DT_LINES
} ;
2019-10-04 16:12:03 +00:00
enum EMatrixType
{
2019-10-05 10:28:08 +00:00
Matrix_View ,
2019-10-04 16:12:03 +00:00
Matrix_Projection ,
Matrix_ModelView ,
2019-10-06 08:19:51 +00:00
Matrix_Detail ,
Matrix_Glow ,
2019-10-05 10:28:08 +00:00
// These are the only ones being used.
2019-10-04 16:12:03 +00:00
NUMMATRICES
} ;
enum ECull
{
Cull_None ,
Cull_Front ,
Cull_Back
} ;
2019-10-04 16:44:16 +00:00
enum EDepthFunc
{
Depth_Always ,
Depth_Less ,
Depth_Equal ,
Depth_LessEqual
} ;
2019-10-04 17:17:55 +00:00
enum ERenderAlpha
{
STYLEALPHA_Zero , // Blend factor is 0.0
STYLEALPHA_One , // Blend factor is 1.0
STYLEALPHA_Src , // Blend factor is alpha
STYLEALPHA_InvSrc , // Blend factor is 1.0 - alpha
STYLEALPHA_SrcCol , // Blend factor is color (HWR only)
STYLEALPHA_InvSrcCol , // Blend factor is 1.0 - color (HWR only)
STYLEALPHA_DstCol , // Blend factor is dest. color (HWR only)
STYLEALPHA_InvDstCol , // Blend factor is 1.0 - dest. color (HWR only)
STYLEALPHA_Dst , // Blend factor is dest. alpha
STYLEALPHA_InvDst , // Blend factor is 1.0 - dest. alpha
STYLEALPHA_MAX
} ;
enum ERenderOp
{
STYLEOP_Add , // Add source to destination
STYLEOP_Sub , // Subtract source from destination
STYLEOP_RevSub , // Subtract destination from source
} ;
2019-10-04 19:13:04 +00:00
enum EWinding
{
Winding_CCW ,
Winding_CW
} ;
2019-09-16 17:35:04 +00:00
class GLInstance
{
2019-09-17 17:03:42 +00:00
enum
{
MAX_TEXTURES = 15 , // slot 15 is used internally and not available.
THCACHESIZE = 200 ,
} ;
2019-09-16 20:56:48 +00:00
std : : vector < BaseVertex > Buffer ; // cheap-ass implementation. The primary purpose is to get the GL accesses out of polymost.cpp, not writing something performant right away.
2019-09-17 17:03:42 +00:00
unsigned int LastBoundTextures [ MAX_TEXTURES ] ;
unsigned TextureHandleCache [ THCACHESIZE ] ;
int currentindex = THCACHESIZE ;
2019-10-04 16:12:03 +00:00
int maxTextureSize ;
2019-10-06 19:15:53 +00:00
PaletteManager palmanager ;
2019-10-06 22:07:45 +00:00
int lastPalswapIndex = - 1 ;
2019-10-04 16:12:03 +00:00
VSMatrix matrices [ NUMMATRICES ] ;
2019-10-05 10:28:08 +00:00
PolymostRenderState renderState ;
FShader * activeShader ;
PolymostShader * polymostShader ;
2019-10-05 11:09:15 +00:00
SurfaceShader * surfaceShader ;
2019-10-05 11:38:02 +00:00
FShader * vpxShader ;
2019-09-17 17:03:42 +00:00
2019-09-16 17:35:04 +00:00
public :
2019-10-04 19:13:04 +00:00
glinfo_t glinfo ;
2019-09-16 20:56:48 +00:00
FSamplerManager * mSamplers ;
void Init ( ) ;
2019-10-04 16:12:03 +00:00
void InitGLState ( int fogmode , int multisample ) ;
2019-10-05 10:28:08 +00:00
void LoadPolymostShader ( ) ;
2019-10-05 11:09:15 +00:00
void LoadSurfaceShader ( ) ;
void LoadVPXShader ( ) ;
2019-10-04 16:12:03 +00:00
2019-09-16 20:56:48 +00:00
void Deinit ( ) ;
2019-09-17 17:03:42 +00:00
static int GetTexDimension ( int value )
{
//if (value > gl.max_texturesize) return gl.max_texturesize;
return value ;
}
2019-09-16 17:35:04 +00:00
2019-10-06 19:15:53 +00:00
GLInstance ( ) ;
2019-09-16 17:35:04 +00:00
std : : pair < size_t , BaseVertex * > AllocVertices ( size_t num ) ;
void Draw ( EDrawType type , size_t start , size_t count ) ;
2019-09-17 17:03:42 +00:00
int GetTextureID ( ) ;
2019-09-18 18:44:21 +00:00
FHardwareTexture * NewTexture ( ) ;
2019-10-06 07:31:36 +00:00
FGameTexture * NewTexture ( const char * name , bool hightile ) ;
2019-09-18 18:44:21 +00:00
void BindTexture ( int texunit , FHardwareTexture * texid , int sampler = NoSampler ) ;
2019-10-06 07:31:36 +00:00
void BindTexture ( int texunit , FGameTexture * texid , int sampler = NoSampler ) ;
2019-09-17 17:03:42 +00:00
void UnbindTexture ( int texunit ) ;
void UnbindAllTextures ( ) ;
2019-10-04 16:12:03 +00:00
void EnableBlend ( bool on ) ;
void EnableAlphaTest ( bool on ) ;
void EnableDepthTest ( bool on ) ;
const VSMatrix & GetMatrix ( int num )
{
return matrices [ num ] ;
}
void SetMatrix ( int num , const VSMatrix * mat ) ;
void SetMatrix ( int num , const float * mat )
{
SetMatrix ( num , reinterpret_cast < const VSMatrix * > ( mat ) ) ;
}
2019-10-04 19:13:04 +00:00
void SetCull ( int type , int winding = Winding_CCW ) ;
2019-10-04 16:12:03 +00:00
void EnableStencilWrite ( int value ) ;
void EnableStencilTest ( int value ) ;
void DisableStencil ( ) ;
2019-10-04 16:25:18 +00:00
void SetColor ( float r , float g , float b , float a = 1.f ) ;
void SetColorub ( uint8_t r , uint8_t g , uint8_t b , uint8_t a = 255 )
{
SetColor ( r * ( 1 / 255.f ) , g * ( 1 / 255.f ) , b * ( 1 / 255.f ) , a * ( 1 / 255.f ) ) ;
}
2019-10-04 16:44:16 +00:00
void SetDepthFunc ( int func ) ;
void SetFogLinear ( float * color , float start , float end ) ;
void SetFogExp2 ( float * color , float coefficient ) ;
2019-10-04 17:17:55 +00:00
void SetColorMask ( bool on ) ;
void SetDepthMask ( bool on ) ;
void SetBlendFunc ( int src , int dst ) ;
void SetBlendOp ( int op ) ;
2019-10-04 19:13:04 +00:00
void ClearScreen ( float r , float g , float b , bool depth ) ;
void ClearDepth ( ) ;
void SetViewport ( int x , int y , int w , int h ) ;
void SetAlphaThreshold ( float al ) ;
void SetWireframe ( bool on ) ;
2019-10-05 10:28:08 +00:00
void SetPolymostShader ( ) ;
2019-10-05 11:09:15 +00:00
void SetSurfaceShader ( ) ;
2019-10-05 11:38:02 +00:00
void SetVPXShader ( ) ;
2019-10-06 19:15:53 +00:00
void SetPalette ( int palette ) ;
2019-10-04 19:13:04 +00:00
void ReadPixels ( int w , int h , uint8_t * buffer ) ;
2019-10-05 10:28:08 +00:00
2019-10-06 19:15:53 +00:00
void SetPaletteData ( int index , const uint8_t * data , bool transient )
{
palmanager . SetPalette ( index , data , transient ) ;
}
2019-10-06 22:34:15 +00:00
void SetPalswapData ( int index , const uint8_t * data , int numshades )
2019-10-06 22:07:45 +00:00
{
2019-10-06 22:34:15 +00:00
palmanager . SetPalswapData ( index , data , numshades ) ;
2019-10-06 22:07:45 +00:00
}
void SetPalswap ( int index ) ;
2019-10-05 10:28:08 +00:00
int GetClamp ( )
{
return int ( renderState . Clamp [ 0 ] + 2 * renderState . Clamp [ 1 ] ) ;
}
void SetClamp ( int clamp )
{
renderState . Clamp [ 0 ] = clamp & 1 ;
renderState . Clamp [ 1 ] = ! ! ( clamp & 2 ) ;
}
void SetShade ( int32_t shade , int numshades )
{
renderState . Shade = shade ;
renderState . NumShades = numshades ;
}
void SetVisibility ( float visibility , float fviewingrange )
{
renderState . VisFactor = visibility * fviewingrange * ( 1.f / ( 64.f * 65536.f ) ) ;
}
void SetFogEnabled ( bool fogEnabled )
{
renderState . FogEnabled = fogEnabled ;
}
void UseColorOnly ( bool useColorOnly )
{
renderState . UseColorOnly = useColorOnly ;
}
void UsePaletteIndexing ( bool usePaletteIndexing )
{
renderState . UsePalette = usePaletteIndexing ;
}
void UseDetailMapping ( bool useDetailMapping )
{
renderState . UseDetailMapping = useDetailMapping ;
}
void UseGlowMapping ( bool useGlowMapping )
{
renderState . UseGlowMapping = useGlowMapping ;
}
void SetNpotEmulation ( bool npotEmulation , float factor , float xOffset )
{
renderState . NPOTEmulation = npotEmulation ;
renderState . NPOTEmulationFactor = factor ;
renderState . NPOTEmulationXOffset = xOffset ;
}
void SetShadeInterpolate ( int32_t shadeInterpolate )
{
renderState . ShadeInterpolate = shadeInterpolate ;
}
void SetBrightness ( int brightness )
{
renderState . Brightness = 8.f / ( brightness + 8.f ) ;
}
2019-10-06 10:42:35 +00:00
2019-10-05 19:59:03 +00:00
FTexture * GetTexture ( const char * filename ) ;
2019-09-16 17:35:04 +00:00
} ;
2019-10-04 16:12:03 +00:00
extern GLInstance GLInterface ;