2008-01-27 11:25:03 +00:00
|
|
|
/*
|
|
|
|
** gltexture.cpp
|
|
|
|
** The texture classes for hardware rendering
|
|
|
|
** (Even though they are named 'gl' there is nothing hardware dependent
|
|
|
|
** in this file. That is all encapsulated in the GLTexture class.)
|
|
|
|
**
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
** Copyright 2004-2005 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.
|
|
|
|
** 4. When not used as part of GZDoom or a GZDoom derivative, this code will be
|
|
|
|
** covered by the terms of the GNU Lesser General Public License as published
|
|
|
|
** by the Free Software Foundation; either version 2.1 of the License, or (at
|
|
|
|
** your option) any later version.
|
|
|
|
**
|
|
|
|
** 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.
|
|
|
|
**---------------------------------------------------------------------------
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
|
2008-03-21 21:15:56 +00:00
|
|
|
#include "gl/gl_include.h"
|
2008-01-27 11:25:03 +00:00
|
|
|
#include "w_wad.h"
|
|
|
|
#include "m_png.h"
|
|
|
|
#include "r_draw.h"
|
|
|
|
#include "sbar.h"
|
|
|
|
#include "gi.h"
|
|
|
|
#include "cmdlib.h"
|
|
|
|
#include "stats.h"
|
|
|
|
#include "templates.h"
|
|
|
|
#include "sc_man.h"
|
2008-04-17 20:58:50 +00:00
|
|
|
#include "r_translate.h"
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
#include "gl/gl_struct.h"
|
|
|
|
#include "gl/gl_framebuffer.h"
|
|
|
|
#include "gl/gl_texture.h"
|
|
|
|
#include "gl/gl_functions.h"
|
|
|
|
#include "gl/gl_shader.h"
|
|
|
|
#include "gl/gl_translate.h"
|
|
|
|
|
|
|
|
CUSTOM_CVAR(Bool, gl_warp_shader, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
|
|
|
{
|
|
|
|
if (self && !(gl.flags & RFL_GLSL)) self=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CUSTOM_CVAR(Bool, gl_colormap_shader, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
|
|
|
{
|
|
|
|
if (self && !(gl.flags & RFL_GLSL)) self=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
CUSTOM_CVAR(Bool, gl_brightmap_shader, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
|
|
|
{
|
|
|
|
if (self && !(gl.flags & RFL_GLSL)) self=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Only for testing for now. This isn't working fully yet.
|
|
|
|
CUSTOM_CVAR(Bool, gl_glsl_renderer, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
|
|
|
{
|
|
|
|
if (!(gl.flags & RFL_GLSL))
|
|
|
|
{
|
|
|
|
if (self) self=0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GLShader::Unbind();
|
|
|
|
FGLTexture::FlushAll();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CUSTOM_CVAR(Bool, gl_texture_usehires, true, CVAR_ARCHIVE|CVAR_NOINITCALL)
|
|
|
|
{
|
|
|
|
FGLTexture::FlushAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
EXTERN_CVAR(Bool, gl_render_precise)
|
|
|
|
|
|
|
|
CVAR(Bool, gl_precache, false, CVAR_ARCHIVE)
|
|
|
|
|
|
|
|
static bool HasGlobalBrightmap;
|
2008-04-17 20:58:50 +00:00
|
|
|
static FRemapTable GlobalBrightmap;
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Examines the colormap to see if some of the colors have to be
|
|
|
|
// considered fullbright all the time.
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
|
|
|
|
void gl_GenerateGlobalBrightmapFromColormap()
|
|
|
|
{
|
|
|
|
FMemLump cmap = Wads.ReadLump("COLORMAP");
|
|
|
|
FMemLump palette = Wads.ReadLump("PLAYPAL");
|
|
|
|
const unsigned char *cmapdata = (const unsigned char *)cmap.GetMem();
|
|
|
|
const unsigned char *paldata = (const unsigned char *)palette.GetMem();
|
|
|
|
|
2008-04-17 20:58:50 +00:00
|
|
|
const int black = 0;
|
|
|
|
const int white = ColorMatcher.Pick(255,255,255);
|
|
|
|
|
|
|
|
|
|
|
|
GlobalBrightmap.MakeIdentity();
|
|
|
|
memset(GlobalBrightmap.Remap, white, 256);
|
|
|
|
for(int i=0;i<256;i++) GlobalBrightmap.Palette[i]=PalEntry(255,255,255);
|
2008-01-27 11:25:03 +00:00
|
|
|
for(int j=0;j<32;j++)
|
|
|
|
{
|
|
|
|
for(int i=0;i<256;i++)
|
|
|
|
{
|
|
|
|
// the palette comparison should be for ==0 but that gives false positives with Heretic
|
|
|
|
// and Hexen.
|
|
|
|
if (cmapdata[i+j*256]!=i || (paldata[3*i]<10 && paldata[3*i+1]<10 && paldata[3*i+2]<10))
|
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
GlobalBrightmap.Remap[i]=black;
|
|
|
|
GlobalBrightmap.Palette[i]=PalEntry(0,0,0);
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(int i=0;i<256;i++)
|
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
HasGlobalBrightmap |= GlobalBrightmap.Remap[i] == black;
|
2008-01-27 11:25:03 +00:00
|
|
|
//if (GlobalBrightmap[i]) Printf("Marked color %d as fullbright\n",i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// multi-format pixel copy with colormap application
|
|
|
|
// requires one of the previously defined conversion classes to work
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
template<class T>
|
|
|
|
void iCopyColors(unsigned char * pout, const unsigned char * pin, int cm, int count, int step)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int fac;
|
|
|
|
|
|
|
|
switch(cm)
|
|
|
|
{
|
|
|
|
case CM_DEFAULT:
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
pout[0]=T::R(pin);
|
|
|
|
pout[1]=T::G(pin);
|
|
|
|
pout[2]=T::B(pin);
|
|
|
|
pout[3]=T::A(pin);
|
|
|
|
pout+=4;
|
|
|
|
pin+=step;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CM_INVERT:
|
|
|
|
// Doom's inverted invulnerability map
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
gl_InverseMap(T::Gray(pin), pout[0], pout[1], pout[2]);
|
|
|
|
pout[3] = T::A(pin);
|
|
|
|
pout+=4;
|
|
|
|
pin+=step;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CM_GOLDMAP:
|
|
|
|
// Heretic's golden invulnerability map
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
gl_GoldMap(T::Gray(pin), pout[0], pout[1], pout[2]);
|
|
|
|
pout[3] = T::A(pin);
|
|
|
|
pout+=4;
|
|
|
|
pin+=step;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CM_REDMAP:
|
|
|
|
// Skulltag's red Doomsphere map
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
gl_RedMap(T::Gray(pin), pout[0], pout[1], pout[2]);
|
|
|
|
pout[3] = T::A(pin);
|
|
|
|
pout+=4;
|
|
|
|
pin+=step;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CM_GREENMAP:
|
|
|
|
// Skulltags's Guardsphere map
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
gl_GreenMap(T::Gray(pin), pout[0], pout[1], pout[2]);
|
|
|
|
pout[3] = T::A(pin);
|
|
|
|
pout+=4;
|
|
|
|
pin+=step;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CM_GRAY:
|
|
|
|
// this is used for colorization of blood.
|
|
|
|
// To get the best results the brightness is taken from
|
|
|
|
// the most intense component and not averaged because that would be too dark.
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
pout[0] = pout[1] = pout[2] = MAX(MAX(T::R(pin), T::G(pin)), T::B(pin));
|
|
|
|
pout[3] = T::A(pin);
|
|
|
|
pout+=4;
|
|
|
|
pin+=step;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CM_ICE:
|
|
|
|
// Create the ice translation table, based on Hexen's.
|
|
|
|
// Since this is done in True Color the purplish tint is fully preserved - even in Doom!
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
int gray = T::Gray(pin)>>4;
|
|
|
|
|
|
|
|
pout[0] = IcePalette[gray][0];
|
|
|
|
pout[1] = IcePalette[gray][1];
|
|
|
|
pout[2] = IcePalette[gray][2];
|
|
|
|
pout[3] = 255;
|
|
|
|
pout+=4;
|
|
|
|
pin+=step;
|
|
|
|
}
|
|
|
|
break;
|
2008-01-27 15:34:47 +00:00
|
|
|
|
|
|
|
case CM_SHADE:
|
|
|
|
// Alpha shade uses the red channel for true color pics
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
pout[0] = pout[1] = pout[2] = 255;
|
|
|
|
pout[3] = T::R(pin);
|
|
|
|
pout+=4;
|
|
|
|
pin+=step;
|
|
|
|
}
|
|
|
|
break;
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
if (cm<=CM_DESAT31)
|
|
|
|
{
|
|
|
|
// Desaturated light settings.
|
|
|
|
fac=cm-CM_DESAT0;
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef void (*CopyFunc)(unsigned char * pout, const unsigned char * pin, int cm, int count, int step);
|
|
|
|
|
|
|
|
static CopyFunc copyfuncs[]={
|
|
|
|
iCopyColors<cRGB>,
|
|
|
|
iCopyColors<cRGBA>,
|
|
|
|
iCopyColors<cIA>,
|
|
|
|
iCopyColors<cCMYK>,
|
|
|
|
iCopyColors<cBGR>,
|
|
|
|
iCopyColors<cBGRA>,
|
|
|
|
iCopyColors<cI16>,
|
|
|
|
iCopyColors<cRGB555>,
|
|
|
|
iCopyColors<cPalEntry>
|
|
|
|
};
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// True Color texture copy function
|
|
|
|
// This excludes all the cases that force downconversion to the
|
|
|
|
// base palette because they wouldn't be used anyway.
|
|
|
|
//
|
|
|
|
//===========================================================================
|
2008-04-17 20:58:50 +00:00
|
|
|
void FGLBitmap::CopyPixelDataRGB(int originx, int originy,
|
|
|
|
const BYTE * patch, int srcwidth, int srcheight, int step_x, int step_y,
|
|
|
|
int rotate, int ct, FCopyInfo *inf)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
if (ClipCopyPixelRect(Width, Height, originx, originy, patch, srcwidth, srcheight, step_x, step_y, rotate))
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
BYTE *buffer = GetPixels() + 4*originx + Pitch*originy;
|
2008-01-27 11:25:03 +00:00
|
|
|
for (int y=0;y<srcheight;y++)
|
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
copyfuncs[ct](&buffer[y*Pitch], &patch[y*step_y], cm, srcwidth, step_x);
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// 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;
|
|
|
|
|
|
|
|
switch(cm)
|
|
|
|
{
|
|
|
|
case CM_DEFAULT:
|
|
|
|
if (pin != pout)
|
|
|
|
memcpy(pout, pin, count * sizeof(PalEntry));
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CM_INVERT:
|
|
|
|
// Doom's inverted invulnerability map
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
int gray = (pin[i].r*77 + pin[i].g*143 + pin[i].b*37) >> 8;
|
|
|
|
gl_InverseMap(gray, pout[i].r, pout[i].g, pout[i].b);
|
- Fixed: Fog for flooding floor textures into gaps created by missing wall textures
didn't work since a parameter changes necessitated by ZDoom's render style 'enhancement'.
Update to ZDoom r940:
SBarInfo Update #18:
- Simplified the DrawGraphic function in sbarinfo_display.cpp
- Added xOffset, yOffset, and alpha to every drawing function in
sbarinfo_display.cpp. So Strife popups can be handeled better and allow for
other effects (translucent bars?). I'm thinking about making a struct for
these five (also x and y) arguments so that the argument lists don't become a
mess.
- Changed DRAWIMAGE in sbarinfo_display.cpp to not use so many calls to
DrawGraphic.
- DrawKeyBar wasn't using screen->DrawTexture.
- Added a Fade transition for popups. It takes two args fade in rate and fade
out rate. Both are floats (1.0 = 1 tic to complete 0.5 = 2 tics to complete
and so on).
- Added a translucency arg to statusbars. 1.0 = opaque and 0.0 = invisible.
- Fixed: When an instrument's envelope runs out, it does not immediately ramp
to zero. Rather, it lets the remainder of the sample finish playing.
- Fixed: When playing a MIDI file with EMIDI track designations to turn a
track off, any ticks that had only events on the disabled track would cause
the delay for that track to be thrown away, and the following notes on
enabled tracks would play too soon. This could be heard quite clearly in
xplasma.mid, where track 4 (FMGlass Drone 1) would interfere with the timing
of tracks 13 and 14 (EP1 Melody and EP1 Echo).
- Fixed: DFlashFader did some operations in its destructor that had to be moved
to its Destroy method.
- Fixed: Dropped weapons from dying players should not double ammo.
- Fixed: When note_on() is called and another copy of the same note is
already playing on the channel, it should stop it with finish_note(), not
kill_note(). This can be clearly heard in the final cymbal crashes of
D_DM2TTL where TiMidity cuts them off because the final cymbals are played
with a velocity of 1 before the preceding cymbals have finished. (I wonder
if I should be setting the self_nonexclusive flag for GUS patches to
disable even this behavior, though, since gf1note.c doesn't turn off
duplicate notes.)
- Changed envelope handling to hopefully match the GUS player's. The most
egregious mistake TiMidity makes is to treat bit 6 as an envelope enable
bit. This is not what it does; every sample has an envelope. Rather, this
is a "no sampled release" flag. Also, despite fiddling with the
PATCH_SUSTAIN flag during instrument loading, TiMidity never actually
used it. Nor did it do anything at all with the PATCH_FAST_REL flag.
- Fixed: wbstartstruct's lump name fields were only 8 characters long
and not properly zero-terminated when all 8 characters were used.
- Fixed: Local sound sequence definitions caused a crash because a proper
NULL check was missing.
- Added translucent blending modes to FMultipatchTexture (not tested yet!)
- Also changed all true color texture creation functions to use proper alpha
values instead of inverted ones.
- Changed FRemapTable so that all palette entries must contain proper alpha
values.
- Fixed: The F1 screen check in m_menu.cpp was missing a NULL pointer check.
- Changed: The boss brain's explosions play weapons/rocklx which is an
unlimited sound. This can become extremely loud. Replaced with a new
sound which is just an alias to weapons/rocklx but has a limit of 4.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@98 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-25 10:00:54 +00:00
|
|
|
pout[i].a = pin[i].a;
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CM_GOLDMAP:
|
|
|
|
// Heretic's golden invulnerability map
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
int gray = (pin[i].r*77 + pin[i].g*143 + pin[i].b*37) >> 8;
|
|
|
|
gl_GoldMap(gray, pout[i].r, pout[i].g, pout[i].b);
|
- Fixed: Fog for flooding floor textures into gaps created by missing wall textures
didn't work since a parameter changes necessitated by ZDoom's render style 'enhancement'.
Update to ZDoom r940:
SBarInfo Update #18:
- Simplified the DrawGraphic function in sbarinfo_display.cpp
- Added xOffset, yOffset, and alpha to every drawing function in
sbarinfo_display.cpp. So Strife popups can be handeled better and allow for
other effects (translucent bars?). I'm thinking about making a struct for
these five (also x and y) arguments so that the argument lists don't become a
mess.
- Changed DRAWIMAGE in sbarinfo_display.cpp to not use so many calls to
DrawGraphic.
- DrawKeyBar wasn't using screen->DrawTexture.
- Added a Fade transition for popups. It takes two args fade in rate and fade
out rate. Both are floats (1.0 = 1 tic to complete 0.5 = 2 tics to complete
and so on).
- Added a translucency arg to statusbars. 1.0 = opaque and 0.0 = invisible.
- Fixed: When an instrument's envelope runs out, it does not immediately ramp
to zero. Rather, it lets the remainder of the sample finish playing.
- Fixed: When playing a MIDI file with EMIDI track designations to turn a
track off, any ticks that had only events on the disabled track would cause
the delay for that track to be thrown away, and the following notes on
enabled tracks would play too soon. This could be heard quite clearly in
xplasma.mid, where track 4 (FMGlass Drone 1) would interfere with the timing
of tracks 13 and 14 (EP1 Melody and EP1 Echo).
- Fixed: DFlashFader did some operations in its destructor that had to be moved
to its Destroy method.
- Fixed: Dropped weapons from dying players should not double ammo.
- Fixed: When note_on() is called and another copy of the same note is
already playing on the channel, it should stop it with finish_note(), not
kill_note(). This can be clearly heard in the final cymbal crashes of
D_DM2TTL where TiMidity cuts them off because the final cymbals are played
with a velocity of 1 before the preceding cymbals have finished. (I wonder
if I should be setting the self_nonexclusive flag for GUS patches to
disable even this behavior, though, since gf1note.c doesn't turn off
duplicate notes.)
- Changed envelope handling to hopefully match the GUS player's. The most
egregious mistake TiMidity makes is to treat bit 6 as an envelope enable
bit. This is not what it does; every sample has an envelope. Rather, this
is a "no sampled release" flag. Also, despite fiddling with the
PATCH_SUSTAIN flag during instrument loading, TiMidity never actually
used it. Nor did it do anything at all with the PATCH_FAST_REL flag.
- Fixed: wbstartstruct's lump name fields were only 8 characters long
and not properly zero-terminated when all 8 characters were used.
- Fixed: Local sound sequence definitions caused a crash because a proper
NULL check was missing.
- Added translucent blending modes to FMultipatchTexture (not tested yet!)
- Also changed all true color texture creation functions to use proper alpha
values instead of inverted ones.
- Changed FRemapTable so that all palette entries must contain proper alpha
values.
- Fixed: The F1 screen check in m_menu.cpp was missing a NULL pointer check.
- Changed: The boss brain's explosions play weapons/rocklx which is an
unlimited sound. This can become extremely loud. Replaced with a new
sound which is just an alias to weapons/rocklx but has a limit of 4.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@98 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-25 10:00:54 +00:00
|
|
|
pout[i].a = pin[i].a;
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CM_REDMAP:
|
|
|
|
// Skulltag's red Doomsphere map
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
int gray = (pin[i].r*77 + pin[i].g*143 + pin[i].b*37) >> 8;
|
|
|
|
gl_RedMap(gray, pout[i].r, pout[i].g, pout[i].b);
|
- Fixed: Fog for flooding floor textures into gaps created by missing wall textures
didn't work since a parameter changes necessitated by ZDoom's render style 'enhancement'.
Update to ZDoom r940:
SBarInfo Update #18:
- Simplified the DrawGraphic function in sbarinfo_display.cpp
- Added xOffset, yOffset, and alpha to every drawing function in
sbarinfo_display.cpp. So Strife popups can be handeled better and allow for
other effects (translucent bars?). I'm thinking about making a struct for
these five (also x and y) arguments so that the argument lists don't become a
mess.
- Changed DRAWIMAGE in sbarinfo_display.cpp to not use so many calls to
DrawGraphic.
- DrawKeyBar wasn't using screen->DrawTexture.
- Added a Fade transition for popups. It takes two args fade in rate and fade
out rate. Both are floats (1.0 = 1 tic to complete 0.5 = 2 tics to complete
and so on).
- Added a translucency arg to statusbars. 1.0 = opaque and 0.0 = invisible.
- Fixed: When an instrument's envelope runs out, it does not immediately ramp
to zero. Rather, it lets the remainder of the sample finish playing.
- Fixed: When playing a MIDI file with EMIDI track designations to turn a
track off, any ticks that had only events on the disabled track would cause
the delay for that track to be thrown away, and the following notes on
enabled tracks would play too soon. This could be heard quite clearly in
xplasma.mid, where track 4 (FMGlass Drone 1) would interfere with the timing
of tracks 13 and 14 (EP1 Melody and EP1 Echo).
- Fixed: DFlashFader did some operations in its destructor that had to be moved
to its Destroy method.
- Fixed: Dropped weapons from dying players should not double ammo.
- Fixed: When note_on() is called and another copy of the same note is
already playing on the channel, it should stop it with finish_note(), not
kill_note(). This can be clearly heard in the final cymbal crashes of
D_DM2TTL where TiMidity cuts them off because the final cymbals are played
with a velocity of 1 before the preceding cymbals have finished. (I wonder
if I should be setting the self_nonexclusive flag for GUS patches to
disable even this behavior, though, since gf1note.c doesn't turn off
duplicate notes.)
- Changed envelope handling to hopefully match the GUS player's. The most
egregious mistake TiMidity makes is to treat bit 6 as an envelope enable
bit. This is not what it does; every sample has an envelope. Rather, this
is a "no sampled release" flag. Also, despite fiddling with the
PATCH_SUSTAIN flag during instrument loading, TiMidity never actually
used it. Nor did it do anything at all with the PATCH_FAST_REL flag.
- Fixed: wbstartstruct's lump name fields were only 8 characters long
and not properly zero-terminated when all 8 characters were used.
- Fixed: Local sound sequence definitions caused a crash because a proper
NULL check was missing.
- Added translucent blending modes to FMultipatchTexture (not tested yet!)
- Also changed all true color texture creation functions to use proper alpha
values instead of inverted ones.
- Changed FRemapTable so that all palette entries must contain proper alpha
values.
- Fixed: The F1 screen check in m_menu.cpp was missing a NULL pointer check.
- Changed: The boss brain's explosions play weapons/rocklx which is an
unlimited sound. This can become extremely loud. Replaced with a new
sound which is just an alias to weapons/rocklx but has a limit of 4.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@98 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-25 10:00:54 +00:00
|
|
|
pout[i].a = pin[i].a;
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CM_GREENMAP:
|
|
|
|
// Skulltags's Guardsphere map
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
int gray = (pin[i].r*77 + pin[i].g*143 + pin[i].b*37) >> 8;
|
|
|
|
gl_GreenMap(gray, pout[i].r, pout[i].g, pout[i].b);
|
- Fixed: Fog for flooding floor textures into gaps created by missing wall textures
didn't work since a parameter changes necessitated by ZDoom's render style 'enhancement'.
Update to ZDoom r940:
SBarInfo Update #18:
- Simplified the DrawGraphic function in sbarinfo_display.cpp
- Added xOffset, yOffset, and alpha to every drawing function in
sbarinfo_display.cpp. So Strife popups can be handeled better and allow for
other effects (translucent bars?). I'm thinking about making a struct for
these five (also x and y) arguments so that the argument lists don't become a
mess.
- Changed DRAWIMAGE in sbarinfo_display.cpp to not use so many calls to
DrawGraphic.
- DrawKeyBar wasn't using screen->DrawTexture.
- Added a Fade transition for popups. It takes two args fade in rate and fade
out rate. Both are floats (1.0 = 1 tic to complete 0.5 = 2 tics to complete
and so on).
- Added a translucency arg to statusbars. 1.0 = opaque and 0.0 = invisible.
- Fixed: When an instrument's envelope runs out, it does not immediately ramp
to zero. Rather, it lets the remainder of the sample finish playing.
- Fixed: When playing a MIDI file with EMIDI track designations to turn a
track off, any ticks that had only events on the disabled track would cause
the delay for that track to be thrown away, and the following notes on
enabled tracks would play too soon. This could be heard quite clearly in
xplasma.mid, where track 4 (FMGlass Drone 1) would interfere with the timing
of tracks 13 and 14 (EP1 Melody and EP1 Echo).
- Fixed: DFlashFader did some operations in its destructor that had to be moved
to its Destroy method.
- Fixed: Dropped weapons from dying players should not double ammo.
- Fixed: When note_on() is called and another copy of the same note is
already playing on the channel, it should stop it with finish_note(), not
kill_note(). This can be clearly heard in the final cymbal crashes of
D_DM2TTL where TiMidity cuts them off because the final cymbals are played
with a velocity of 1 before the preceding cymbals have finished. (I wonder
if I should be setting the self_nonexclusive flag for GUS patches to
disable even this behavior, though, since gf1note.c doesn't turn off
duplicate notes.)
- Changed envelope handling to hopefully match the GUS player's. The most
egregious mistake TiMidity makes is to treat bit 6 as an envelope enable
bit. This is not what it does; every sample has an envelope. Rather, this
is a "no sampled release" flag. Also, despite fiddling with the
PATCH_SUSTAIN flag during instrument loading, TiMidity never actually
used it. Nor did it do anything at all with the PATCH_FAST_REL flag.
- Fixed: wbstartstruct's lump name fields were only 8 characters long
and not properly zero-terminated when all 8 characters were used.
- Fixed: Local sound sequence definitions caused a crash because a proper
NULL check was missing.
- Added translucent blending modes to FMultipatchTexture (not tested yet!)
- Also changed all true color texture creation functions to use proper alpha
values instead of inverted ones.
- Changed FRemapTable so that all palette entries must contain proper alpha
values.
- Fixed: The F1 screen check in m_menu.cpp was missing a NULL pointer check.
- Changed: The boss brain's explosions play weapons/rocklx which is an
unlimited sound. This can become extremely loud. Replaced with a new
sound which is just an alias to weapons/rocklx but has a limit of 4.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@98 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-25 10:00:54 +00:00
|
|
|
pout[i].a = pin[i].a;
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CM_GRAY:
|
|
|
|
// this is used for colorization of blood.
|
|
|
|
// To get the best results the brightness is taken from
|
|
|
|
// the most intense component and not averaged because that would be too dark.
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
pout[i].r = pout[i].g = pout[i].b = max(max(pin[i].r, pin[i].g), pin[i].b);
|
|
|
|
pout[i].a = pin[i].a;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CM_ICE:
|
|
|
|
// Create the ice translation table, based on Hexen's.
|
|
|
|
// Since this is done in True Color the purplish tint is fully preserved - even in Doom!
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
int gray=(pin[i].r*77 + pin[i].g*143 + pin[i].b*37)>>12;
|
|
|
|
|
|
|
|
pout[i].r = IcePalette[gray][0];
|
|
|
|
pout[i].g = IcePalette[gray][1];
|
|
|
|
pout[i].b = IcePalette[gray][2];
|
|
|
|
pout[i].a = pin[i].a;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
// Boom colormaps.
|
|
|
|
if (cm>=CM_FIRSTCOLORMAP && cm<CM_FIRSTCOLORMAP+numfakecmaps)
|
|
|
|
{
|
|
|
|
if (count<=256) // This does not work for raw image data because it assumes
|
|
|
|
// the use of the base palette!
|
|
|
|
{
|
|
|
|
// CreateTexBuffer has already taken care of needed palette mapping so this
|
|
|
|
// buffer is guaranteed to be in the base palette.
|
|
|
|
byte * cmapp = &realcolormaps [NUMCOLORMAPS*256*(cm - CM_FIRSTCOLORMAP)];
|
|
|
|
|
|
|
|
for(i=0;i<count;i++)
|
|
|
|
{
|
|
|
|
pout[i].r = GPalette.BaseColors[*cmapp].r;
|
|
|
|
pout[i].g = GPalette.BaseColors[*cmapp].g;
|
|
|
|
pout[i].b = GPalette.BaseColors[*cmapp].b;
|
|
|
|
pout[i].a = pin[i].a;
|
|
|
|
cmapp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (pin != pout)
|
|
|
|
{
|
|
|
|
// Boom colormaps cannot be applied to hires texture replacements.
|
|
|
|
// For those you have to set the colormap usage to 'blend'.
|
|
|
|
memcpy(pout, pin, count * sizeof(PalEntry));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Paletted to True Color texture copy function
|
|
|
|
//
|
|
|
|
//===========================================================================
|
2008-04-17 20:58:50 +00:00
|
|
|
void FGLBitmap::CopyPixelData(int originx, int originy, const BYTE * patch, int srcwidth, int srcheight,
|
|
|
|
int step_x, int step_y, int rotate, PalEntry * palette, FCopyInfo *inf)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
PalEntry penew[256];
|
|
|
|
|
|
|
|
int x,y,pos,i;
|
|
|
|
|
2008-04-17 20:58:50 +00:00
|
|
|
if (ClipCopyPixelRect(Width, Height, originx, originy, patch, srcwidth, srcheight, step_x, step_y, rotate))
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
BYTE *buffer = GetPixels() + 4*originx + Pitch*originy;
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
// CM_SHADE is an alpha map with 0==transparent and 1==opaque
|
|
|
|
if (cm == CM_SHADE)
|
|
|
|
{
|
|
|
|
for(int i=0;i<256;i++)
|
|
|
|
{
|
- Fixed: Fog for flooding floor textures into gaps created by missing wall textures
didn't work since a parameter changes necessitated by ZDoom's render style 'enhancement'.
Update to ZDoom r940:
SBarInfo Update #18:
- Simplified the DrawGraphic function in sbarinfo_display.cpp
- Added xOffset, yOffset, and alpha to every drawing function in
sbarinfo_display.cpp. So Strife popups can be handeled better and allow for
other effects (translucent bars?). I'm thinking about making a struct for
these five (also x and y) arguments so that the argument lists don't become a
mess.
- Changed DRAWIMAGE in sbarinfo_display.cpp to not use so many calls to
DrawGraphic.
- DrawKeyBar wasn't using screen->DrawTexture.
- Added a Fade transition for popups. It takes two args fade in rate and fade
out rate. Both are floats (1.0 = 1 tic to complete 0.5 = 2 tics to complete
and so on).
- Added a translucency arg to statusbars. 1.0 = opaque and 0.0 = invisible.
- Fixed: When an instrument's envelope runs out, it does not immediately ramp
to zero. Rather, it lets the remainder of the sample finish playing.
- Fixed: When playing a MIDI file with EMIDI track designations to turn a
track off, any ticks that had only events on the disabled track would cause
the delay for that track to be thrown away, and the following notes on
enabled tracks would play too soon. This could be heard quite clearly in
xplasma.mid, where track 4 (FMGlass Drone 1) would interfere with the timing
of tracks 13 and 14 (EP1 Melody and EP1 Echo).
- Fixed: DFlashFader did some operations in its destructor that had to be moved
to its Destroy method.
- Fixed: Dropped weapons from dying players should not double ammo.
- Fixed: When note_on() is called and another copy of the same note is
already playing on the channel, it should stop it with finish_note(), not
kill_note(). This can be clearly heard in the final cymbal crashes of
D_DM2TTL where TiMidity cuts them off because the final cymbals are played
with a velocity of 1 before the preceding cymbals have finished. (I wonder
if I should be setting the self_nonexclusive flag for GUS patches to
disable even this behavior, though, since gf1note.c doesn't turn off
duplicate notes.)
- Changed envelope handling to hopefully match the GUS player's. The most
egregious mistake TiMidity makes is to treat bit 6 as an envelope enable
bit. This is not what it does; every sample has an envelope. Rather, this
is a "no sampled release" flag. Also, despite fiddling with the
PATCH_SUSTAIN flag during instrument loading, TiMidity never actually
used it. Nor did it do anything at all with the PATCH_FAST_REL flag.
- Fixed: wbstartstruct's lump name fields were only 8 characters long
and not properly zero-terminated when all 8 characters were used.
- Fixed: Local sound sequence definitions caused a crash because a proper
NULL check was missing.
- Added translucent blending modes to FMultipatchTexture (not tested yet!)
- Also changed all true color texture creation functions to use proper alpha
values instead of inverted ones.
- Changed FRemapTable so that all palette entries must contain proper alpha
values.
- Fixed: The F1 screen check in m_menu.cpp was missing a NULL pointer check.
- Changed: The boss brain's explosions play weapons/rocklx which is an
unlimited sound. This can become extremely loud. Replaced with a new
sound which is just an alias to weapons/rocklx but has a limit of 4.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@98 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-25 10:00:54 +00:00
|
|
|
if (palette[i].a != 0)
|
|
|
|
penew[i]=PalEntry(255,255,255,255);
|
2008-01-27 11:25:03 +00:00
|
|
|
else
|
- Fixed: Fog for flooding floor textures into gaps created by missing wall textures
didn't work since a parameter changes necessitated by ZDoom's render style 'enhancement'.
Update to ZDoom r940:
SBarInfo Update #18:
- Simplified the DrawGraphic function in sbarinfo_display.cpp
- Added xOffset, yOffset, and alpha to every drawing function in
sbarinfo_display.cpp. So Strife popups can be handeled better and allow for
other effects (translucent bars?). I'm thinking about making a struct for
these five (also x and y) arguments so that the argument lists don't become a
mess.
- Changed DRAWIMAGE in sbarinfo_display.cpp to not use so many calls to
DrawGraphic.
- DrawKeyBar wasn't using screen->DrawTexture.
- Added a Fade transition for popups. It takes two args fade in rate and fade
out rate. Both are floats (1.0 = 1 tic to complete 0.5 = 2 tics to complete
and so on).
- Added a translucency arg to statusbars. 1.0 = opaque and 0.0 = invisible.
- Fixed: When an instrument's envelope runs out, it does not immediately ramp
to zero. Rather, it lets the remainder of the sample finish playing.
- Fixed: When playing a MIDI file with EMIDI track designations to turn a
track off, any ticks that had only events on the disabled track would cause
the delay for that track to be thrown away, and the following notes on
enabled tracks would play too soon. This could be heard quite clearly in
xplasma.mid, where track 4 (FMGlass Drone 1) would interfere with the timing
of tracks 13 and 14 (EP1 Melody and EP1 Echo).
- Fixed: DFlashFader did some operations in its destructor that had to be moved
to its Destroy method.
- Fixed: Dropped weapons from dying players should not double ammo.
- Fixed: When note_on() is called and another copy of the same note is
already playing on the channel, it should stop it with finish_note(), not
kill_note(). This can be clearly heard in the final cymbal crashes of
D_DM2TTL where TiMidity cuts them off because the final cymbals are played
with a velocity of 1 before the preceding cymbals have finished. (I wonder
if I should be setting the self_nonexclusive flag for GUS patches to
disable even this behavior, though, since gf1note.c doesn't turn off
duplicate notes.)
- Changed envelope handling to hopefully match the GUS player's. The most
egregious mistake TiMidity makes is to treat bit 6 as an envelope enable
bit. This is not what it does; every sample has an envelope. Rather, this
is a "no sampled release" flag. Also, despite fiddling with the
PATCH_SUSTAIN flag during instrument loading, TiMidity never actually
used it. Nor did it do anything at all with the PATCH_FAST_REL flag.
- Fixed: wbstartstruct's lump name fields were only 8 characters long
and not properly zero-terminated when all 8 characters were used.
- Fixed: Local sound sequence definitions caused a crash because a proper
NULL check was missing.
- Added translucent blending modes to FMultipatchTexture (not tested yet!)
- Also changed all true color texture creation functions to use proper alpha
values instead of inverted ones.
- Changed FRemapTable so that all palette entries must contain proper alpha
values.
- Fixed: The F1 screen check in m_menu.cpp was missing a NULL pointer check.
- Changed: The boss brain's explosions play weapons/rocklx which is an
unlimited sound. This can become extremely loud. Replaced with a new
sound which is just an alias to weapons/rocklx but has a limit of 4.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@98 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-25 10:00:54 +00:00
|
|
|
penew[i]=PalEntry(0,255,255,255); // If the palette contains transparent colors keep them.
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// apply any translation.
|
|
|
|
// The ice and blood color translations are done directly
|
|
|
|
// because that yields better results.
|
|
|
|
switch(translation)
|
|
|
|
{
|
|
|
|
case CM_GRAY:
|
|
|
|
ModifyPalette(penew, palette, CM_GRAY, 256);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CM_ICE:
|
|
|
|
ModifyPalette(penew, palette, CM_ICE, 256);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
PalEntry *ptrans = GLTranslationPalette::GetPalette(translation);
|
|
|
|
if (ptrans)
|
|
|
|
{
|
|
|
|
for(i = 0; i < 256; i++)
|
|
|
|
{
|
|
|
|
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.
|
|
|
|
|
|
|
|
// convert the image according to the translated palette.
|
|
|
|
// Please note that the alpha of the passed palette is inverted. This is
|
|
|
|
// so that the base palette can be used without constantly changing it.
|
|
|
|
// This can also handle full PNG translucency.
|
|
|
|
for (y=0;y<srcheight;y++)
|
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
pos=(y*Pitch);
|
2008-01-27 11:25:03 +00:00
|
|
|
for (x=0;x<srcwidth;x++,pos+=4)
|
|
|
|
{
|
|
|
|
int v=(unsigned char)patch[y*step_y+x*step_x];
|
- Fixed: Fog for flooding floor textures into gaps created by missing wall textures
didn't work since a parameter changes necessitated by ZDoom's render style 'enhancement'.
Update to ZDoom r940:
SBarInfo Update #18:
- Simplified the DrawGraphic function in sbarinfo_display.cpp
- Added xOffset, yOffset, and alpha to every drawing function in
sbarinfo_display.cpp. So Strife popups can be handeled better and allow for
other effects (translucent bars?). I'm thinking about making a struct for
these five (also x and y) arguments so that the argument lists don't become a
mess.
- Changed DRAWIMAGE in sbarinfo_display.cpp to not use so many calls to
DrawGraphic.
- DrawKeyBar wasn't using screen->DrawTexture.
- Added a Fade transition for popups. It takes two args fade in rate and fade
out rate. Both are floats (1.0 = 1 tic to complete 0.5 = 2 tics to complete
and so on).
- Added a translucency arg to statusbars. 1.0 = opaque and 0.0 = invisible.
- Fixed: When an instrument's envelope runs out, it does not immediately ramp
to zero. Rather, it lets the remainder of the sample finish playing.
- Fixed: When playing a MIDI file with EMIDI track designations to turn a
track off, any ticks that had only events on the disabled track would cause
the delay for that track to be thrown away, and the following notes on
enabled tracks would play too soon. This could be heard quite clearly in
xplasma.mid, where track 4 (FMGlass Drone 1) would interfere with the timing
of tracks 13 and 14 (EP1 Melody and EP1 Echo).
- Fixed: DFlashFader did some operations in its destructor that had to be moved
to its Destroy method.
- Fixed: Dropped weapons from dying players should not double ammo.
- Fixed: When note_on() is called and another copy of the same note is
already playing on the channel, it should stop it with finish_note(), not
kill_note(). This can be clearly heard in the final cymbal crashes of
D_DM2TTL where TiMidity cuts them off because the final cymbals are played
with a velocity of 1 before the preceding cymbals have finished. (I wonder
if I should be setting the self_nonexclusive flag for GUS patches to
disable even this behavior, though, since gf1note.c doesn't turn off
duplicate notes.)
- Changed envelope handling to hopefully match the GUS player's. The most
egregious mistake TiMidity makes is to treat bit 6 as an envelope enable
bit. This is not what it does; every sample has an envelope. Rather, this
is a "no sampled release" flag. Also, despite fiddling with the
PATCH_SUSTAIN flag during instrument loading, TiMidity never actually
used it. Nor did it do anything at all with the PATCH_FAST_REL flag.
- Fixed: wbstartstruct's lump name fields were only 8 characters long
and not properly zero-terminated when all 8 characters were used.
- Fixed: Local sound sequence definitions caused a crash because a proper
NULL check was missing.
- Added translucent blending modes to FMultipatchTexture (not tested yet!)
- Also changed all true color texture creation functions to use proper alpha
values instead of inverted ones.
- Changed FRemapTable so that all palette entries must contain proper alpha
values.
- Fixed: The F1 screen check in m_menu.cpp was missing a NULL pointer check.
- Changed: The boss brain's explosions play weapons/rocklx which is an
unlimited sound. This can become extremely loud. Replaced with a new
sound which is just an alias to weapons/rocklx but has a limit of 4.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@98 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-25 10:00:54 +00:00
|
|
|
if (penew[v].a!=0)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
- Fixed: Fog for flooding floor textures into gaps created by missing wall textures
didn't work since a parameter changes necessitated by ZDoom's render style 'enhancement'.
Update to ZDoom r940:
SBarInfo Update #18:
- Simplified the DrawGraphic function in sbarinfo_display.cpp
- Added xOffset, yOffset, and alpha to every drawing function in
sbarinfo_display.cpp. So Strife popups can be handeled better and allow for
other effects (translucent bars?). I'm thinking about making a struct for
these five (also x and y) arguments so that the argument lists don't become a
mess.
- Changed DRAWIMAGE in sbarinfo_display.cpp to not use so many calls to
DrawGraphic.
- DrawKeyBar wasn't using screen->DrawTexture.
- Added a Fade transition for popups. It takes two args fade in rate and fade
out rate. Both are floats (1.0 = 1 tic to complete 0.5 = 2 tics to complete
and so on).
- Added a translucency arg to statusbars. 1.0 = opaque and 0.0 = invisible.
- Fixed: When an instrument's envelope runs out, it does not immediately ramp
to zero. Rather, it lets the remainder of the sample finish playing.
- Fixed: When playing a MIDI file with EMIDI track designations to turn a
track off, any ticks that had only events on the disabled track would cause
the delay for that track to be thrown away, and the following notes on
enabled tracks would play too soon. This could be heard quite clearly in
xplasma.mid, where track 4 (FMGlass Drone 1) would interfere with the timing
of tracks 13 and 14 (EP1 Melody and EP1 Echo).
- Fixed: DFlashFader did some operations in its destructor that had to be moved
to its Destroy method.
- Fixed: Dropped weapons from dying players should not double ammo.
- Fixed: When note_on() is called and another copy of the same note is
already playing on the channel, it should stop it with finish_note(), not
kill_note(). This can be clearly heard in the final cymbal crashes of
D_DM2TTL where TiMidity cuts them off because the final cymbals are played
with a velocity of 1 before the preceding cymbals have finished. (I wonder
if I should be setting the self_nonexclusive flag for GUS patches to
disable even this behavior, though, since gf1note.c doesn't turn off
duplicate notes.)
- Changed envelope handling to hopefully match the GUS player's. The most
egregious mistake TiMidity makes is to treat bit 6 as an envelope enable
bit. This is not what it does; every sample has an envelope. Rather, this
is a "no sampled release" flag. Also, despite fiddling with the
PATCH_SUSTAIN flag during instrument loading, TiMidity never actually
used it. Nor did it do anything at all with the PATCH_FAST_REL flag.
- Fixed: wbstartstruct's lump name fields were only 8 characters long
and not properly zero-terminated when all 8 characters were used.
- Fixed: Local sound sequence definitions caused a crash because a proper
NULL check was missing.
- Added translucent blending modes to FMultipatchTexture (not tested yet!)
- Also changed all true color texture creation functions to use proper alpha
values instead of inverted ones.
- Changed FRemapTable so that all palette entries must contain proper alpha
values.
- Fixed: The F1 screen check in m_menu.cpp was missing a NULL pointer check.
- Changed: The boss brain's explosions play weapons/rocklx which is an
unlimited sound. This can become extremely loud. Replaced with a new
sound which is just an alias to weapons/rocklx but has a limit of 4.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@98 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-25 10:00:54 +00:00
|
|
|
buffer[pos] = penew[v].r;
|
|
|
|
buffer[pos+1] = penew[v].g;
|
|
|
|
buffer[pos+2] = penew[v].b;
|
|
|
|
buffer[pos+3] = penew[v].a;
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
- Fixed: Fog for flooding floor textures into gaps created by missing wall textures
didn't work since a parameter changes necessitated by ZDoom's render style 'enhancement'.
Update to ZDoom r940:
SBarInfo Update #18:
- Simplified the DrawGraphic function in sbarinfo_display.cpp
- Added xOffset, yOffset, and alpha to every drawing function in
sbarinfo_display.cpp. So Strife popups can be handeled better and allow for
other effects (translucent bars?). I'm thinking about making a struct for
these five (also x and y) arguments so that the argument lists don't become a
mess.
- Changed DRAWIMAGE in sbarinfo_display.cpp to not use so many calls to
DrawGraphic.
- DrawKeyBar wasn't using screen->DrawTexture.
- Added a Fade transition for popups. It takes two args fade in rate and fade
out rate. Both are floats (1.0 = 1 tic to complete 0.5 = 2 tics to complete
and so on).
- Added a translucency arg to statusbars. 1.0 = opaque and 0.0 = invisible.
- Fixed: When an instrument's envelope runs out, it does not immediately ramp
to zero. Rather, it lets the remainder of the sample finish playing.
- Fixed: When playing a MIDI file with EMIDI track designations to turn a
track off, any ticks that had only events on the disabled track would cause
the delay for that track to be thrown away, and the following notes on
enabled tracks would play too soon. This could be heard quite clearly in
xplasma.mid, where track 4 (FMGlass Drone 1) would interfere with the timing
of tracks 13 and 14 (EP1 Melody and EP1 Echo).
- Fixed: DFlashFader did some operations in its destructor that had to be moved
to its Destroy method.
- Fixed: Dropped weapons from dying players should not double ammo.
- Fixed: When note_on() is called and another copy of the same note is
already playing on the channel, it should stop it with finish_note(), not
kill_note(). This can be clearly heard in the final cymbal crashes of
D_DM2TTL where TiMidity cuts them off because the final cymbals are played
with a velocity of 1 before the preceding cymbals have finished. (I wonder
if I should be setting the self_nonexclusive flag for GUS patches to
disable even this behavior, though, since gf1note.c doesn't turn off
duplicate notes.)
- Changed envelope handling to hopefully match the GUS player's. The most
egregious mistake TiMidity makes is to treat bit 6 as an envelope enable
bit. This is not what it does; every sample has an envelope. Rather, this
is a "no sampled release" flag. Also, despite fiddling with the
PATCH_SUSTAIN flag during instrument loading, TiMidity never actually
used it. Nor did it do anything at all with the PATCH_FAST_REL flag.
- Fixed: wbstartstruct's lump name fields were only 8 characters long
and not properly zero-terminated when all 8 characters were used.
- Fixed: Local sound sequence definitions caused a crash because a proper
NULL check was missing.
- Added translucent blending modes to FMultipatchTexture (not tested yet!)
- Also changed all true color texture creation functions to use proper alpha
values instead of inverted ones.
- Changed FRemapTable so that all palette entries must contain proper alpha
values.
- Fixed: The F1 screen check in m_menu.cpp was missing a NULL pointer check.
- Changed: The boss brain's explosions play weapons/rocklx which is an
unlimited sound. This can become extremely loud. Replaced with a new
sound which is just an alias to weapons/rocklx but has a limit of 4.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@98 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-25 10:00:54 +00:00
|
|
|
/*
|
2008-01-27 11:25:03 +00:00
|
|
|
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);
|
|
|
|
}
|
- Fixed: Fog for flooding floor textures into gaps created by missing wall textures
didn't work since a parameter changes necessitated by ZDoom's render style 'enhancement'.
Update to ZDoom r940:
SBarInfo Update #18:
- Simplified the DrawGraphic function in sbarinfo_display.cpp
- Added xOffset, yOffset, and alpha to every drawing function in
sbarinfo_display.cpp. So Strife popups can be handeled better and allow for
other effects (translucent bars?). I'm thinking about making a struct for
these five (also x and y) arguments so that the argument lists don't become a
mess.
- Changed DRAWIMAGE in sbarinfo_display.cpp to not use so many calls to
DrawGraphic.
- DrawKeyBar wasn't using screen->DrawTexture.
- Added a Fade transition for popups. It takes two args fade in rate and fade
out rate. Both are floats (1.0 = 1 tic to complete 0.5 = 2 tics to complete
and so on).
- Added a translucency arg to statusbars. 1.0 = opaque and 0.0 = invisible.
- Fixed: When an instrument's envelope runs out, it does not immediately ramp
to zero. Rather, it lets the remainder of the sample finish playing.
- Fixed: When playing a MIDI file with EMIDI track designations to turn a
track off, any ticks that had only events on the disabled track would cause
the delay for that track to be thrown away, and the following notes on
enabled tracks would play too soon. This could be heard quite clearly in
xplasma.mid, where track 4 (FMGlass Drone 1) would interfere with the timing
of tracks 13 and 14 (EP1 Melody and EP1 Echo).
- Fixed: DFlashFader did some operations in its destructor that had to be moved
to its Destroy method.
- Fixed: Dropped weapons from dying players should not double ammo.
- Fixed: When note_on() is called and another copy of the same note is
already playing on the channel, it should stop it with finish_note(), not
kill_note(). This can be clearly heard in the final cymbal crashes of
D_DM2TTL where TiMidity cuts them off because the final cymbals are played
with a velocity of 1 before the preceding cymbals have finished. (I wonder
if I should be setting the self_nonexclusive flag for GUS patches to
disable even this behavior, though, since gf1note.c doesn't turn off
duplicate notes.)
- Changed envelope handling to hopefully match the GUS player's. The most
egregious mistake TiMidity makes is to treat bit 6 as an envelope enable
bit. This is not what it does; every sample has an envelope. Rather, this
is a "no sampled release" flag. Also, despite fiddling with the
PATCH_SUSTAIN flag during instrument loading, TiMidity never actually
used it. Nor did it do anything at all with the PATCH_FAST_REL flag.
- Fixed: wbstartstruct's lump name fields were only 8 characters long
and not properly zero-terminated when all 8 characters were used.
- Fixed: Local sound sequence definitions caused a crash because a proper
NULL check was missing.
- Added translucent blending modes to FMultipatchTexture (not tested yet!)
- Also changed all true color texture creation functions to use proper alpha
values instead of inverted ones.
- Changed FRemapTable so that all palette entries must contain proper alpha
values.
- Fixed: The F1 screen check in m_menu.cpp was missing a NULL pointer check.
- Changed: The boss brain's explosions play weapons/rocklx which is an
unlimited sound. This can become extremely loud. Replaced with a new
sound which is just an alias to weapons/rocklx but has a limit of 4.
git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@98 b0f79afe-0144-0410-b225-9a4edf0717df
2008-04-25 10:00:54 +00:00
|
|
|
*/
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// FWarpTexture::CopyTrueColorPixels
|
|
|
|
//
|
|
|
|
// Since the base texture can be anything the warping must be done in
|
|
|
|
// true color
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
|
2008-04-17 20:58:50 +00:00
|
|
|
int FWarpTexture::CopyTrueColorPixels(FBitmap *bmp, int xx, int yy, int rotate, FCopyInfo *inf)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
int buf_pitch = bmp->GetPitch();
|
|
|
|
int buf_width = bmp->GetWidth();
|
|
|
|
int buf_height = bmp->GetHeight();
|
|
|
|
|
|
|
|
if (gl_warp_shader || gl_glsl_renderer || rotate != 0 || inf != NULL || Width > 256 || Height > 256)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
return SourcePic->CopyTrueColorPixels(bmp, xx, yy, rotate, inf);
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
|
2008-04-17 20:58:50 +00:00
|
|
|
FGLBitmap inb;
|
|
|
|
|
|
|
|
if (!inb.Create(Width, Height))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
unsigned long * in = (unsigned long *)inb.GetPixels();
|
2008-01-27 11:25:03 +00:00
|
|
|
unsigned long * out;
|
|
|
|
bool direct;
|
|
|
|
|
|
|
|
FGLTexture *gltex = FGLTexture::ValidateTexture(this);
|
|
|
|
gltex->createWarped = true;
|
|
|
|
if (Width == buf_width && Height == buf_height && xx==0 && yy==0)
|
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
out = (unsigned long*)bmp->GetPixels();
|
2008-01-27 11:25:03 +00:00
|
|
|
direct=true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
out = new unsigned long[Width*Height];
|
|
|
|
direct=false;
|
|
|
|
}
|
|
|
|
|
|
|
|
GenTime = r_FrameTime;
|
|
|
|
if (SourcePic->bMasked) memset(in, 0, Width*Height*sizeof(long));
|
2008-04-17 20:58:50 +00:00
|
|
|
int ret = SourcePic->CopyTrueColorPixels(&inb, 0, 0);
|
2008-01-27 11:25:03 +00:00
|
|
|
|
2008-04-17 20:58:50 +00:00
|
|
|
static unsigned long linebuffer[256]; // anything larger will bring down performance so it is excluded above.
|
2008-01-27 11:25:03 +00:00
|
|
|
int timebase = r_FrameTime*23/28;
|
|
|
|
int xsize = Width;
|
|
|
|
int ysize = Height;
|
|
|
|
int xmask = xsize - 1;
|
|
|
|
int ymask = ysize - 1;
|
|
|
|
int ds_xbits;
|
|
|
|
int i,x;
|
|
|
|
|
|
|
|
for(ds_xbits=-1,i=Width; i; i>>=1, ds_xbits++);
|
|
|
|
|
|
|
|
for (x = xsize-1; x >= 0; x--)
|
|
|
|
{
|
|
|
|
int yt, yf = (finesine[(timebase+(x+17)*128)&FINEMASK]>>13) & ymask;
|
|
|
|
const unsigned long *source = in + x;
|
|
|
|
unsigned long *dest = out + x;
|
|
|
|
for (yt = ysize; yt; yt--, yf = (yf+1)&ymask, dest += xsize)
|
|
|
|
{
|
|
|
|
*dest = *(source+(yf<<ds_xbits));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
timebase = r_FrameTime*32/28;
|
|
|
|
int y;
|
|
|
|
for (y = ysize-1; y >= 0; y--)
|
|
|
|
{
|
|
|
|
int xt, xf = (finesine[(timebase+y*128)&FINEMASK]>>13) & xmask;
|
|
|
|
unsigned long *source = out + (y<<ds_xbits);
|
|
|
|
unsigned long *dest = linebuffer;
|
|
|
|
for (xt = xsize; xt; xt--, xf = (xf+1)&xmask)
|
|
|
|
{
|
|
|
|
*dest++ = *(source+xf);
|
|
|
|
}
|
|
|
|
memcpy (out+y*xsize, linebuffer, xsize*sizeof(unsigned long));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!direct)
|
|
|
|
{
|
|
|
|
// Negative offsets cannot occur here.
|
|
|
|
if (xx<0) xx=0;
|
|
|
|
if (yy<0) yy=0;
|
|
|
|
|
2008-04-17 20:58:50 +00:00
|
|
|
unsigned long * targ = ((unsigned long*)bmp->GetPixels()) + xx + yy*buf_width;
|
2008-01-27 11:25:03 +00:00
|
|
|
int linelen=MIN<int>(Width, buf_width-xx);
|
|
|
|
int linecount=MIN<int>(Height, buf_height-yy);
|
|
|
|
|
|
|
|
for(i=0;i<linecount;i++)
|
|
|
|
{
|
|
|
|
memcpy(targ, &out[Width*i], linelen*sizeof(unsigned long));
|
|
|
|
targ+=buf_width;
|
|
|
|
}
|
|
|
|
delete [] out;
|
|
|
|
}
|
|
|
|
GenTime=r_FrameTime;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// FWarpTexture::CopyTrueColorPixels
|
|
|
|
//
|
|
|
|
// Since the base texture can be anything the warping must be done in
|
|
|
|
// true color
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
|
2008-04-17 20:58:50 +00:00
|
|
|
int FWarp2Texture::CopyTrueColorPixels(FBitmap *bmp, int xx, int yy, int rotate, FCopyInfo *inf)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
int buf_pitch = bmp->GetPitch();
|
|
|
|
int buf_width = bmp->GetWidth();
|
|
|
|
int buf_height = bmp->GetHeight();
|
|
|
|
|
|
|
|
if (gl_warp_shader || gl_glsl_renderer || rotate != 0 || inf != NULL || Width > 256 || Height > 256)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
return SourcePic->CopyTrueColorPixels(bmp, xx, yy, rotate, inf);
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
|
2008-04-17 20:58:50 +00:00
|
|
|
FGLBitmap inb;
|
|
|
|
|
|
|
|
if (!inb.Create(Width, Height))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
unsigned long * in = (unsigned long *)inb.GetPixels();
|
2008-01-27 11:25:03 +00:00
|
|
|
unsigned long * out;
|
|
|
|
bool direct;
|
|
|
|
|
|
|
|
FGLTexture *gltex = FGLTexture::ValidateTexture(this);
|
|
|
|
gltex->createWarped = true;
|
|
|
|
if (Width == buf_width && Height == buf_height && xx==0 && yy==0)
|
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
out = (unsigned long*)bmp->GetPixels();
|
2008-01-27 11:25:03 +00:00
|
|
|
direct=true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
out = new unsigned long[Width*Height];
|
|
|
|
direct=false;
|
|
|
|
}
|
|
|
|
|
|
|
|
GenTime = r_FrameTime;
|
|
|
|
if (SourcePic->bMasked) memset(in, 0, Width*Height*sizeof(long));
|
2008-04-17 20:58:50 +00:00
|
|
|
int ret = SourcePic->CopyTrueColorPixels(&inb, 0, 0);
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
int xsize = Width;
|
|
|
|
int ysize = Height;
|
|
|
|
int xmask = xsize - 1;
|
|
|
|
int ymask = ysize - 1;
|
|
|
|
int ybits;
|
|
|
|
int x, y;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for(ybits=-1,i=ysize; i; i>>=1, ybits++);
|
|
|
|
|
|
|
|
DWORD timebase = r_FrameTime * 40 / 28;
|
|
|
|
for (x = xsize-1; x >= 0; x--)
|
|
|
|
{
|
|
|
|
for (y = ysize-1; y >= 0; y--)
|
|
|
|
{
|
|
|
|
int xt = (x + 128
|
|
|
|
+ ((finesine[(y*128 + timebase*5 + 900) & 8191]*2)>>FRACBITS)
|
|
|
|
+ ((finesine[(x*256 + timebase*4 + 300) & 8191]*2)>>FRACBITS)) & xmask;
|
|
|
|
int yt = (y + 128
|
|
|
|
+ ((finesine[(y*128 + timebase*3 + 700) & 8191]*2)>>FRACBITS)
|
|
|
|
+ ((finesine[(x*256 + timebase*4 + 1200) & 8191]*2)>>FRACBITS)) & ymask;
|
|
|
|
const unsigned long *source = in + (xt << ybits) + yt;
|
|
|
|
unsigned long *dest = out + (x << ybits) + y;
|
|
|
|
*dest = *source;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!direct)
|
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
// This can only happen for sprites so
|
|
|
|
// negative offsets cannot occur here.
|
2008-01-27 11:25:03 +00:00
|
|
|
if (xx<0) xx=0;
|
|
|
|
if (yy<0) yy=0;
|
|
|
|
|
2008-04-17 20:58:50 +00:00
|
|
|
unsigned long * targ = ((unsigned long*)bmp->GetPixels()) + xx + yy*buf_width;
|
2008-01-27 11:25:03 +00:00
|
|
|
int linelen=MIN<int>(Width, buf_width-xx);
|
|
|
|
int linecount=MIN<int>(Height, buf_height-yy);
|
|
|
|
|
|
|
|
for(i=0;i<linecount;i++)
|
|
|
|
{
|
|
|
|
memcpy(targ, &out[Width*i], linelen*sizeof(unsigned long));
|
2008-04-17 20:58:50 +00:00
|
|
|
targ+=buf_pitch/4;
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
delete [] out;
|
|
|
|
}
|
|
|
|
GenTime=r_FrameTime;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Camera texture rendering
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
|
|
|
|
void FCanvasTexture::RenderGLView (AActor *viewpoint, int fov)
|
|
|
|
{
|
|
|
|
gl_RenderTextureView(this, viewpoint, fov);
|
|
|
|
bNeedsUpdate = false;
|
|
|
|
bDidUpdate = true;
|
|
|
|
bFirstUpdate = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// Precaches a GL texture
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
void FTexture::PrecacheGL()
|
|
|
|
{
|
2008-01-28 11:24:32 +00:00
|
|
|
if (gl_precache)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
FGLTexture * gltex = FGLTexture::ValidateTexture(this);
|
|
|
|
if (gltex)
|
|
|
|
{
|
|
|
|
if (UseType==FTexture::TEX_Sprite)
|
|
|
|
{
|
|
|
|
gltex->BindPatch(CM_DEFAULT);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gltex->Bind (CM_DEFAULT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// Precaches a GL texture
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
void FTexture::UncacheGL()
|
|
|
|
{
|
|
|
|
if (Native)
|
|
|
|
{
|
|
|
|
FGLTexture * gltex = FGLTexture::ValidateTexture(this);
|
|
|
|
if (gltex) gltex->Clean(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// fake brightness maps
|
|
|
|
// These are generated for textures affected by a colormap with
|
|
|
|
// fullbright entries.
|
|
|
|
// These textures are only used internally by the GL renderer so
|
|
|
|
// all code for software rendering support is missing
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
|
|
|
|
FBrightmapTexture::FBrightmapTexture (FTexture *source)
|
|
|
|
{
|
|
|
|
SourcePic = source;
|
|
|
|
CopySize(source);
|
|
|
|
bNoDecals = source->bNoDecals;
|
|
|
|
Rotations = source->Rotations;
|
|
|
|
UseType = source->UseType;
|
|
|
|
}
|
|
|
|
|
|
|
|
FBrightmapTexture::~FBrightmapTexture ()
|
|
|
|
{
|
|
|
|
Unload();
|
|
|
|
}
|
|
|
|
|
|
|
|
const BYTE *FBrightmapTexture::GetColumn (unsigned int column, const Span **spans_out)
|
|
|
|
{
|
|
|
|
// not needed
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const BYTE *FBrightmapTexture::GetPixels ()
|
|
|
|
{
|
|
|
|
// not needed
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FBrightmapTexture::Unload ()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2008-04-17 20:58:50 +00:00
|
|
|
int FBrightmapTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
SourcePic->CopyTrueColorTranslated(bmp, x, y, rotate, &GlobalBrightmap);
|
2008-01-27 11:25:03 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// The GL texture maintenance class
|
|
|
|
//
|
|
|
|
//===========================================================================
|
2008-02-25 11:47:19 +00:00
|
|
|
TArray<FGLTexture *> FGLTexture::gltextures;
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Constructor
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
FGLTexture::FGLTexture(FTexture * tx)
|
|
|
|
{
|
|
|
|
tex = tx;
|
|
|
|
|
|
|
|
glpatch=NULL;
|
|
|
|
gltexture=NULL;
|
|
|
|
|
|
|
|
Shader = NULL;
|
|
|
|
|
|
|
|
HiresLump=-1;
|
|
|
|
hirestexture = NULL;
|
|
|
|
|
|
|
|
areacount = 0;
|
|
|
|
areas = NULL;
|
|
|
|
createWarped = false;
|
|
|
|
|
|
|
|
bHasColorkey = false;
|
|
|
|
|
2008-04-20 10:26:25 +00:00
|
|
|
for (int i=GLUSE_PATCH; i<=GLUSE_TEXTURE; i++)
|
|
|
|
{
|
|
|
|
Width[i] = tex->GetWidth();
|
|
|
|
Height[i] = tex->GetHeight();
|
|
|
|
LeftOffset[i] = tex->LeftOffset;
|
|
|
|
TopOffset[i] = tex->TopOffset;
|
|
|
|
RenderWidth[i] = tex->GetScaledWidth();
|
|
|
|
RenderHeight[i] = tex->GetScaledHeight();
|
|
|
|
}
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
scalex = tex->xScale/(float)FRACUNIT;
|
|
|
|
scaley = tex->yScale/(float)FRACUNIT;
|
|
|
|
|
|
|
|
|
|
|
|
// a little adjustment to make sprites look better with texture filtering:
|
|
|
|
// create a 1 pixel wide empty frame around them.
|
|
|
|
if (tex->UseType == FTexture::TEX_Sprite ||
|
|
|
|
tex->UseType == FTexture::TEX_SkinSprite ||
|
|
|
|
tex->UseType == FTexture::TEX_Decal)
|
|
|
|
{
|
2008-04-20 10:26:25 +00:00
|
|
|
RenderWidth[GLUSE_PATCH]+=2;
|
|
|
|
RenderHeight[GLUSE_PATCH]+=2;
|
|
|
|
Width[GLUSE_PATCH]+=2;
|
|
|
|
Height[GLUSE_PATCH]+=2;
|
|
|
|
LeftOffset[GLUSE_PATCH]+=1;
|
|
|
|
TopOffset[GLUSE_PATCH]+=1;
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ((gl.flags & RFL_GLSL) && tx->UseBasePalette() && HasGlobalBrightmap &&
|
|
|
|
tx->UseType != FTexture::TEX_Autopage && tx->UseType != FTexture::TEX_Decal &&
|
|
|
|
tx->UseType != FTexture::TEX_MiscPatch && tx->UseType != FTexture::TEX_FontChar &&
|
|
|
|
tex->bm_info.Brightmap == NULL
|
|
|
|
)
|
|
|
|
{
|
|
|
|
tex->bm_info.Brightmap = new FBrightmapTexture(tx);
|
|
|
|
tex->bm_info.Brightmap->bm_info.bIsBrightmap=-1;
|
|
|
|
}
|
|
|
|
bIsTransparent = -1;
|
|
|
|
|
|
|
|
if (tex->bHasCanvas) scaley=-scaley;
|
|
|
|
|
2008-02-25 11:47:19 +00:00
|
|
|
index = gltextures.Push(this);
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Destructor
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
|
|
|
|
FGLTexture::~FGLTexture()
|
|
|
|
{
|
|
|
|
Clean(true);
|
|
|
|
if (areas) delete [] areas;
|
|
|
|
if (hirestexture) delete hirestexture;
|
|
|
|
|
2008-02-25 11:47:19 +00:00
|
|
|
for(unsigned i=0;i<gltextures.Size();i++)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2008-02-25 11:47:19 +00:00
|
|
|
if (gltextures[i]==this)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2008-02-25 11:47:19 +00:00
|
|
|
gltextures.Delete(i);
|
2008-01-27 11:25:03 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Update
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
|
|
|
|
bool FGLTexture::Update ()
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// GetRect
|
|
|
|
//
|
|
|
|
//===========================================================================
|
2008-04-20 10:26:25 +00:00
|
|
|
void FGLTexture::GetRect(GL_RECT * r, FGLTexture::ETexUse i) const
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2008-04-20 10:26:25 +00:00
|
|
|
r->left=-(float)GetScaledLeftOffset(i);
|
|
|
|
r->top=-(float)GetScaledTopOffset(i);
|
|
|
|
r->width=(float)TextureWidth(i);
|
|
|
|
r->height=(float)TextureHeight(i);
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Finds gaps in the texture which can be skipped by the renderer
|
|
|
|
// This was mainly added to speed up one area in E4M6 of 007LTSD
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
bool FGLTexture::FindHoles(const unsigned char * buffer, int w, int h)
|
|
|
|
{
|
|
|
|
const unsigned char * li;
|
|
|
|
int y,x;
|
|
|
|
int startdraw,lendraw;
|
|
|
|
int gaps[5][2];
|
|
|
|
int gapc=0;
|
|
|
|
|
|
|
|
|
|
|
|
// already done!
|
|
|
|
if (areacount) return false;
|
|
|
|
if (tex->UseType==FTexture::TEX_Flat) return false; // flats don't have transparent parts
|
|
|
|
areacount=-1; //whatever happens next, it shouldn't be done twice!
|
|
|
|
|
|
|
|
// large textures are excluded for performance reasons
|
|
|
|
if (h>256) return false;
|
|
|
|
|
|
|
|
startdraw=-1;
|
|
|
|
lendraw=0;
|
|
|
|
for(y=0;y<h;y++)
|
|
|
|
{
|
|
|
|
li=buffer+w*y*4+3;
|
|
|
|
|
|
|
|
for(x=0;x<w;x++,li+=4)
|
|
|
|
{
|
|
|
|
if (*li!=0) break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (x!=w)
|
|
|
|
{
|
|
|
|
// non - transparent
|
|
|
|
if (startdraw==-1)
|
|
|
|
{
|
|
|
|
startdraw=y;
|
|
|
|
// merge transparent gaps of less than 16 pixels into the last drawing block
|
|
|
|
if (gapc && y<=gaps[gapc-1][0]+gaps[gapc-1][1]+16)
|
|
|
|
{
|
|
|
|
gapc--;
|
|
|
|
startdraw=gaps[gapc][0];
|
|
|
|
lendraw=y-startdraw;
|
|
|
|
}
|
|
|
|
if (gapc==4) return false; // too many splits - this isn't worth it
|
|
|
|
}
|
|
|
|
lendraw++;
|
|
|
|
}
|
|
|
|
else if (startdraw!=-1)
|
|
|
|
{
|
|
|
|
if (lendraw==1) lendraw=2;
|
|
|
|
gaps[gapc][0]=startdraw;
|
|
|
|
gaps[gapc][1]=lendraw;
|
|
|
|
gapc++;
|
|
|
|
|
|
|
|
startdraw=-1;
|
|
|
|
lendraw=0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (startdraw!=-1)
|
|
|
|
{
|
|
|
|
gaps[gapc][0]=startdraw;
|
|
|
|
gaps[gapc][1]=lendraw;
|
|
|
|
gapc++;
|
|
|
|
}
|
|
|
|
if (startdraw==0 && lendraw==h) return false; // nothing saved so don't create a split list
|
|
|
|
|
|
|
|
GL_RECT * rcs=new GL_RECT[gapc];
|
|
|
|
|
|
|
|
for(x=0;x<gapc;x++)
|
|
|
|
{
|
|
|
|
// gaps are stored as texture (u/v) coordinates
|
|
|
|
rcs[x].width=rcs[x].left=-1.0f;
|
|
|
|
rcs[x].top=(float)gaps[x][0]/(float)h;
|
|
|
|
rcs[x].height=(float)gaps[x][1]/(float)h;
|
|
|
|
}
|
|
|
|
areas=rcs;
|
|
|
|
areacount=gapc;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// smooth the edges of transparent fields in the texture
|
|
|
|
// returns false when nothing is manipulated to save the work on further
|
|
|
|
// levels
|
|
|
|
|
|
|
|
// 28/10/2003: major optimization: This function was far too pedantic.
|
|
|
|
// taking the value of one of the neighboring pixels is fully sufficient
|
|
|
|
//
|
|
|
|
//===========================================================================
|
2008-02-27 11:51:25 +00:00
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
|
|
#define MSB 0
|
|
|
|
#define SOME_MASK 0xffffff00
|
|
|
|
#else
|
|
|
|
#define MSB 3
|
|
|
|
#define SOME_MASK 0x00ffffff
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define CHKPIX(ofs) (l1[(ofs)*4+MSB]==255 ? (( ((long*)l1)[0] = ((long*)l1)[ofs]&SOME_MASK), trans=true ) : false)
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
bool FGLTexture::SmoothEdges(unsigned char * buffer,int w, int h, bool clampsides)
|
|
|
|
{
|
2008-02-27 11:51:25 +00:00
|
|
|
int x,y;
|
|
|
|
bool trans=buffer[MSB]==0; // If I set this to false here the code won't detect textures
|
|
|
|
// that only contain transparent pixels.
|
|
|
|
unsigned char * l1;
|
|
|
|
|
|
|
|
if (h<=1 || w<=1) return false; // makes (a) no sense and (b) doesn't work with this code!
|
|
|
|
|
|
|
|
l1=buffer;
|
|
|
|
|
|
|
|
|
|
|
|
if (l1[MSB]==0 && !CHKPIX(1)) CHKPIX(w);
|
|
|
|
l1+=4;
|
|
|
|
for(x=1;x<w-1;x++, l1+=4)
|
|
|
|
{
|
|
|
|
if (l1[MSB]==0 && !CHKPIX(-1) && !CHKPIX(1)) CHKPIX(w);
|
|
|
|
}
|
|
|
|
if (l1[MSB]==0 && !CHKPIX(-1)) CHKPIX(w);
|
|
|
|
l1+=4;
|
|
|
|
|
|
|
|
for(y=1;y<h-1;y++)
|
|
|
|
{
|
|
|
|
if (l1[MSB]==0 && !CHKPIX(-w) && !CHKPIX(1)) CHKPIX(w);
|
|
|
|
l1+=4;
|
|
|
|
for(x=1;x<w-1;x++, l1+=4)
|
|
|
|
{
|
|
|
|
if (l1[MSB]==0 && !CHKPIX(-w) && !CHKPIX(-1) && !CHKPIX(1)) CHKPIX(w);
|
|
|
|
}
|
|
|
|
if (l1[MSB]==0 && !CHKPIX(-w) && !CHKPIX(-1)) CHKPIX(w);
|
|
|
|
l1+=4;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (l1[MSB]==0 && !CHKPIX(-w)) CHKPIX(1);
|
|
|
|
l1+=4;
|
|
|
|
for(x=1;x<w-1;x++, l1+=4)
|
|
|
|
{
|
|
|
|
if (l1[MSB]==0 && !CHKPIX(-w) && !CHKPIX(-1)) CHKPIX(1);
|
|
|
|
}
|
|
|
|
if (l1[MSB]==0 && !CHKPIX(-w)) CHKPIX(-1);
|
|
|
|
|
|
|
|
return trans;
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Post-process the texture data after the buffer has been created
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
bool FGLTexture::ProcessData(unsigned char * buffer, int w, int h, int cm, bool ispatch)
|
|
|
|
{
|
|
|
|
if (tex->bm_info.bIsBrightmap==-1)
|
|
|
|
{
|
|
|
|
DWORD * dwbuf = (DWORD*)buffer;
|
|
|
|
for(int i=0;i<w*h;i++)
|
|
|
|
{
|
|
|
|
if ((dwbuf[i]&0xffffff) != 0)
|
|
|
|
{
|
|
|
|
tex->bm_info.bIsBrightmap = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (tex->bm_info.bIsBrightmap == -1)
|
|
|
|
{
|
|
|
|
tex->bm_info.bIsBrightmap = 0;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (tex->bMasked && !tex->bm_info.bIsBrightmap)
|
|
|
|
{
|
|
|
|
tex->bMasked=SmoothEdges(buffer, w, h, ispatch);
|
|
|
|
if (tex->bMasked && !ispatch) FindHoles(buffer, w, h);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Checks for transparent pixels if there is no simpler means to get
|
|
|
|
// this information
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
void FGLTexture::CheckTrans(unsigned char * buffer, int size, int trans)
|
|
|
|
{
|
|
|
|
if (bIsTransparent == -1)
|
|
|
|
{
|
|
|
|
bIsTransparent = trans;
|
|
|
|
if (trans == -1)
|
|
|
|
{
|
|
|
|
DWORD * dwbuf = (DWORD*)buffer;
|
|
|
|
if (bIsTransparent == -1) for(int i=0;i<size;i++)
|
|
|
|
{
|
|
|
|
DWORD alpha = dwbuf[i]>>24;
|
|
|
|
|
|
|
|
if (alpha != 0xff && alpha != 0)
|
|
|
|
{
|
|
|
|
bIsTransparent = 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bIsTransparent = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Deletes all allocated resources
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
|
|
|
|
void FGLTexture::Clean(bool all)
|
|
|
|
{
|
|
|
|
WorldTextureInfo::Clean(all);
|
|
|
|
PatchTextureInfo::Clean(all);
|
|
|
|
createWarped = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Initializes the buffer for the texture data
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
|
2008-04-20 10:26:25 +00:00
|
|
|
unsigned char * FGLTexture::CreateTexBuffer(ETexUse use, int _cm, int translation, int & w, int & h, bool allowhires)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
unsigned char * buffer;
|
|
|
|
intptr_t cm = _cm;
|
2008-04-20 10:26:25 +00:00
|
|
|
int W, H;
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
// Textures that are already scaled in the texture lump will not get replaced
|
|
|
|
// by hires textures
|
|
|
|
if (gl_texture_usehires && allowhires && scalex==1.f && scaley==1.f)
|
|
|
|
{
|
2008-04-17 20:58:50 +00:00
|
|
|
buffer = LoadHiresTexture (&w, &h, _cm);
|
2008-01-27 11:25:03 +00:00
|
|
|
if (buffer)
|
|
|
|
{
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-04-20 10:26:25 +00:00
|
|
|
W = w = Width[use];
|
|
|
|
H = h = Height[use];
|
2008-01-27 11:25:03 +00:00
|
|
|
|
2008-04-17 20:58:50 +00:00
|
|
|
|
2008-04-20 10:26:25 +00:00
|
|
|
buffer=new unsigned char[W*(H+1)*4];
|
|
|
|
memset(buffer, 0, W * (H+1) * 4);
|
2008-01-27 11:25:03 +00:00
|
|
|
|
2008-04-20 10:26:25 +00:00
|
|
|
FGLBitmap bmp(buffer, W*4, W, H);
|
2008-04-17 20:58:50 +00:00
|
|
|
bmp.SetTranslationInfo(cm, translation);
|
|
|
|
|
|
|
|
if (tex->bComplex)
|
|
|
|
{
|
|
|
|
FBitmap imgCreate;
|
|
|
|
|
|
|
|
// The texture contains special processing so it must be composited using with the
|
|
|
|
// base bitmap class and then be converted as a whole.
|
2008-04-20 10:26:25 +00:00
|
|
|
if (imgCreate.Create(W, H))
|
2008-04-17 20:58:50 +00:00
|
|
|
{
|
2008-04-20 10:26:25 +00:00
|
|
|
memset(imgCreate.GetPixels(), 0, W * H * 4);
|
2008-04-17 20:58:50 +00:00
|
|
|
int trans =
|
2008-04-20 10:26:25 +00:00
|
|
|
tex->CopyTrueColorPixels(&imgCreate, GetLeftOffset(use) - tex->LeftOffset, GetTopOffset(use) - tex->TopOffset);
|
|
|
|
bmp.CopyPixelDataRGB(0, 0, imgCreate.GetPixels(), W, H, 4, W * 4, 0, CF_BGRA);
|
|
|
|
CheckTrans(buffer, W*H, trans);
|
2008-04-17 20:58:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (translation<=0)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
int trans =
|
2008-04-20 10:26:25 +00:00
|
|
|
tex->CopyTrueColorPixels(&bmp, GetLeftOffset(use) - tex->LeftOffset, GetTopOffset(use) - tex->TopOffset);
|
2008-01-27 11:25:03 +00:00
|
|
|
|
2008-04-20 10:26:25 +00:00
|
|
|
CheckTrans(buffer, W*H, trans);
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// When using translations everything must be mapped to the base palette.
|
|
|
|
// Since FTexture's method is doing exactly that by calling GetPixels let's use that here
|
|
|
|
// to do all the dirty work for us. ;)
|
2008-04-20 10:26:25 +00:00
|
|
|
tex->FTexture::CopyTrueColorPixels(&bmp, GetLeftOffset(use) - tex->LeftOffset, GetTopOffset(use) - tex->TopOffset);
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Gets texture coordinate info for world (wall/flat) textures
|
|
|
|
// The wrapper class is there to provide a set of coordinate
|
|
|
|
// functions to access the texture
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
const WorldTextureInfo * FGLTexture::GetWorldTextureInfo()
|
|
|
|
{
|
|
|
|
|
|
|
|
if (tex->UseType==FTexture::TEX_Null) return NULL; // Cannot register a NULL texture!
|
2008-04-20 10:26:25 +00:00
|
|
|
if (!gltexture) gltexture=new GLTexture(Width[GLUSE_TEXTURE], Height[GLUSE_TEXTURE], true, true);
|
2008-01-27 11:25:03 +00:00
|
|
|
if (gltexture) return (WorldTextureInfo*)this;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Gets texture coordinate info for sprites
|
|
|
|
// The wrapper class is there to provide a set of coordinate
|
|
|
|
// functions to access the texture
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
const PatchTextureInfo * FGLTexture::GetPatchTextureInfo()
|
|
|
|
{
|
|
|
|
if (tex->UseType==FTexture::TEX_Null) return NULL; // Cannot register a NULL texture!
|
|
|
|
if (!glpatch)
|
|
|
|
{
|
2008-04-20 10:26:25 +00:00
|
|
|
glpatch=new GLTexture(Width[GLUSE_PATCH], Height[GLUSE_PATCH], false, false);
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
if (glpatch) return (PatchTextureInfo*)this;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Binds a texture to the renderer
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
|
|
|
|
const WorldTextureInfo * FGLTexture::Bind(int texunit, int cm, int clampmode, int translation)
|
|
|
|
{
|
|
|
|
bool usebright = false;
|
|
|
|
|
|
|
|
translation = GLTranslationPalette::GetInternalTranslation(translation);
|
|
|
|
|
|
|
|
if (GetWorldTextureInfo())
|
|
|
|
{
|
|
|
|
if (texunit == 0)
|
|
|
|
{
|
|
|
|
FTexture *brightmap = tex->bm_info.Brightmap;
|
|
|
|
|
|
|
|
if (brightmap && (gl_glsl_renderer || gl_brightmap_shader) && translation >= 0 &&
|
|
|
|
cm >= CM_DEFAULT && cm <= CM_DESAT31 && gl_brightmapenabled)
|
|
|
|
{
|
|
|
|
FGLTexture *bmgltex = FGLTexture::ValidateTexture(brightmap);
|
|
|
|
bmgltex->Bind(1, CM_DEFAULT, clampmode, 0);
|
|
|
|
if (brightmap->bm_info.bIsBrightmap == 0)
|
|
|
|
{
|
|
|
|
delete brightmap;
|
|
|
|
tex->bm_info.Brightmap = NULL;
|
|
|
|
}
|
|
|
|
else usebright = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!gl_glsl_renderer)
|
|
|
|
{
|
|
|
|
if (gl.flags & RFL_GLSL)
|
|
|
|
{
|
|
|
|
if (createWarped && gl_warp_shader && tex->bWarped!=0)
|
2008-01-27 15:34:47 +00:00
|
|
|
{
|
2008-01-27 11:25:03 +00:00
|
|
|
Clean(true);
|
2008-01-27 15:34:47 +00:00
|
|
|
GetWorldTextureInfo();
|
|
|
|
}
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
if ((gl_warp_shader && tex->bWarped!=0) ||
|
|
|
|
(usebright) ||
|
2008-02-14 13:07:19 +00:00
|
|
|
((tex->bHasCanvas || gl_colormap_shader) && cm!=CM_DEFAULT && /*!(cm>=CM_DESAT1 && cm<=CM_DESAT31) &&*/ cm!=CM_SHADE && gl_texturemode != TM_MASK))
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
Shader->Bind(cm, usebright);
|
|
|
|
if (cm != CM_SHADE) cm = CM_DEFAULT;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GLShader::Unbind();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tex->bWarped == 0 || !gl_warp_shader)
|
|
|
|
{
|
|
|
|
// If this is a warped texture that needs updating
|
|
|
|
// delete all system textures created for this
|
|
|
|
if (tex->CheckModified() && !tex->bHasCanvas && HiresLump<0 && HiresLump!=-2)
|
|
|
|
{
|
|
|
|
gltexture->Clean(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Shader->Bind(cm, usebright);
|
|
|
|
if (cm != CM_SHADE) cm = CM_DEFAULT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bind it to the system.
|
2008-01-27 15:34:47 +00:00
|
|
|
// clamping in x-direction may cause problems when rendering segs
|
|
|
|
if (!gltexture->Bind(texunit, cm, translation, gl_render_precise? clampmode&GLT_CLAMPY : clampmode))
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
int w,h;
|
|
|
|
|
|
|
|
// Create this texture
|
2008-04-20 10:26:25 +00:00
|
|
|
unsigned char * buffer = CreateTexBuffer(GLUSE_TEXTURE, cm, translation, w, h);
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
ProcessData(buffer, w, h, cm, false);
|
|
|
|
if (!gltexture->CreateTexture(buffer, w, h, true, texunit, cm, translation))
|
|
|
|
{
|
|
|
|
// could not create texture
|
|
|
|
delete buffer;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
delete buffer;
|
|
|
|
}
|
2008-01-27 23:11:51 +00:00
|
|
|
if (texunit == 0) gltexture->SetTextureClamp(gl_render_precise? clampmode&GLT_CLAMPY : clampmode);
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
if (tex->bHasCanvas) static_cast<FCanvasTexture*>(tex)->NeedUpdate();
|
|
|
|
return (WorldTextureInfo*)this;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const WorldTextureInfo * FGLTexture::Bind(int cm, int clampmode, int translation)
|
|
|
|
{
|
|
|
|
return Bind(0, cm, clampmode, translation);
|
|
|
|
}
|
|
|
|
//===========================================================================
|
|
|
|
//
|
|
|
|
// Binds a sprite to the renderer
|
|
|
|
//
|
|
|
|
//===========================================================================
|
|
|
|
const PatchTextureInfo * FGLTexture::BindPatch(int texunit, int cm, int translation)
|
|
|
|
{
|
|
|
|
bool usebright = false;
|
|
|
|
int transparm = translation;
|
|
|
|
|
|
|
|
translation = GLTranslationPalette::GetInternalTranslation(translation);
|
|
|
|
|
|
|
|
if (GetPatchTextureInfo())
|
|
|
|
{
|
|
|
|
if (texunit == 0)
|
|
|
|
{
|
|
|
|
FTexture *brightmap = tex->bm_info.Brightmap;
|
|
|
|
|
|
|
|
if (brightmap && (gl_glsl_renderer || gl_brightmap_shader) && translation >= 0 &&
|
|
|
|
transparm >= 0 && cm >= CM_DEFAULT && cm <= CM_DESAT31 && gl_brightmapenabled)
|
|
|
|
{
|
|
|
|
FGLTexture *bmgltex = FGLTexture::ValidateTexture(brightmap);
|
|
|
|
bmgltex->BindPatch(1, CM_DEFAULT, 0);
|
|
|
|
if (brightmap->bm_info.bIsBrightmap == 0)
|
|
|
|
{
|
|
|
|
delete brightmap;
|
|
|
|
tex->bm_info.Brightmap = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
usebright = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!gl_glsl_renderer)
|
|
|
|
{
|
|
|
|
if (gl.flags & RFL_GLSL)
|
|
|
|
{
|
|
|
|
if (createWarped && gl_warp_shader && tex->bWarped!=0)
|
2008-01-27 15:34:47 +00:00
|
|
|
{
|
2008-01-27 11:25:03 +00:00
|
|
|
Clean(true);
|
2008-01-27 15:34:47 +00:00
|
|
|
GetPatchTextureInfo();
|
|
|
|
}
|
|
|
|
|
2008-01-27 11:25:03 +00:00
|
|
|
if ((gl_warp_shader && tex->bWarped!=0) ||
|
|
|
|
(usebright) ||
|
2008-02-14 13:07:19 +00:00
|
|
|
((tex->bHasCanvas || gl_colormap_shader) && cm!=CM_DEFAULT && /*!(cm>=CM_DESAT1 && cm<=CM_DESAT31) &&*/ cm!=CM_SHADE && gl_texturemode != TM_MASK))
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
Shader->Bind(cm, usebright);
|
|
|
|
if (cm != CM_SHADE) cm = CM_DEFAULT;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GLShader::Unbind();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tex->bWarped == 0 || !gl_warp_shader)
|
|
|
|
{
|
|
|
|
// If this is a warped texture that needs updating
|
|
|
|
// delete all system textures created for this
|
|
|
|
if (tex->CheckModified() && !tex->bHasCanvas && HiresLump<0 && HiresLump!=-2)
|
|
|
|
{
|
|
|
|
glpatch->Clean(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Shader->Bind(cm, usebright);
|
|
|
|
if (cm != CM_SHADE) cm = CM_DEFAULT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bind it to the system. For multitexturing this
|
|
|
|
// should be the only thing that needs adjusting
|
2008-01-27 15:34:47 +00:00
|
|
|
if (!glpatch->Bind(texunit, cm, translation, -1))
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
int w, h;
|
|
|
|
|
|
|
|
// Create this texture
|
2008-04-20 10:26:25 +00:00
|
|
|
unsigned char * buffer = CreateTexBuffer(GLUSE_PATCH, cm, translation, w, h, false);
|
2008-01-27 11:25:03 +00:00
|
|
|
ProcessData(buffer, w, h, cm, true);
|
|
|
|
if (!glpatch->CreateTexture(buffer, w, h, false, texunit, cm, translation))
|
|
|
|
{
|
|
|
|
// could not create texture
|
|
|
|
delete buffer;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
delete buffer;
|
|
|
|
}
|
|
|
|
if (gl_render_precise)
|
|
|
|
{
|
|
|
|
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
|
|
gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
|
|
}
|
|
|
|
return (PatchTextureInfo*)this;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
const PatchTextureInfo * FGLTexture::BindPatch(int cm, int translation)
|
|
|
|
{
|
|
|
|
return BindPatch(0, cm, translation);
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// Flushes all hardware dependent data
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
void FGLTexture::FlushAll()
|
|
|
|
{
|
2008-02-25 11:47:19 +00:00
|
|
|
for(int i=gltextures.Size()-1;i>=0;i--)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2008-02-25 11:47:19 +00:00
|
|
|
gltextures[i]->Clean(true);
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// Gets a texture from the texture manager and checks its validity for
|
|
|
|
// GL rendering.
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
|
|
|
FGLTexture * FGLTexture::ValidateTexture(FTexture * tex)
|
|
|
|
{
|
|
|
|
if (tex && tex->UseType!=FTexture::TEX_Null)
|
|
|
|
{
|
|
|
|
FGLTexture *gltex = static_cast<FGLTexture*>(tex->GetNative(false));
|
|
|
|
|
|
|
|
if (gltex)
|
|
|
|
{
|
|
|
|
// This can't be put in the constructor because many
|
|
|
|
// textures are created before the GL renderer is operable
|
|
|
|
if ((gl.flags & RFL_GLSL) && !gltex->Shader) switch(tex->bWarped)
|
|
|
|
{
|
|
|
|
default:
|
|
|
|
gltex->Shader = GLShader::Find("Default");
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
gltex->Shader = GLShader::Find("Warp 1");
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
gltex->Shader = GLShader::Find("Warp 2");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return gltex;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
FGLTexture * FGLTexture::ValidateTexture(int no, bool translate)
|
|
|
|
{
|
|
|
|
return FGLTexture::ValidateTexture(translate? TexMan(no) : TexMan[no]);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// Parses a brightmap definition
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
2008-01-27 15:34:47 +00:00
|
|
|
void gl_ParseBrightmap(FScanner &sc, int deflump)
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
int type = FTexture::TEX_Any;
|
|
|
|
bool disable_fullbright=false;
|
|
|
|
bool thiswad = false;
|
|
|
|
bool iwad = false;
|
|
|
|
int maplump = -1;
|
|
|
|
FString maplumpname;
|
|
|
|
|
2008-01-27 15:34:47 +00:00
|
|
|
sc.MustGetString();
|
|
|
|
if (sc.Compare("texture")) type = FTexture::TEX_Wall;
|
|
|
|
else if (sc.Compare("flat")) type = FTexture::TEX_Flat;
|
|
|
|
else if (sc.Compare("sprite")) type = FTexture::TEX_Sprite;
|
|
|
|
else sc.UnGet();
|
2008-01-27 11:25:03 +00:00
|
|
|
|
2008-01-27 15:34:47 +00:00
|
|
|
sc.MustGetString();
|
|
|
|
int no = TexMan.CheckForTexture(sc.String, type);
|
2008-01-27 11:25:03 +00:00
|
|
|
FTexture *tex = TexMan[no];
|
|
|
|
|
2008-01-27 15:34:47 +00:00
|
|
|
sc.MustGetToken('{');
|
|
|
|
while (!sc.CheckToken('}'))
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2008-01-27 15:34:47 +00:00
|
|
|
sc.MustGetString();
|
|
|
|
if (sc.Compare("disablefullbright"))
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
// This can also be used without a brightness map to disable
|
|
|
|
// fullbright in rotations that only use brightness maps on
|
|
|
|
// other angles.
|
|
|
|
disable_fullbright = true;
|
|
|
|
}
|
2008-01-27 15:34:47 +00:00
|
|
|
else if (sc.Compare("thiswad"))
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
// only affects textures defined in the WAD containing the definition file.
|
|
|
|
thiswad = true;
|
|
|
|
}
|
2008-01-27 15:34:47 +00:00
|
|
|
else if (sc.Compare ("iwad"))
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
|
|
|
// only affects textures defined in the IWAD.
|
|
|
|
iwad = true;
|
|
|
|
}
|
2008-01-27 15:34:47 +00:00
|
|
|
else if (sc.Compare ("map"))
|
2008-01-27 11:25:03 +00:00
|
|
|
{
|
2008-01-27 15:34:47 +00:00
|
|
|
sc.MustGetString();
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
if (maplump >= 0)
|
|
|
|
{
|
|
|
|
Printf("Multiple brightmap definitions in texture %s\n", tex? tex->Name : "(null)");
|
|
|
|
}
|
|
|
|
|
2008-01-27 15:34:47 +00:00
|
|
|
maplump = Wads.CheckNumForFullName(sc.String);
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
// Try a normal WAD name lookup only if it's a proper name without path separator and
|
|
|
|
// not longer than 8 characters.
|
2008-01-27 15:34:47 +00:00
|
|
|
if (maplump==-1 && strlen(sc.String) <= 8 && !strchr(sc.String, '/'))
|
|
|
|
maplump = Wads.CheckNumForName(sc.String);
|
2008-01-27 11:25:03 +00:00
|
|
|
|
|
|
|
if (maplump==-1)
|
2008-01-27 15:34:47 +00:00
|
|
|
Printf("Brightmap '%s' not found in texture '%s'\n", sc.String, tex? tex->Name : "(null)");
|
2008-01-27 11:25:03 +00:00
|
|
|
|
2008-01-27 15:34:47 +00:00
|
|
|
maplumpname = sc.String;
|
2008-01-27 11:25:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!tex)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (thiswad || iwad)
|
|
|
|
{
|
|
|
|
bool useme = false;
|
|
|
|
int lumpnum = tex->GetSourceLump();
|
|
|
|
|
|
|
|
if (lumpnum != -1)
|
|
|
|
{
|
|
|
|
if (iwad && Wads.GetLumpFile(lumpnum) <= FWadCollection::IWAD_FILENUM) useme = true;
|
|
|
|
if (thiswad && Wads.GetLumpFile(lumpnum) == deflump) useme = true;
|
|
|
|
}
|
|
|
|
if (!useme) return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (maplump != -1)
|
|
|
|
{
|
|
|
|
FTexture *brightmap = FTexture::CreateTexture(maplump, tex->UseType);
|
|
|
|
if (!brightmap)
|
|
|
|
{
|
|
|
|
Printf("Unable to create texture from '%s' in brightmap definition for '%s'\n",
|
|
|
|
maplumpname.GetChars(), tex->Name);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
tex->bm_info.Brightmap = brightmap;
|
|
|
|
brightmap->bm_info.bIsBrightmap = true;
|
|
|
|
}
|
|
|
|
tex->bm_info.bBrightmapDisablesFullbright = disable_fullbright;
|
|
|
|
}
|