- remove colormap from texture generation parameters. The one remaining special case, alpha texture on old hardware is now handled by the currently set texture mode at the time of use.

- use the cleaned up decal lighting code from the first GLEW branch.
This commit is contained in:
Christoph Oelckers 2014-05-11 19:44:19 +02:00
parent 7793bbbcc9
commit 887d35d559
14 changed files with 134 additions and 292 deletions

View file

@ -170,6 +170,7 @@ void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend
} }
else if (style.Flags & STYLEF_InvertSource) else if (style.Flags & STYLEF_InvertSource)
{ {
// The only place where InvertSource is used is for inverted sprites with the infrared powerup.
texturemode = TM_INVERSE; texturemode = TM_INVERSE;
} }

View file

@ -246,7 +246,7 @@ unsigned char *FGLRenderer::GetTextureBuffer(FTexture *tex, int &w, int &h)
FMaterial * gltex = FMaterial::ValidateTexture(tex); FMaterial * gltex = FMaterial::ValidateTexture(tex);
if (gltex) if (gltex)
{ {
return gltex->CreateTexBuffer(CM_DEFAULT, 0, w, h); return gltex->CreateTexBuffer(0, w, h);
} }
return NULL; return NULL;
} }

View file

@ -2,6 +2,7 @@
#define __GL_RENDERSTATE_H #define __GL_RENDERSTATE_H
#include <string.h> #include <string.h>
#include "gl/system/gl_interface.h"
#include "c_cvars.h" #include "c_cvars.h"
#include "r_defs.h" #include "r_defs.h"
@ -177,6 +178,7 @@ public:
void SetTextureMode(int mode) void SetTextureMode(int mode)
{ {
mTextureMode = mode; mTextureMode = mode;
gl.checkTextureMode(mode);
} }
void EnableTexture(bool on) void EnableTexture(bool on)

View file

@ -74,7 +74,7 @@ void GLWall::DrawDecal(DBaseDecal *decal)
int light; int light;
int rel; int rel;
float a; float a;
bool flipx, flipy, loadAlpha; bool flipx, flipy;
DecalVertex dv[4]; DecalVertex dv[4];
FTextureID decalTile; FTextureID decalTile;
@ -179,9 +179,6 @@ void GLWall::DrawDecal(DBaseDecal *decal)
rel = rellight + getExtraLight(); rel = rellight + getExtraLight();
} }
int r = RPART(decal->AlphaColor);
int g = GPART(decal->AlphaColor);
int b = BPART(decal->AlphaColor);
FColormap p = Colormap; FColormap p = Colormap;
if (glset.nocoloredspritelighting) if (glset.nocoloredspritelighting)
@ -190,58 +187,6 @@ void GLWall::DrawDecal(DBaseDecal *decal)
p.LightColor = PalEntry(p.colormap, v, v, v); p.LightColor = PalEntry(p.colormap, v, v, v);
} }
float red, green, blue;
if (decal->RenderStyle.Flags & STYLEF_RedIsAlpha)
{
loadAlpha = true;
p.colormap=CM_SHADE;
if (glset.lightmode != 8)
{
gl_GetLightColor(light, rel, &p, &red, &green, &blue);
}
else
{
gl_GetLightColor(lightlevel, rellight, &p, &red, &green, &blue);
}
if (gl_lights && GLRenderer->mLightCount && !gl_fixedcolormap && gl_light_sprites)
{
float result[3];
fixed_t x, y;
decal->GetXY(seg->sidedef, x, y);
gl_GetSpriteLight(NULL, x, y, zpos, sub, Colormap.colormap-CM_DESAT0, result, line, side == line->sidedef[0]? 0:1);
if (glset.lightmode != 8)
{
red = clamp<float>(result[0]+red, 0, 1.0f);
green = clamp<float>(result[1]+green, 0, 1.0f);
blue = clamp<float>(result[2]+blue, 0, 1.0f);
}
else
{
gl_RenderState.SetDynLight(result[0], result[1], result[2]);
}
}
BYTE R = xs_RoundToInt(r * red);
BYTE G = xs_RoundToInt(g * green);
BYTE B = xs_RoundToInt(b * blue);
gl_ModifyColor(R,G,B, Colormap.colormap);
red = R/255.f;
green = G/255.f;
blue = B/255.f;
}
else
{
loadAlpha = false;
red = 1.f;
green = 1.f;
blue = 1.f;
}
a = FIXED2FLOAT(decal->Alpha); a = FIXED2FLOAT(decal->Alpha);
@ -299,8 +244,6 @@ void GLWall::DrawDecal(DBaseDecal *decal)
zpos+= FRACUNIT*(flipy? decalheight-decaltopo : decaltopo); zpos+= FRACUNIT*(flipy? decalheight-decaltopo : decaltopo);
tex->BindPatch(p.colormap, decal->Translation);
dv[1].z=dv[2].z = FIXED2FLOAT(zpos); dv[1].z=dv[2].z = FIXED2FLOAT(zpos);
dv[0].z=dv[3].z = dv[1].z - decalheight; dv[0].z=dv[3].z = dv[1].z - decalheight;
dv[1].v=dv[2].v = tex->GetVT(); dv[1].v=dv[2].v = tex->GetVT();
@ -359,32 +302,25 @@ void GLWall::DrawDecal(DBaseDecal *decal)
float vb = tex->GetVB(); float vb = tex->GetVB();
for(i=0;i<4;i++) dv[i].v=vb-dv[i].v; for(i=0;i<4;i++) dv[i].v=vb-dv[i].v;
} }
// fog is set once per wall in the calling function and not per decal!
if (loadAlpha) // calculate dynamic light effect.
if (gl_lights && GLRenderer->mLightCount && !gl_fixedcolormap && gl_light_sprites)
{ {
glColor4f(red, green, blue, a); // Note: This should be replaced with proper shader based lighting.
fixed_t x, y;
if (glset.lightmode == 8) decal->GetXY(seg->sidedef, x, y);
{ gl_SetDynSpriteLight(NULL, x, y, zpos, sub);
if (gl_fixedcolormap)
glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0);
else
glVertexAttrib1f(VATTR_LIGHTLEVEL, gl_CalcLightLevel(light, rel, false) / 255.0);
}
}
else
{
if (glset.lightmode == 8)
{
gl_SetColor(light, rel, &p, a, !!extralight); // Korshun.
}
else
{
gl_SetColor(light, rel, &p, a);
}
} }
// alpha color only has an effect when using an alpha texture.
if (decal->RenderStyle.Flags & STYLEF_RedIsAlpha)
{
gl_RenderState.SetObjectColor(decal->AlphaColor);
}
gl_SetColor(light, rel, &p, a);
// for additively drawn decals we must temporarily set the fog color to black.
PalEntry fc = gl_RenderState.GetFogColor(); PalEntry fc = gl_RenderState.GetFogColor();
if (decal->RenderStyle.BlendOp == STYLEOP_Add && decal->RenderStyle.DestAlpha == STYLEALPHA_One) if (decal->RenderStyle.BlendOp == STYLEOP_Add && decal->RenderStyle.DestAlpha == STYLEALPHA_One)
{ {
@ -393,6 +329,8 @@ void GLWall::DrawDecal(DBaseDecal *decal)
gl_SetRenderStyle(decal->RenderStyle, false, false); gl_SetRenderStyle(decal->RenderStyle, false, false);
tex->BindPatch(p.colormap, decal->Translation);
// If srcalpha is one it looks better with a higher alpha threshold // If srcalpha is one it looks better with a higher alpha threshold
if (decal->RenderStyle.SrcAlpha == STYLEALPHA_One) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold); if (decal->RenderStyle.SrcAlpha == STYLEALPHA_One) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
@ -407,6 +345,8 @@ void GLWall::DrawDecal(DBaseDecal *decal)
} }
glEnd(); glEnd();
rendered_decals++; rendered_decals++;
gl_RenderState.SetTextureMode(TM_MODULATE);
gl_RenderState.SetObjectColor(0xffffffff);
gl_RenderState.SetFog(fc,-1); gl_RenderState.SetFog(fc,-1);
gl_RenderState.SetDynLight(0,0,0); gl_RenderState.SetDynLight(0,0,0);
} }

View file

@ -290,7 +290,6 @@ static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float
if (tex && !secondlayer) if (tex && !secondlayer)
{ {
PalEntry pe = tex->tex->GetSkyCapColor(false); PalEntry pe = tex->tex->GetSkyCapColor(false);
if (CM_Index!=CM_DEFAULT) ModifyPalette(&pe, &pe, CM_Index, 1);
R=pe.r/255.0f; R=pe.r/255.0f;
G=pe.g/255.0f; G=pe.g/255.0f;
@ -312,7 +311,6 @@ static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float
if (tex && !secondlayer) if (tex && !secondlayer)
{ {
PalEntry pe = tex->tex->GetSkyCapColor(true); PalEntry pe = tex->tex->GetSkyCapColor(true);
if (CM_Index!=CM_DEFAULT) ModifyPalette(&pe, &pe, CM_Index, 1);
R=pe.r/255.0f; R=pe.r/255.0f;
G=pe.g/255.0f; G=pe.g/255.0f;
B=pe.b/255.0f; B=pe.b/255.0f;

View file

@ -194,7 +194,6 @@ void gl_PrintStartupLog()
void gl_SetTextureMode(int type) void gl_SetTextureMode(int type)
{ {
gl.needAlphaTexture = false;
if (type == TM_MASK) if (type == TM_MASK)
{ {
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
@ -239,7 +238,6 @@ void gl_SetTextureMode(int type)
else // if (type == TM_MODULATE) else // if (type == TM_MODULATE)
{ {
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
gl.needAlphaTexture = (type == TM_REDTOALPHA);
} }
} }

View file

@ -44,6 +44,11 @@ struct RenderContext
{ {
return glslversion >= 1.3f; return glslversion >= 1.3f;
} }
void checkTextureMode(int mode)
{
if (!hasGLSL()) needAlphaTexture = (mode == TM_REDTOALPHA);
}
}; };
extern RenderContext gl; extern RenderContext gl;

View file

@ -145,9 +145,9 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
} }
wipestartscreen = new FHardwareTexture(Width, Height, false, false, false, true); wipestartscreen = new FHardwareTexture(Width, Height, false, false, false, true);
wipestartscreen->CreateTexture(NULL, Width, Height, false, 0, CM_DEFAULT); wipestartscreen->CreateTexture(NULL, Width, Height, false, 0);
glFinish(); glFinish();
wipestartscreen->Bind(0, CM_DEFAULT); wipestartscreen->Bind(0);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@ -168,9 +168,9 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
void OpenGLFrameBuffer::WipeEndScreen() void OpenGLFrameBuffer::WipeEndScreen()
{ {
wipeendscreen = new FHardwareTexture(Width, Height, false, false, false, true); wipeendscreen = new FHardwareTexture(Width, Height, false, false, false, true);
wipeendscreen->CreateTexture(NULL, Width, Height, false, 0, CM_DEFAULT); wipeendscreen->CreateTexture(NULL, Width, Height, false, 0);
glFlush(); glFlush();
wipeendscreen->Bind(0, CM_DEFAULT); wipeendscreen->Bind(0);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@ -280,7 +280,7 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb)
gl_RenderState.SetTextureMode(TM_OPAQUE); gl_RenderState.SetTextureMode(TM_OPAQUE);
gl_RenderState.EnableAlphaTest(false); gl_RenderState.EnableAlphaTest(false);
gl_RenderState.Apply(); gl_RenderState.Apply();
fb->wipestartscreen->Bind(0, CM_DEFAULT); fb->wipestartscreen->Bind(0);
glColor4f(1.f, 1.f, 1.f, 1.f); glColor4f(1.f, 1.f, 1.f, 1.f);
glBegin(GL_TRIANGLE_STRIP); glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0, vb); glTexCoord2f(0, vb);
@ -293,7 +293,7 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb)
glVertex2i(fb->Width, fb->Height); glVertex2i(fb->Width, fb->Height);
glEnd(); glEnd();
fb->wipeendscreen->Bind(0, CM_DEFAULT); fb->wipeendscreen->Bind(0);
glColor4f(1.f, 1.f, 1.f, clamp(Clock/32.f, 0.f, 1.f)); glColor4f(1.f, 1.f, 1.f, clamp(Clock/32.f, 0.f, 1.f));
glBegin(GL_TRIANGLE_STRIP); glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0, vb); glTexCoord2f(0, vb);
@ -347,7 +347,7 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb)
// Draw the new screen on the bottom. // Draw the new screen on the bottom.
gl_RenderState.SetTextureMode(TM_OPAQUE); gl_RenderState.SetTextureMode(TM_OPAQUE);
gl_RenderState.Apply(); gl_RenderState.Apply();
fb->wipeendscreen->Bind(0, CM_DEFAULT); fb->wipeendscreen->Bind(0);
glColor4f(1.f, 1.f, 1.f, 1.f); glColor4f(1.f, 1.f, 1.f, 1.f);
glBegin(GL_TRIANGLE_STRIP); glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0, vb); glTexCoord2f(0, vb);
@ -363,7 +363,7 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb)
int i, dy; int i, dy;
bool done = false; bool done = false;
fb->wipestartscreen->Bind(0, CM_DEFAULT); fb->wipestartscreen->Bind(0);
// Copy the old screen in vertical strips on top of the new one. // Copy the old screen in vertical strips on top of the new one.
while (ticks--) while (ticks--)
{ {
@ -492,7 +492,7 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb)
gl_RenderState.SetTextureMode(TM_OPAQUE); gl_RenderState.SetTextureMode(TM_OPAQUE);
gl_RenderState.EnableAlphaTest(false); gl_RenderState.EnableAlphaTest(false);
gl_RenderState.Apply(); gl_RenderState.Apply();
fb->wipestartscreen->Bind(0, CM_DEFAULT); fb->wipestartscreen->Bind(0);
glColor4f(1.f, 1.f, 1.f, 1.f); glColor4f(1.f, 1.f, 1.f, 1.f);
glBegin(GL_TRIANGLE_STRIP); glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0, vb); glTexCoord2f(0, vb);
@ -523,10 +523,10 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb)
// Burn the new screen on top of it. // Burn the new screen on top of it.
glColor4f(1.f, 1.f, 1.f, 1.f); glColor4f(1.f, 1.f, 1.f, 1.f);
fb->wipeendscreen->Bind(1, CM_DEFAULT); fb->wipeendscreen->Bind(1);
//BurnTexture->Bind(0, CM_DEFAULT); //BurnTexture->Bind(0, CM_DEFAULT);
BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, false, 0, CM_DEFAULT); BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, false, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

View file

@ -50,12 +50,11 @@
// //
//=========================================================================== //===========================================================================
template<class T> template<class T>
void iCopyColors(unsigned char * pout, const unsigned char * pin, int cm, int count, int step) void iCopyColors(unsigned char * pout, const unsigned char * pin, bool alphatex, int count, int step)
{ {
int i; int i;
int fac;
if (cm == CM_DEFAULT) if (!alphatex)
{ {
for(i=0;i<count;i++) for(i=0;i<count;i++)
{ {
@ -70,7 +69,7 @@ void iCopyColors(unsigned char * pout, const unsigned char * pin, int cm, int co
pin+=step; pin+=step;
} }
} }
else if (cm == CM_SHADE) else
{ {
// Alpha shade uses the red channel for true color pics // Alpha shade uses the red channel for true color pics
for(i=0;i<count;i++) for(i=0;i<count;i++)
@ -84,40 +83,9 @@ void iCopyColors(unsigned char * pout, const unsigned char * pin, int cm, int co
pin+=step; pin+=step;
} }
} }
else if (cm >= CM_FIRSTSPECIALCOLORMAP && cm < CM_FIRSTSPECIALCOLORMAP + int(SpecialColormaps.Size()))
{
for(i=0;i<count;i++)
{
if (T::A(pin) != 0)
{
PalEntry pe = SpecialColormaps[cm - CM_FIRSTSPECIALCOLORMAP].GrayscaleToColor[T::Gray(pin)];
pout[0] = pe.r;
pout[1] = pe.g;
pout[2] = pe.b;
pout[3] = T::A(pin);
}
pout+=4;
pin+=step;
}
}
else if (cm<=CM_DESAT31)
{
// Desaturated light settings.
fac=cm-CM_DESAT0;
for(i=0;i<count;i++)
{
if (T::A(pin) != 0)
{
gl_Desaturate(T::Gray(pin), T::R(pin), T::G(pin), T::B(pin), pout[0], pout[1], pout[2], fac);
pout[3] = T::A(pin);
}
pout+=4;
pin+=step;
}
}
} }
typedef void (*CopyFunc)(unsigned char * pout, const unsigned char * pin, int cm, int count, int step); typedef void (*CopyFunc)(unsigned char * pout, const unsigned char * pin, bool alphatex, int count, int step);
static CopyFunc copyfuncs[]={ static CopyFunc copyfuncs[]={
iCopyColors<cRGB>, iCopyColors<cRGB>,
@ -147,57 +115,11 @@ void FGLBitmap::CopyPixelDataRGB(int originx, int originy,
BYTE *buffer = GetPixels() + 4*originx + Pitch*originy; BYTE *buffer = GetPixels() + 4*originx + Pitch*originy;
for (int y=0;y<srcheight;y++) for (int y=0;y<srcheight;y++)
{ {
copyfuncs[ct](&buffer[y*Pitch], &patch[y*step_y], cm, srcwidth, step_x); copyfuncs[ct](&buffer[y*Pitch], &patch[y*step_y], alphatex, srcwidth, step_x);
} }
} }
} }
//===========================================================================
//
// Creates one of the special palette translations for the given palette
//
//===========================================================================
void ModifyPalette(PalEntry * pout, PalEntry * pin, int cm, int count)
{
int i;
int fac;
if (cm == CM_DEFAULT)
{
if (pin != pout)
memcpy(pout, pin, count * sizeof(PalEntry));
}
else if (cm >= CM_FIRSTSPECIALCOLORMAP && cm < CM_FIRSTSPECIALCOLORMAP + int(SpecialColormaps.Size()))
{
for(i=0;i<count;i++)
{
int gray = (pin[i].r*77 + pin[i].g*143 + pin[i].b*37) >> 8;
// This can be done in place so we cannot copy the color directly.
PalEntry pe = SpecialColormaps[cm - CM_FIRSTSPECIALCOLORMAP].GrayscaleToColor[gray];
pout[i].r = pe.r;
pout[i].g = pe.g;
pout[i].b = pe.b;
pout[i].a = pin[i].a;
}
}
else if (cm<=CM_DESAT31)
{
// Desaturated light settings.
fac=cm-CM_DESAT0;
for(i=0;i<count;i++)
{
int gray=(pin[i].r*77 + pin[i].g*143 + pin[i].b*36)>>8;
gl_Desaturate(gray, pin[i].r, pin[i].g, pin[i].b, pout[i].r, pout[i].g, pout[i].b, fac);
pout[i].a = pin[i].a;
}
}
else if (pin!=pout)
{
memcpy(pout, pin, count * sizeof(PalEntry));
}
}
//=========================================================================== //===========================================================================
// //
// Paletted to True Color texture copy function // Paletted to True Color texture copy function
@ -215,7 +137,7 @@ void FGLBitmap::CopyPixelData(int originx, int originy, const BYTE * patch, int
BYTE *buffer = GetPixels() + 4*originx + Pitch*originy; BYTE *buffer = GetPixels() + 4*originx + Pitch*originy;
// CM_SHADE is an alpha map with 0==transparent and 1==opaque // CM_SHADE is an alpha map with 0==transparent and 1==opaque
if (cm == CM_SHADE) if (alphatex)
{ {
for(int i=0;i<256;i++) for(int i=0;i<256;i++)
{ {
@ -225,37 +147,21 @@ void FGLBitmap::CopyPixelData(int originx, int originy, const BYTE * patch, int
penew[i]=PalEntry(0,255,255,255); // If the palette contains transparent colors keep them. penew[i]=PalEntry(0,255,255,255); // If the palette contains transparent colors keep them.
} }
} }
else else if (translation > 0)
{ {
// apply any translation. PalEntry *ptrans = GLTranslationPalette::GetPalette(translation);
// The ice and blood color translations are done directly if (ptrans)
// because that yields better results.
switch(translation)
{ {
default: for (i = 0; i < 256; i++)
{
PalEntry *ptrans = GLTranslationPalette::GetPalette(translation);
if (ptrans)
{ {
for(i = 0; i < 256; i++) penew[i] = (ptrans[i] & 0xffffff) | (palette[i] & 0xff000000);
{
penew[i] = (ptrans[i]&0xffffff) | (palette[i]&0xff000000);
}
break;
} }
} }
case 0:
memcpy(penew, palette, 256*sizeof(PalEntry));
break;
}
if (cm!=0)
{
// Apply color modifications like invulnerability, desaturation and Boom colormaps
ModifyPalette(penew, penew, cm, 256);
}
} }
// Now penew contains the actual palette that is to be used for creating the image. else
{
memcpy(penew, palette, 256*sizeof(PalEntry));
}
// convert the image according to the translated palette. // convert the image according to the translated palette.
for (y=0;y<srcheight;y++) for (y=0;y<srcheight;y++)
@ -271,15 +177,6 @@ void FGLBitmap::CopyPixelData(int originx, int originy, const BYTE * patch, int
buffer[pos+2] = penew[v].b; buffer[pos+2] = penew[v].b;
buffer[pos+3] = penew[v].a; buffer[pos+3] = penew[v].a;
} }
/*
else if (penew[v].a!=255)
{
buffer[pos ] = (buffer[pos ] * penew[v].a + penew[v].r * (1-penew[v].a)) / 255;
buffer[pos+1] = (buffer[pos+1] * penew[v].a + penew[v].g * (1-penew[v].a)) / 255;
buffer[pos+2] = (buffer[pos+2] * penew[v].a + penew[v].b * (1-penew[v].a)) / 255;
buffer[pos+3] = clamp<int>(buffer[pos+3] + (( 255-buffer[pos+3]) * (255-penew[v].a))/255, 0, 255);
}
*/
} }
} }
} }

View file

@ -5,24 +5,34 @@
#include "gl/textures/gl_material.h" #include "gl/textures/gl_material.h"
void ModifyPalette(PalEntry * pout, PalEntry * pin, int cm, int count);
class FGLBitmap : public FBitmap class FGLBitmap : public FBitmap
{ {
int cm; bool alphatex;
int translation; int translation;
public: public:
FGLBitmap() { cm = CM_DEFAULT; translation = 0; } FGLBitmap()
{
alphatex = false;
translation = 0;
}
FGLBitmap(BYTE *buffer, int pitch, int width, int height) FGLBitmap(BYTE *buffer, int pitch, int width, int height)
: FBitmap(buffer, pitch, width, height) : FBitmap(buffer, pitch, width, height)
{ cm = CM_DEFAULT; translation = 0; }
void SetTranslationInfo(int _cm, int _trans=-1337)
{ {
if (_cm != -1) cm = _cm; alphatex = false;
if (_trans != -1337) translation = _trans; translation = 0;
}
void SetTranslationInfo(int _trans)
{
if (_trans == -1) alphatex = true;
else if (_trans != -1337) translation = _trans;
}
void SetAlphaTex()
{
alphatex = true;
} }
virtual void CopyPixelDataRGB(int originx, int originy, const BYTE *patch, int srcwidth, virtual void CopyPixelDataRGB(int originx, int originy, const BYTE *patch, int srcwidth,

View file

@ -277,9 +277,7 @@ FHardwareTexture::FHardwareTexture(int _width, int _height, bool _mipmap, bool w
texwidth=_width; texwidth=_width;
texheight=_height; texheight=_height;
int cm_arraysize = CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size(); glDefTexID = 0;
glTexID = new unsigned[cm_arraysize];
memset(glTexID,0,sizeof(unsigned int)*cm_arraysize);
clampmode=0; clampmode=0;
glDepthID = 0; glDepthID = 0;
forcenofiltering = nofilter; forcenofiltering = nofilter;
@ -317,21 +315,8 @@ void FHardwareTexture::Clean(bool all)
if (all) if (all)
{ {
for (int i=0;i<cm_arraysize;i++) DeleteTexture(glDefTexID);
{ glDefTexID = 0;
DeleteTexture(glTexID[i]);
}
//glDeleteTextures(cm_arraysize,glTexID);
memset(glTexID,0,sizeof(unsigned int)*cm_arraysize);
}
else
{
for (int i=1;i<cm_arraysize;i++)
{
DeleteTexture(glTexID[i]);
}
//glDeleteTextures(cm_arraysize-1,glTexID+1);
memset(glTexID+1,0,sizeof(unsigned int)*(cm_arraysize-1));
} }
for(unsigned int i=0;i<glTexID_Translated.Size();i++) for(unsigned int i=0;i<glTexID_Translated.Size();i++)
{ {
@ -349,7 +334,6 @@ void FHardwareTexture::Clean(bool all)
FHardwareTexture::~FHardwareTexture() FHardwareTexture::~FHardwareTexture()
{ {
Clean(true); Clean(true);
delete [] glTexID;
} }
@ -359,28 +343,24 @@ FHardwareTexture::~FHardwareTexture()
// //
//=========================================================================== //===========================================================================
unsigned * FHardwareTexture::GetTexID(int cm, int translation) unsigned * FHardwareTexture::GetTexID(int translation)
{ {
if (cm < 0 || cm >= CM_MAXCOLORMAP) cm=CM_DEFAULT;
if (translation==0) if (translation==0)
{ {
return &glTexID[cm]; return &glDefTexID;
} }
// normally there aren't more than very few different // normally there aren't more than very few different
// translations here so this isn't performance critical. // translations here so this isn't performance critical.
for(unsigned int i=0;i<glTexID_Translated.Size();i++) for(unsigned int i=0;i<glTexID_Translated.Size();i++)
{ {
if (glTexID_Translated[i].cm == cm && if (glTexID_Translated[i].translation == translation)
glTexID_Translated[i].translation == translation)
{ {
return &glTexID_Translated[i].glTexID; return &glTexID_Translated[i].glTexID;
} }
} }
int add = glTexID_Translated.Reserve(1); int add = glTexID_Translated.Reserve(1);
glTexID_Translated[add].cm=cm;
glTexID_Translated[add].translation=translation; glTexID_Translated[add].translation=translation;
glTexID_Translated[add].glTexID=0; glTexID_Translated[add].glTexID=0;
return &glTexID_Translated[add].glTexID; return &glTexID_Translated[add].glTexID;
@ -391,9 +371,10 @@ unsigned * FHardwareTexture::GetTexID(int cm, int translation)
// Binds this patch // Binds this patch
// //
//=========================================================================== //===========================================================================
unsigned int FHardwareTexture::Bind(int texunit, int cm,int translation) unsigned int FHardwareTexture::Bind(int texunit, int translation, bool alphatexture)
{ {
unsigned int * pTexID=GetTexID(cm, translation); if (alphatexture) translation = TRANS_Alpha;
unsigned int * pTexID=GetTexID(translation);
if (*pTexID!=0) if (*pTexID!=0)
{ {
@ -461,7 +442,7 @@ void FHardwareTexture::BindToFrameBuffer()
{ {
if (gl.flags & RFL_FRAMEBUFFER) if (gl.flags & RFL_FRAMEBUFFER)
{ {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glTexID[0], 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glDefTexID, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer()); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer());
} }
} }
@ -472,15 +453,13 @@ void FHardwareTexture::BindToFrameBuffer()
// (re-)creates the texture // (re-)creates the texture
// //
//=========================================================================== //===========================================================================
unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, bool wrap, int texunit, unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, bool wrap, int texunit, int translation, bool alphatexture)
int cm, int translation)
{ {
if (cm < 0 || cm >= CM_MAXCOLORMAP) cm=CM_DEFAULT; if (alphatexture) translation = TRANS_Alpha;
unsigned int * pTexID=GetTexID(translation);
unsigned int * pTexID=GetTexID(cm, translation);
if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit); if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit);
LoadImage(buffer, w, h, *pTexID, wrap? GL_REPEAT:GL_CLAMP, cm==CM_SHADE, texunit); LoadImage(buffer, w, h, *pTexID, wrap? GL_REPEAT:GL_CLAMP, alphatexture, texunit);
if (texunit != 0) glActiveTexture(GL_TEXTURE0); if (texunit != 0) glActiveTexture(GL_TEXTURE0);
return *pTexID; return *pTexID;
} }

View file

@ -10,6 +10,17 @@
class FCanvasTexture; class FCanvasTexture;
class AActor; class AActor;
// For error catching while changing parameters.
enum EInvalid
{
Invalid = 0
};
enum ETranslation
{
TRANS_Alpha = INT_MAX
};
enum enum
{ {
GLT_CLAMPX=1, GLT_CLAMPX=1,
@ -27,7 +38,7 @@ class FHardwareTexture
{ {
unsigned int glTexID; unsigned int glTexID;
int translation; int translation;
int cm; //int cm;
}; };
public: public:
@ -48,12 +59,12 @@ private:
bool forcenofiltering; bool forcenofiltering;
bool forcenocompression; bool forcenocompression;
unsigned int * glTexID; unsigned glDefTexID;
TArray<TranslatedTexture> glTexID_Translated; TArray<TranslatedTexture> glTexID_Translated;
unsigned int glDepthID; // only used by camera textures unsigned int glDepthID; // only used by camera textures
void LoadImage(unsigned char * buffer,int w, int h, unsigned int & glTexID,int wrapparam, bool alphatexture, int texunit); void LoadImage(unsigned char * buffer,int w, int h, unsigned int & glTexID,int wrapparam, bool alphatexture, int texunit);
unsigned * GetTexID(int cm, int translation); unsigned * GetTexID(int translation);
int GetDepthBuffer(); int GetDepthBuffer();
void DeleteTexture(unsigned int texid); void DeleteTexture(unsigned int texid);
@ -68,8 +79,8 @@ public:
void BindToFrameBuffer(); void BindToFrameBuffer();
unsigned int Bind(int texunit, int cm, int translation=0); unsigned int Bind(int texunit, int translation=0, bool alphatexture = false);
unsigned int CreateTexture(unsigned char * buffer, int w, int h,bool wrap, int texunit, int cm, int translation=0); unsigned int CreateTexture(unsigned char * buffer, int w, int h,bool wrap, int texunit, int translation=0, bool alphatexture = false);
void Resize(int _width, int _height) ; void Resize(int _width, int _height) ;
void Clean(bool all); void Clean(bool all);

View file

@ -109,7 +109,7 @@ FGLTexture::~FGLTexture()
// Checks for the presence of a hires texture replacement and loads it // Checks for the presence of a hires texture replacement and loads it
// //
//========================================================================== //==========================================================================
unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *height, int cm) unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *height, bool alphatexture)
{ {
if (HiresLump==-1) if (HiresLump==-1)
{ {
@ -131,7 +131,7 @@ unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *heig
memset(buffer, 0, w * (h+1) * 4); memset(buffer, 0, w * (h+1) * 4);
FGLBitmap bmp(buffer, w*4, w, h); FGLBitmap bmp(buffer, w*4, w, h);
bmp.SetTranslationInfo(cm); if (alphatexture) bmp.SetAlphaTex();
int trans = hirestexture->CopyTrueColorPixels(&bmp, 0, 0); int trans = hirestexture->CopyTrueColorPixels(&bmp, 0, 0);
@ -271,7 +271,7 @@ BYTE *FGLTexture::WarpBuffer(BYTE *buffer, int Width, int Height, int warp)
// //
//=========================================================================== //===========================================================================
unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, int & h, bool expand, FTexture *hirescheck, int warp) unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, bool expand, FTexture *hirescheck, int warp, bool alphatexture)
{ {
unsigned char * buffer; unsigned char * buffer;
int W, H; int W, H;
@ -281,7 +281,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, in
// by hires textures // by hires textures
if (gl_texture_usehires && hirescheck != NULL) if (gl_texture_usehires && hirescheck != NULL)
{ {
buffer = LoadHiresTexture (hirescheck, &w, &h, cm); buffer = LoadHiresTexture (hirescheck, &w, &h, alphatexture);
if (buffer) if (buffer)
{ {
return buffer; return buffer;
@ -296,7 +296,8 @@ unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, in
memset(buffer, 0, W * (H+1) * 4); memset(buffer, 0, W * (H+1) * 4);
FGLBitmap bmp(buffer, W*4, W, H); FGLBitmap bmp(buffer, W*4, W, H);
bmp.SetTranslationInfo(cm, translation); bmp.SetTranslationInfo(translation);
if (alphatexture) bmp.SetAlphaTex();
if (tex->bComplex) if (tex->bComplex)
{ {
@ -337,7 +338,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, in
else //if (bIsTransparent != 1) else //if (bIsTransparent != 1)
{ {
// [BB] Potentially upsample the buffer. // [BB] Potentially upsample the buffer.
buffer = gl_CreateUpsampledTextureBuffer ( tex, buffer, W, H, w, h, bIsTransparent || cm == CM_SHADE ); buffer = gl_CreateUpsampledTextureBuffer ( tex, buffer, W, H, w, h, bIsTransparent || alphatexture);
} }
currentwarp = warp; currentwarp = warp;
currentwarptime = gl_frameMS; currentwarptime = gl_frameMS;
@ -386,7 +387,7 @@ bool FGLTexture::CreatePatch()
// //
//=========================================================================== //===========================================================================
const FHardwareTexture *FGLTexture::Bind(int texunit, int cm, int clampmode, int translation, FTexture *hirescheck, int warp) const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, FTexture *hirescheck, int warp)
{ {
int usebright = false; int usebright = false;
@ -400,7 +401,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int cm, int clampmode, int
hwtex = gltexture[clampmode] = gltexture[4]; hwtex = gltexture[clampmode] = gltexture[4];
gltexture[4] = NULL; gltexture[4] = NULL;
if (hwtex->Bind(texunit, cm, translation)) if (hwtex->Bind(texunit, translation))
{ {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (clampmode & GLT_CLAMPX)? GL_CLAMP_TO_EDGE : GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (clampmode & GLT_CLAMPX)? GL_CLAMP_TO_EDGE : GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (clampmode & GLT_CLAMPY)? GL_CLAMP_TO_EDGE : GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (clampmode & GLT_CLAMPY)? GL_CLAMP_TO_EDGE : GL_REPEAT);
@ -428,7 +429,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int cm, int clampmode, int
} }
// Bind it to the system. // Bind it to the system.
if (!hwtex->Bind(texunit, cm, translation)) if (!hwtex->Bind(texunit, translation))
{ {
int w=0, h=0; int w=0, h=0;
@ -438,10 +439,10 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int cm, int clampmode, int
if (!tex->bHasCanvas) if (!tex->bHasCanvas)
{ {
buffer = CreateTexBuffer(cm, translation, w, h, false, hirescheck, warp); buffer = CreateTexBuffer(translation, w, h, false, hirescheck, warp);
tex->ProcessData(buffer, w, h, false); tex->ProcessData(buffer, w, h, false);
} }
if (!hwtex->CreateTexture(buffer, w, h, true, texunit, cm, translation)) if (!hwtex->CreateTexture(buffer, w, h, true, texunit, translation))
{ {
// could not create texture // could not create texture
delete[] buffer; delete[] buffer;
@ -463,7 +464,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int cm, int clampmode, int
// Binds a sprite to the renderer // Binds a sprite to the renderer
// //
//=========================================================================== //===========================================================================
const FHardwareTexture * FGLTexture::BindPatch(int texunit, int cm, int translation, int warp) const FHardwareTexture * FGLTexture::BindPatch(int texunit, int translation, int warp, bool alphatexture)
{ {
bool usebright = false; bool usebright = false;
int transparm = translation; int transparm = translation;
@ -489,14 +490,14 @@ const FHardwareTexture * FGLTexture::BindPatch(int texunit, int cm, int translat
// Bind it to the system. // Bind it to the system.
if (!glpatch->Bind(texunit, cm, translation)) if (!glpatch->Bind(texunit, translation, alphatexture))
{ {
int w, h; int w, h;
// Create this texture // Create this texture
unsigned char * buffer = CreateTexBuffer(cm, translation, w, h, bExpand, NULL, warp); unsigned char * buffer = CreateTexBuffer(translation, w, h, bExpand, NULL, warp, alphatexture);
tex->ProcessData(buffer, w, h, true); tex->ProcessData(buffer, w, h, true);
if (!glpatch->CreateTexture(buffer, w, h, false, texunit, cm, translation)) if (!glpatch->CreateTexture(buffer, w, h, false, texunit, translation, alphatexture))
{ {
// could not create texture // could not create texture
delete[] buffer; delete[] buffer;
@ -755,7 +756,7 @@ bool FMaterial::TrimBorders(int *rect)
int w; int w;
int h; int h;
unsigned char *buffer = CreateTexBuffer(CM_DEFAULT, 0, w, h); unsigned char *buffer = CreateTexBuffer(0, w, h);
if (buffer == NULL) if (buffer == NULL)
{ {
@ -847,7 +848,7 @@ void FMaterial::Bind(int cm, int clampmode, int translation, int overrideshader)
else if (clampmode != -1) clampmode &= 3; else if (clampmode != -1) clampmode &= 3;
else clampmode = 4; else clampmode = 4;
const FHardwareTexture *gltexture = mBaseLayer->Bind(0, cm, clampmode, translation, allowhires? tex:NULL, softwarewarp); const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, allowhires? tex:NULL, softwarewarp);
if (gltexture != NULL && shaderindex > 0 && overrideshader == 0) if (gltexture != NULL && shaderindex > 0 && overrideshader == 0)
{ {
for(unsigned i=0;i<mTextureLayers.Size();i++) for(unsigned i=0;i<mTextureLayers.Size();i++)
@ -863,7 +864,7 @@ void FMaterial::Bind(int cm, int clampmode, int translation, int overrideshader)
{ {
layer = mTextureLayers[i].texture; layer = mTextureLayers[i].texture;
} }
layer->gl_info.SystemTexture->Bind(i+1, CM_DEFAULT, clampmode, 0, NULL, false); layer->gl_info.SystemTexture->Bind(i+1, clampmode, 0, NULL, false);
maxbound = i+1; maxbound = i+1;
} }
} }
@ -890,11 +891,11 @@ void FMaterial::BindPatch(int cm, int translation, int overrideshader)
int softwarewarp = gl_RenderState.SetupShader(tex->bHasCanvas, shaderindex, cm, tex->gl_info.shaderspeed); int softwarewarp = gl_RenderState.SetupShader(tex->bHasCanvas, shaderindex, cm, tex->gl_info.shaderspeed);
const FHardwareTexture *glpatch = mBaseLayer->BindPatch(0, cm, translation, softwarewarp); const FHardwareTexture *glpatch = mBaseLayer->BindPatch(0, translation, softwarewarp, gl.needAlphaTexture);
// The only multitexture effect usable on sprites is the brightmap. // The only multitexture effect usable on sprites is the brightmap.
if (glpatch != NULL && shaderindex == 3) if (glpatch != NULL && shaderindex == 3)
{ {
mTextureLayers[0].texture->gl_info.SystemTexture->BindPatch(1, CM_DEFAULT, 0, 0); mTextureLayers[0].texture->gl_info.SystemTexture->BindPatch(1, 0, 0, false);
maxbound = 1; maxbound = 1;
} }
// unbind everything from the last texture that's still active // unbind everything from the last texture that's still active
@ -1012,7 +1013,7 @@ void FMaterial::BindToFrameBuffer()
if (mBaseLayer->gltexture == NULL) if (mBaseLayer->gltexture == NULL)
{ {
// must create the hardware texture first // must create the hardware texture first
mBaseLayer->Bind(0, CM_DEFAULT, 0, 0, NULL, 0); mBaseLayer->Bind(0, 0, 0, NULL, 0);
FHardwareTexture::Unbind(0); FHardwareTexture::Unbind(0);
} }
mBaseLayer->gltexture[0]->BindToFrameBuffer(); mBaseLayer->gltexture[0]->BindToFrameBuffer();

View file

@ -48,7 +48,7 @@ enum ETexUse
}; };
class FGLTexture //: protected WorldTextureInfo, protected PatchTextureInfo class FGLTexture
{ {
friend class FMaterial; friend class FMaterial;
public: public:
@ -68,21 +68,21 @@ private:
bool bExpand; bool bExpand;
float AlphaThreshold; float AlphaThreshold;
unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height, int cm); unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height, bool alphatexture);
BYTE *WarpBuffer(BYTE *buffer, int Width, int Height, int warp); BYTE *WarpBuffer(BYTE *buffer, int Width, int Height, int warp);
FHardwareTexture *CreateTexture(int clampmode); FHardwareTexture *CreateTexture(int clampmode);
//bool CreateTexture(); //bool CreateTexture();
bool CreatePatch(); bool CreatePatch();
const FHardwareTexture *Bind(int texunit, int cm, int clamp, int translation, FTexture *hirescheck, int warp); const FHardwareTexture *Bind(int texunit, int clamp, int translation, FTexture *hirescheck, int warp);
const FHardwareTexture *BindPatch(int texunit, int cm, int translation, int warp); const FHardwareTexture *BindPatch(int texunit, int translation, int warp, bool alphatexture);
public: public:
FGLTexture(FTexture * tx, bool expandpatches); FGLTexture(FTexture * tx, bool expandpatches);
~FGLTexture(); ~FGLTexture();
unsigned char * CreateTexBuffer(int cm, int translation, int & w, int & h, bool expand, FTexture *hirescheck, int warp); unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool expand, FTexture *hirescheck, int warp, bool alphatexture = false);
void Clean(bool all); void Clean(bool all);
int Dump(int i); int Dump(int i);
@ -138,9 +138,9 @@ public:
void Bind(int cm, int clamp = 0, int translation = 0, int overrideshader = 0); void Bind(int cm, int clamp = 0, int translation = 0, int overrideshader = 0);
void BindPatch(int cm, int translation = 0, int overrideshader = 0); void BindPatch(int cm, int translation = 0, int overrideshader = 0);
unsigned char * CreateTexBuffer(int cm, int translation, int & w, int & h, bool expand = false, bool allowhires=true) const unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool expand = false, bool allowhires=true) const
{ {
return mBaseLayer->CreateTexBuffer(cm, translation, w, h, expand, allowhires? tex:NULL, 0); return mBaseLayer->CreateTexBuffer(translation, w, h, expand, allowhires? tex:NULL, 0);
} }
void Clean(bool f) void Clean(bool f)
@ -233,7 +233,7 @@ public:
if (!mBaseLayer->tex->bHasCanvas) if (!mBaseLayer->tex->bHasCanvas)
{ {
int w, h; int w, h;
unsigned char *buffer = CreateTexBuffer(CM_DEFAULT, 0, w, h); unsigned char *buffer = CreateTexBuffer(0, w, h);
delete [] buffer; delete [] buffer;
} }
else else