mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-02-27 22:31:07 +00:00
- moved the span and swtruecolor creation code into FSoftwareTexture.
This commit is contained in:
parent
32e245f2b9
commit
4c67785c40
15 changed files with 608 additions and 630 deletions
|
@ -681,6 +681,7 @@ file( GLOB HEADER_FILES
|
||||||
sound/wildmidi/*.h
|
sound/wildmidi/*.h
|
||||||
xlat/*.h
|
xlat/*.h
|
||||||
swrenderer/*.h
|
swrenderer/*.h
|
||||||
|
swrenderer/textures/*.h
|
||||||
swrenderer/drawers/*.h
|
swrenderer/drawers/*.h
|
||||||
swrenderer/scene/*.h
|
swrenderer/scene/*.h
|
||||||
swrenderer/segments/*.h
|
swrenderer/segments/*.h
|
||||||
|
@ -1244,6 +1245,7 @@ set (PCH_SOURCES
|
||||||
sound/wildmidi/reverb.cpp
|
sound/wildmidi/reverb.cpp
|
||||||
sound/wildmidi/wildmidi_lib.cpp
|
sound/wildmidi/wildmidi_lib.cpp
|
||||||
sound/wildmidi/wm_error.cpp
|
sound/wildmidi/wm_error.cpp
|
||||||
|
swrenderer/textures/r_swtexture.cpp
|
||||||
events.cpp
|
events.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "../swrenderer/textures/r_swtexture.h"
|
||||||
#include "poly_renderer.cpp"
|
#include "poly_renderer.cpp"
|
||||||
#include "poly_renderthread.cpp"
|
#include "poly_renderthread.cpp"
|
||||||
#include "drawers/poly_buffer.cpp"
|
#include "drawers/poly_buffer.cpp"
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "textures/r_swtexture.h"
|
||||||
#include "r_memory.cpp"
|
#include "r_memory.cpp"
|
||||||
#include "r_renderthread.cpp"
|
#include "r_renderthread.cpp"
|
||||||
#include "r_swrenderer.cpp"
|
#include "r_swrenderer.cpp"
|
||||||
|
|
|
@ -84,7 +84,7 @@ void FSoftwareRenderer::PrecacheTexture(FTexture *ttex, int cache)
|
||||||
{
|
{
|
||||||
bool isbgra = V_IsTrueColor();
|
bool isbgra = V_IsTrueColor();
|
||||||
|
|
||||||
if (ttex != NULL)
|
if (ttex != NULL && ttex->isValid())
|
||||||
{
|
{
|
||||||
FSoftwareTexture *tex = ttex->GetSoftwareTexture();
|
FSoftwareTexture *tex = ttex->GetSoftwareTexture();
|
||||||
if (cache & FTextureManager::HIT_Columnmode)
|
if (cache & FTextureManager::HIT_Columnmode)
|
||||||
|
|
453
src/swrenderer/textures/r_swtexture.cpp
Normal file
453
src/swrenderer/textures/r_swtexture.cpp
Normal file
|
@ -0,0 +1,453 @@
|
||||||
|
/*
|
||||||
|
** texture.cpp
|
||||||
|
** The base texture class
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 2004-2007 Randy Heit
|
||||||
|
** Copyright 2006-2018 Christoph Oelckers
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "r_swtexture.h"
|
||||||
|
#include "bitmap.h"
|
||||||
|
#include "m_alloc.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
const uint32_t *FSoftwareTexture::GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out)
|
||||||
|
{
|
||||||
|
const uint32_t *pixels = GetPixelsBgra();
|
||||||
|
if (pixels == nullptr) return nullptr;
|
||||||
|
|
||||||
|
column %= GetWidth();
|
||||||
|
|
||||||
|
if (spans_out != nullptr)
|
||||||
|
GetColumn(DefaultRenderStyle(), column, spans_out); // This isn't the right way to create the spans.
|
||||||
|
return pixels + column * GetHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t *FSoftwareTexture::GetPixelsBgra()
|
||||||
|
{
|
||||||
|
if (PixelsBgra.empty() || mTexture->CheckModified(DefaultRenderStyle()))
|
||||||
|
{
|
||||||
|
if (!GetColumn(DefaultRenderStyle(), 0, nullptr))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
FBitmap bitmap;
|
||||||
|
bitmap.Create(GetWidth(), GetHeight());
|
||||||
|
mTexture->CopyTrueColorPixels(&bitmap, 0, 0);
|
||||||
|
GenerateBgraFromBitmap(bitmap);
|
||||||
|
}
|
||||||
|
return PixelsBgra.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FSoftwareTextureSpan **FSoftwareTexture::CreateSpans (const uint8_t *pixels)
|
||||||
|
{
|
||||||
|
FSoftwareTextureSpan **spans, *span;
|
||||||
|
|
||||||
|
if (!mTexture->isMasked())
|
||||||
|
{ // Texture does not have holes, so it can use a simpler span structure
|
||||||
|
spans = (FSoftwareTextureSpan **)M_Malloc (sizeof(FSoftwareTextureSpan*)*GetWidth() + sizeof(FSoftwareTextureSpan)*2);
|
||||||
|
span = (FSoftwareTextureSpan *)&spans[GetWidth()];
|
||||||
|
for (int x = 0; x < GetWidth(); ++x)
|
||||||
|
{
|
||||||
|
spans[x] = span;
|
||||||
|
}
|
||||||
|
span[0].Length = GetHeight();
|
||||||
|
span[0].TopOffset = 0;
|
||||||
|
span[1].Length = 0;
|
||||||
|
span[1].TopOffset = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Texture might have holes, so build a complete span structure
|
||||||
|
int numcols = GetWidth();
|
||||||
|
int numrows = GetHeight();
|
||||||
|
int numspans = numcols; // One span to terminate each column
|
||||||
|
const uint8_t *data_p;
|
||||||
|
bool newspan;
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
data_p = pixels;
|
||||||
|
|
||||||
|
// Count the number of spans in this texture
|
||||||
|
for (x = numcols; x > 0; --x)
|
||||||
|
{
|
||||||
|
newspan = true;
|
||||||
|
for (y = numrows; y > 0; --y)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (*data_p++ == 0)
|
||||||
|
{
|
||||||
|
if (!newspan)
|
||||||
|
{
|
||||||
|
newspan = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (newspan)
|
||||||
|
{
|
||||||
|
newspan = false;
|
||||||
|
numspans++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate space for the spans
|
||||||
|
spans = (FSoftwareTextureSpan **)M_Malloc (sizeof(FSoftwareTextureSpan*)*numcols + sizeof(FSoftwareTextureSpan)*numspans);
|
||||||
|
|
||||||
|
// Fill in the spans
|
||||||
|
for (x = 0, span = (FSoftwareTextureSpan *)&spans[numcols], data_p = pixels; x < numcols; ++x)
|
||||||
|
{
|
||||||
|
newspan = true;
|
||||||
|
spans[x] = span;
|
||||||
|
for (y = 0; y < numrows; ++y)
|
||||||
|
{
|
||||||
|
if (*data_p++ == 0)
|
||||||
|
{
|
||||||
|
if (!newspan)
|
||||||
|
{
|
||||||
|
newspan = true;
|
||||||
|
span++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (newspan)
|
||||||
|
{
|
||||||
|
newspan = false;
|
||||||
|
span->TopOffset = y;
|
||||||
|
span->Length = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
span->Length++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!newspan)
|
||||||
|
{
|
||||||
|
span++;
|
||||||
|
}
|
||||||
|
span->TopOffset = 0;
|
||||||
|
span->Length = 0;
|
||||||
|
span++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return spans;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSoftwareTexture::FreeSpans (FSoftwareTextureSpan **spans)
|
||||||
|
{
|
||||||
|
M_Free (spans);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FSoftwareTexture::GenerateBgraFromBitmap(const FBitmap &bitmap)
|
||||||
|
{
|
||||||
|
CreatePixelsBgraWithMipmaps();
|
||||||
|
|
||||||
|
// Transpose
|
||||||
|
const uint32_t *src = (const uint32_t *)bitmap.GetPixels();
|
||||||
|
uint32_t *dest = PixelsBgra.data();
|
||||||
|
for (int x = 0; x < GetWidth(); x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < GetHeight(); y++)
|
||||||
|
{
|
||||||
|
dest[y + x * GetHeight()] = src[x + y * GetWidth()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GenerateBgraMipmaps();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FSoftwareTexture::CreatePixelsBgraWithMipmaps()
|
||||||
|
{
|
||||||
|
int levels = MipmapLevels();
|
||||||
|
int buffersize = 0;
|
||||||
|
for (int i = 0; i < levels; i++)
|
||||||
|
{
|
||||||
|
int w = MAX(GetWidth() >> i, 1);
|
||||||
|
int h = MAX(GetHeight() >> i, 1);
|
||||||
|
buffersize += w * h;
|
||||||
|
}
|
||||||
|
PixelsBgra.resize(buffersize, 0xffff0000);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FSoftwareTexture::MipmapLevels()
|
||||||
|
{
|
||||||
|
int widthbits = 0;
|
||||||
|
while ((GetWidth() >> widthbits) != 0) widthbits++;
|
||||||
|
|
||||||
|
int heightbits = 0;
|
||||||
|
while ((GetHeight() >> heightbits) != 0) heightbits++;
|
||||||
|
|
||||||
|
return MAX(widthbits, heightbits);
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FSoftwareTexture::GenerateBgraMipmaps()
|
||||||
|
{
|
||||||
|
struct Color4f
|
||||||
|
{
|
||||||
|
float a, r, g, b;
|
||||||
|
Color4f operator*(const Color4f &v) const { return Color4f{ a * v.a, r * v.r, g * v.g, b * v.b }; }
|
||||||
|
Color4f operator/(const Color4f &v) const { return Color4f{ a / v.a, r / v.r, g / v.g, b / v.b }; }
|
||||||
|
Color4f operator+(const Color4f &v) const { return Color4f{ a + v.a, r + v.r, g + v.g, b + v.b }; }
|
||||||
|
Color4f operator-(const Color4f &v) const { return Color4f{ a - v.a, r - v.r, g - v.g, b - v.b }; }
|
||||||
|
Color4f operator*(float s) const { return Color4f{ a * s, r * s, g * s, b * s }; }
|
||||||
|
Color4f operator/(float s) const { return Color4f{ a / s, r / s, g / s, b / s }; }
|
||||||
|
Color4f operator+(float s) const { return Color4f{ a + s, r + s, g + s, b + s }; }
|
||||||
|
Color4f operator-(float s) const { return Color4f{ a - s, r - s, g - s, b - s }; }
|
||||||
|
};
|
||||||
|
|
||||||
|
int levels = MipmapLevels();
|
||||||
|
std::vector<Color4f> image(PixelsBgra.size());
|
||||||
|
|
||||||
|
// Convert to normalized linear colorspace
|
||||||
|
{
|
||||||
|
for (int x = 0; x < GetWidth(); x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < GetHeight(); y++)
|
||||||
|
{
|
||||||
|
uint32_t c8 = PixelsBgra[x * GetHeight() + y];
|
||||||
|
Color4f c;
|
||||||
|
c.a = powf(APART(c8) * (1.0f / 255.0f), 2.2f);
|
||||||
|
c.r = powf(RPART(c8) * (1.0f / 255.0f), 2.2f);
|
||||||
|
c.g = powf(GPART(c8) * (1.0f / 255.0f), 2.2f);
|
||||||
|
c.b = powf(BPART(c8) * (1.0f / 255.0f), 2.2f);
|
||||||
|
image[x * GetHeight() + y] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate mipmaps
|
||||||
|
{
|
||||||
|
std::vector<Color4f> smoothed(GetWidth() * GetHeight());
|
||||||
|
Color4f *src = image.data();
|
||||||
|
Color4f *dest = src + GetWidth() * GetHeight();
|
||||||
|
for (int i = 1; i < levels; i++)
|
||||||
|
{
|
||||||
|
int srcw = MAX(GetWidth() >> (i - 1), 1);
|
||||||
|
int srch = MAX(GetHeight() >> (i - 1), 1);
|
||||||
|
int w = MAX(GetWidth() >> i, 1);
|
||||||
|
int h = MAX(GetHeight() >> i, 1);
|
||||||
|
|
||||||
|
// Downscale
|
||||||
|
for (int x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
int sx0 = x * 2;
|
||||||
|
int sx1 = MIN((x + 1) * 2, srcw - 1);
|
||||||
|
for (int y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
int sy0 = y * 2;
|
||||||
|
int sy1 = MIN((y + 1) * 2, srch - 1);
|
||||||
|
|
||||||
|
Color4f src00 = src[sy0 + sx0 * srch];
|
||||||
|
Color4f src01 = src[sy1 + sx0 * srch];
|
||||||
|
Color4f src10 = src[sy0 + sx1 * srch];
|
||||||
|
Color4f src11 = src[sy1 + sx1 * srch];
|
||||||
|
Color4f c = (src00 + src01 + src10 + src11) * 0.25f;
|
||||||
|
|
||||||
|
dest[y + x * h] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sharpen filter with a 3x3 kernel:
|
||||||
|
for (int x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
for (int y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
Color4f c = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||||
|
for (int kx = -1; kx < 2; kx++)
|
||||||
|
{
|
||||||
|
for (int ky = -1; ky < 2; ky++)
|
||||||
|
{
|
||||||
|
int a = y + ky;
|
||||||
|
int b = x + kx;
|
||||||
|
if (a < 0) a = h - 1;
|
||||||
|
if (a == h) a = 0;
|
||||||
|
if (b < 0) b = w - 1;
|
||||||
|
if (b == w) b = 0;
|
||||||
|
c = c + dest[a + b * h];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c = c * (1.0f / 9.0f);
|
||||||
|
smoothed[y + x * h] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float k = 0.08f;
|
||||||
|
for (int j = 0; j < w * h; j++)
|
||||||
|
dest[j] = dest[j] + (dest[j] - smoothed[j]) * k;
|
||||||
|
|
||||||
|
src = dest;
|
||||||
|
dest += w * h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to bgra8 sRGB colorspace
|
||||||
|
{
|
||||||
|
Color4f *src = image.data() + GetWidth() * GetHeight();
|
||||||
|
uint32_t *dest = PixelsBgra.data() + GetWidth() * GetHeight();
|
||||||
|
for (int i = 1; i < levels; i++)
|
||||||
|
{
|
||||||
|
int w = MAX(GetWidth() >> i, 1);
|
||||||
|
int h = MAX(GetHeight() >> i, 1);
|
||||||
|
for (int j = 0; j < w * h; j++)
|
||||||
|
{
|
||||||
|
uint32_t a = (uint32_t)clamp(powf(MAX(src[j].a, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f);
|
||||||
|
uint32_t r = (uint32_t)clamp(powf(MAX(src[j].r, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f);
|
||||||
|
uint32_t g = (uint32_t)clamp(powf(MAX(src[j].g, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f);
|
||||||
|
uint32_t b = (uint32_t)clamp(powf(MAX(src[j].b, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f);
|
||||||
|
dest[j] = (a << 24) | (r << 16) | (g << 8) | b;
|
||||||
|
}
|
||||||
|
src += w * h;
|
||||||
|
dest += w * h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FSoftwareTexture::GenerateBgraMipmapsFast()
|
||||||
|
{
|
||||||
|
uint32_t *src = PixelsBgra.data();
|
||||||
|
uint32_t *dest = src + GetWidth() * GetHeight();
|
||||||
|
int levels = MipmapLevels();
|
||||||
|
for (int i = 1; i < levels; i++)
|
||||||
|
{
|
||||||
|
int srcw = MAX(GetWidth() >> (i - 1), 1);
|
||||||
|
int srch = MAX(GetHeight() >> (i - 1), 1);
|
||||||
|
int w = MAX(GetWidth() >> i, 1);
|
||||||
|
int h = MAX(GetHeight() >> i, 1);
|
||||||
|
|
||||||
|
for (int x = 0; x < w; x++)
|
||||||
|
{
|
||||||
|
int sx0 = x * 2;
|
||||||
|
int sx1 = MIN((x + 1) * 2, srcw - 1);
|
||||||
|
|
||||||
|
for (int y = 0; y < h; y++)
|
||||||
|
{
|
||||||
|
int sy0 = y * 2;
|
||||||
|
int sy1 = MIN((y + 1) * 2, srch - 1);
|
||||||
|
|
||||||
|
uint32_t src00 = src[sy0 + sx0 * srch];
|
||||||
|
uint32_t src01 = src[sy1 + sx0 * srch];
|
||||||
|
uint32_t src10 = src[sy0 + sx1 * srch];
|
||||||
|
uint32_t src11 = src[sy1 + sx1 * srch];
|
||||||
|
|
||||||
|
uint32_t alpha = (APART(src00) + APART(src01) + APART(src10) + APART(src11) + 2) / 4;
|
||||||
|
uint32_t red = (RPART(src00) + RPART(src01) + RPART(src10) + RPART(src11) + 2) / 4;
|
||||||
|
uint32_t green = (GPART(src00) + GPART(src01) + GPART(src10) + GPART(src11) + 2) / 4;
|
||||||
|
uint32_t blue = (BPART(src00) + BPART(src01) + BPART(src10) + BPART(src11) + 2) / 4;
|
||||||
|
|
||||||
|
dest[y + x * h] = (alpha << 24) | (red << 16) | (green << 8) | blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
src = dest;
|
||||||
|
dest += w * h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
const uint8_t *FSoftwareTexture::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out)
|
||||||
|
{
|
||||||
|
int index = !!(style.Flags & STYLEF_RedIsAlpha);
|
||||||
|
auto Pixeldata = GetPixels(style);
|
||||||
|
if ((unsigned)column >= (unsigned)GetWidth())
|
||||||
|
{
|
||||||
|
if (mTexture->WidthMask + 1 == GetWidth())
|
||||||
|
{
|
||||||
|
column &= mTexture->WidthMask;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
column %= GetWidth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (spans_out != nullptr)
|
||||||
|
{
|
||||||
|
if (Spandata[index] == nullptr)
|
||||||
|
{
|
||||||
|
Spandata[index] = CreateSpans (Pixeldata);
|
||||||
|
}
|
||||||
|
*spans_out = Spandata[index][column];
|
||||||
|
}
|
||||||
|
return Pixeldata + column*GetHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FSoftwareTexture::FreeAllSpans()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
if (Spandata[i] != nullptr)
|
||||||
|
{
|
||||||
|
FreeSpans (Spandata[i]);
|
||||||
|
Spandata[i] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
129
src/swrenderer/textures/r_swtexture.h
Normal file
129
src/swrenderer/textures/r_swtexture.h
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
#pragma once
|
||||||
|
#include "textures/textures.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct FSoftwareTextureSpan
|
||||||
|
{
|
||||||
|
uint16_t TopOffset;
|
||||||
|
uint16_t Length; // A length of 0 terminates this column
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// For now this is just a minimal wrapper around FTexture. Once the software renderer no longer accesses FTexture directly, it is time for cleaning up.
|
||||||
|
class FSoftwareTexture
|
||||||
|
{
|
||||||
|
FTexture *mTexture;
|
||||||
|
FTexture *mSource;
|
||||||
|
std::vector<uint32_t> PixelsBgra;
|
||||||
|
FSoftwareTextureSpan **Spandata[2] = { nullptr, nullptr };
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
FSoftwareTexture(FTexture *tex)
|
||||||
|
{
|
||||||
|
mTexture = tex;
|
||||||
|
mSource = tex;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~FSoftwareTexture()
|
||||||
|
{
|
||||||
|
FreeAllSpans();
|
||||||
|
}
|
||||||
|
|
||||||
|
FTexture *GetTexture() const
|
||||||
|
{
|
||||||
|
return mTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The feature from hell... :(
|
||||||
|
bool useWorldPanning() const
|
||||||
|
{
|
||||||
|
return mTexture->bWorldPanning;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMasked()
|
||||||
|
{
|
||||||
|
return mTexture->bMasked;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UseBasePalette() const { return mTexture->UseBasePalette(); }
|
||||||
|
int GetSkyOffset() const { return mTexture->GetSkyOffset(); }
|
||||||
|
PalEntry GetSkyCapColor(bool bottom) const { return mTexture->GetSkyCapColor(bottom); }
|
||||||
|
|
||||||
|
int GetWidth () { return mTexture->GetWidth(); }
|
||||||
|
int GetHeight () { return mTexture->GetHeight(); }
|
||||||
|
int GetWidthBits() { return mTexture->WidthBits; }
|
||||||
|
int GetHeightBits() { return mTexture->HeightBits; }
|
||||||
|
bool Mipmapped() { return mTexture->Mipmapped(); }
|
||||||
|
|
||||||
|
int GetScaledWidth () { return mTexture->GetScaledWidth(); }
|
||||||
|
int GetScaledHeight () { return mTexture->GetScaledHeight(); }
|
||||||
|
double GetScaledWidthDouble () { return mTexture->GetScaledWidthDouble(); }
|
||||||
|
double GetScaledHeightDouble () { return mTexture->GetScaledHeightDouble(); }
|
||||||
|
double GetScaleY() const { return mTexture->GetScaleY(); }
|
||||||
|
|
||||||
|
// Now with improved offset adjustment.
|
||||||
|
int GetLeftOffset(int adjusted) { return mTexture->GetLeftOffset(adjusted); }
|
||||||
|
int GetTopOffset(int adjusted) { return mTexture->GetTopOffset(adjusted); }
|
||||||
|
int GetScaledLeftOffset (int adjusted) { return mTexture->GetScaledLeftOffset(adjusted); }
|
||||||
|
int GetScaledTopOffset (int adjusted) { return mTexture->GetScaledTopOffset(adjusted); }
|
||||||
|
double GetScaledLeftOffsetDouble(int adjusted) { return mTexture->GetScaledLeftOffsetDouble(adjusted); }
|
||||||
|
double GetScaledTopOffsetDouble(int adjusted) { return mTexture->GetScaledTopOffsetDouble(adjusted); }
|
||||||
|
|
||||||
|
// Interfaces for the different renderers. Everything that needs to check renderer-dependent offsets
|
||||||
|
// should use these, so that if changes are needed, this is the only place to edit.
|
||||||
|
|
||||||
|
// For the original software renderer
|
||||||
|
int GetLeftOffsetSW() { return GetLeftOffset(r_spriteadjustSW); }
|
||||||
|
int GetTopOffsetSW() { return GetTopOffset(r_spriteadjustSW); }
|
||||||
|
int GetScaledLeftOffsetSW() { return GetScaledLeftOffset(r_spriteadjustSW); }
|
||||||
|
int GetScaledTopOffsetSW() { return GetScaledTopOffset(r_spriteadjustSW); }
|
||||||
|
|
||||||
|
// For the softpoly renderer, in case it wants adjustment
|
||||||
|
int GetLeftOffsetPo() { return GetLeftOffset(r_spriteadjustSW); }
|
||||||
|
int GetTopOffsetPo() { return GetTopOffset(r_spriteadjustSW); }
|
||||||
|
int GetScaledLeftOffsetPo() { return GetScaledLeftOffset(r_spriteadjustSW); }
|
||||||
|
int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); }
|
||||||
|
|
||||||
|
DVector2 GetScale() const { return mTexture->Scale; }
|
||||||
|
|
||||||
|
// Returns the whole texture, stored in column-major order
|
||||||
|
const uint8_t *GetPixels(FRenderStyle style)
|
||||||
|
{
|
||||||
|
return mTexture->GetPixels(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unload()
|
||||||
|
{
|
||||||
|
mTexture->Unload();
|
||||||
|
PixelsBgra = std::vector<uint32_t>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateBgraFromBitmap(const FBitmap &bitmap);
|
||||||
|
void CreatePixelsBgraWithMipmaps();
|
||||||
|
void GenerateBgraMipmaps();
|
||||||
|
void GenerateBgraMipmapsFast();
|
||||||
|
int MipmapLevels();
|
||||||
|
void FreeAllSpans();
|
||||||
|
|
||||||
|
FSoftwareTextureSpan **CreateSpans (const uint8_t *pixels);
|
||||||
|
void FreeSpans (FSoftwareTextureSpan **spans);
|
||||||
|
|
||||||
|
// Returns a single column of the texture
|
||||||
|
virtual const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out);
|
||||||
|
|
||||||
|
// Returns a single column of the texture, in BGRA8 format
|
||||||
|
virtual const uint32_t *GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out);
|
||||||
|
|
||||||
|
// Returns the whole texture, stored in column-major order, in BGRA8 format
|
||||||
|
virtual const uint32_t *GetPixelsBgra();
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
inline FSoftwareTexture *FTexture::GetSoftwareTexture()
|
||||||
|
{
|
||||||
|
if (!SoftwareTexture) SoftwareTexture = new FSoftwareTexture(this);
|
||||||
|
return SoftwareTexture;
|
||||||
|
}
|
|
@ -44,10 +44,12 @@ FCanvasTexture::FCanvasTexture (const char *name, int width, int height)
|
||||||
CalcBitSize ();
|
CalcBitSize ();
|
||||||
|
|
||||||
bMasked = false;
|
bMasked = false;
|
||||||
|
/*
|
||||||
DummySpans[0].TopOffset = 0;
|
DummySpans[0].TopOffset = 0;
|
||||||
DummySpans[0].Length = height;
|
DummySpans[0].Length = height;
|
||||||
DummySpans[1].TopOffset = 0;
|
DummySpans[1].TopOffset = 0;
|
||||||
DummySpans[1].Length = 0;
|
DummySpans[1].Length = 0;
|
||||||
|
*/
|
||||||
UseType = ETextureType::Wall;
|
UseType = ETextureType::Wall;
|
||||||
bNeedsUpdate = true;
|
bNeedsUpdate = true;
|
||||||
bDidUpdate = false;
|
bDidUpdate = false;
|
||||||
|
@ -61,6 +63,7 @@ FCanvasTexture::~FCanvasTexture ()
|
||||||
Unload ();
|
Unload ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
const uint8_t *FCanvasTexture::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out)
|
const uint8_t *FCanvasTexture::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out)
|
||||||
{
|
{
|
||||||
bNeedsUpdate = true;
|
bNeedsUpdate = true;
|
||||||
|
@ -85,6 +88,7 @@ const uint8_t *FCanvasTexture::GetColumn(FRenderStyle style, unsigned int column
|
||||||
}
|
}
|
||||||
return Pixels + column*Height;
|
return Pixels + column*Height;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const uint8_t *FCanvasTexture::GetPixels (FRenderStyle style)
|
const uint8_t *FCanvasTexture::GetPixels (FRenderStyle style)
|
||||||
{
|
{
|
||||||
|
@ -96,6 +100,7 @@ const uint8_t *FCanvasTexture::GetPixels (FRenderStyle style)
|
||||||
return Pixels;
|
return Pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
const uint32_t *FCanvasTexture::GetPixelsBgra()
|
const uint32_t *FCanvasTexture::GetPixelsBgra()
|
||||||
{
|
{
|
||||||
bNeedsUpdate = true;
|
bNeedsUpdate = true;
|
||||||
|
@ -105,6 +110,7 @@ const uint32_t *FCanvasTexture::GetPixelsBgra()
|
||||||
}
|
}
|
||||||
return PixelsBgra;
|
return PixelsBgra;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style because making it work as alpha texture is impractical.
|
void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style because making it work as alpha texture is impractical.
|
||||||
{
|
{
|
||||||
|
|
|
@ -164,7 +164,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint8_t *Pixels;
|
uint8_t *Pixels;
|
||||||
FSoftwareTextureSpan **Spans;
|
//FSoftwareTextureSpan **Spans;
|
||||||
int DefinitionLump;
|
int DefinitionLump;
|
||||||
|
|
||||||
struct TexPart
|
struct TexPart
|
||||||
|
@ -199,8 +199,6 @@ protected:
|
||||||
|
|
||||||
// The getters must optionally redirect if it's a simple one-patch texture.
|
// The getters must optionally redirect if it's a simple one-patch texture.
|
||||||
const uint8_t *GetPixels(FRenderStyle style) override { return bRedirect ? Parts->Texture->GetPixels(style) : FWorldTexture::GetPixels(style); }
|
const uint8_t *GetPixels(FRenderStyle style) override { return bRedirect ? Parts->Texture->GetPixels(style) : FWorldTexture::GetPixels(style); }
|
||||||
const uint8_t *GetColumn(FRenderStyle style, unsigned int col, const FSoftwareTextureSpan **out) override
|
|
||||||
{ return bRedirect ? Parts->Texture->GetColumn(style, col, out) : FWorldTexture::GetColumn(style, col, out); }
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -215,7 +213,7 @@ private:
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum)
|
FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum)
|
||||||
: Pixels (0), Spans(0), Parts(nullptr), Inits(nullptr), bRedirect(false), bTranslucentPatches(false)
|
: Pixels (0), Parts(nullptr), Inits(nullptr), bRedirect(false), bTranslucentPatches(false)
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
@ -1065,7 +1063,7 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, TexInit &init)
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, ETextureType usetype)
|
FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, ETextureType usetype)
|
||||||
: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false)
|
: Pixels (0), Parts(0), bRedirect(false), bTranslucentPatches(false)
|
||||||
{
|
{
|
||||||
TArray<TexPart> parts;
|
TArray<TexPart> parts;
|
||||||
TArray<TexInit> inits;
|
TArray<TexInit> inits;
|
||||||
|
|
|
@ -59,7 +59,7 @@ void FWarpTexture::Unload ()
|
||||||
{
|
{
|
||||||
SourcePic->Unload ();
|
SourcePic->Unload ();
|
||||||
FWorldTexture::Unload();
|
FWorldTexture::Unload();
|
||||||
FreeAllSpans();
|
//FreeAllSpans();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FWarpTexture::CheckModified (FRenderStyle style)
|
bool FWarpTexture::CheckModified (FRenderStyle style)
|
||||||
|
@ -67,6 +67,7 @@ bool FWarpTexture::CheckModified (FRenderStyle style)
|
||||||
return screen->FrameTime != GenTime[!!(style.Flags & STYLEF_RedIsAlpha)];
|
return screen->FrameTime != GenTime[!!(style.Flags & STYLEF_RedIsAlpha)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
const uint32_t *FWarpTexture::GetPixelsBgra()
|
const uint32_t *FWarpTexture::GetPixelsBgra()
|
||||||
{
|
{
|
||||||
auto Pixels = GetPixels(DefaultRenderStyle());
|
auto Pixels = GetPixels(DefaultRenderStyle());
|
||||||
|
@ -85,6 +86,7 @@ const uint32_t *FWarpTexture::GetPixelsBgra()
|
||||||
}
|
}
|
||||||
return PixelsBgra.data();
|
return PixelsBgra.data();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
uint8_t *FWarpTexture::MakeTexture(FRenderStyle style)
|
uint8_t *FWarpTexture::MakeTexture(FRenderStyle style)
|
||||||
|
@ -93,7 +95,7 @@ uint8_t *FWarpTexture::MakeTexture(FRenderStyle style)
|
||||||
const uint8_t *otherpix = SourcePic->GetPixels(style);
|
const uint8_t *otherpix = SourcePic->GetPixels(style);
|
||||||
auto Pixels = new uint8_t[Width * Height];
|
auto Pixels = new uint8_t[Width * Height];
|
||||||
WarpBuffer(Pixels, otherpix, Width, Height, WidthOffsetMultiplier, HeightOffsetMultiplier, time, Speed, bWarped);
|
WarpBuffer(Pixels, otherpix, Width, Height, WidthOffsetMultiplier, HeightOffsetMultiplier, time, Speed, bWarped);
|
||||||
FreeAllSpans();
|
//FreeAllSpans();
|
||||||
GenTime[!!(style.Flags & STYLEF_RedIsAlpha)] = time;
|
GenTime[!!(style.Flags & STYLEF_RedIsAlpha)] = time;
|
||||||
return Pixels;
|
return Pixels;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,25 +56,6 @@ FWorldTexture::FWorldTexture(const char *name, int lumpnum)
|
||||||
FWorldTexture::~FWorldTexture()
|
FWorldTexture::~FWorldTexture()
|
||||||
{
|
{
|
||||||
Unload();
|
Unload();
|
||||||
FreeAllSpans();
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FWorldTexture::FreeAllSpans()
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
if (Spandata[i] != nullptr)
|
|
||||||
{
|
|
||||||
FreeSpans (Spandata[i]);
|
|
||||||
Spandata[i] = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -102,38 +83,6 @@ void FWorldTexture::Unload ()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
const uint8_t *FWorldTexture::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out)
|
|
||||||
{
|
|
||||||
int index = !!(style.Flags & STYLEF_RedIsAlpha);
|
|
||||||
GetPixels(style);
|
|
||||||
if ((unsigned)column >= (unsigned)Width)
|
|
||||||
{
|
|
||||||
if (WidthMask + 1 == Width)
|
|
||||||
{
|
|
||||||
column &= WidthMask;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
column %= Width;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (spans_out != nullptr)
|
|
||||||
{
|
|
||||||
if (Spandata[index] == nullptr)
|
|
||||||
{
|
|
||||||
Spandata[index] = CreateSpans (Pixeldata[index]);
|
|
||||||
}
|
|
||||||
*spans_out = Spandata[index][column];
|
|
||||||
}
|
|
||||||
return Pixeldata[index] + column*Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
const uint8_t *FWorldTexture::GetPixels (FRenderStyle style)
|
const uint8_t *FWorldTexture::GetPixels (FRenderStyle style)
|
||||||
{
|
{
|
||||||
if (CheckModified(style))
|
if (CheckModified(style))
|
||||||
|
|
|
@ -53,18 +53,6 @@ FSkyBox::~FSkyBox()
|
||||||
// The faces are only referenced but not owned so don't delete them.
|
// The faces are only referenced but not owned so don't delete them.
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// If something attempts to use this as a texture just pass the information of the first face.
|
|
||||||
//
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
const uint8_t *FSkyBox::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out)
|
|
||||||
{
|
|
||||||
if (faces[0]) return faces[0]->GetColumn(style, column, spans_out);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
|
@ -17,7 +17,7 @@ public:
|
||||||
|
|
||||||
FSkyBox(const char *name = nullptr);
|
FSkyBox(const char *name = nullptr);
|
||||||
~FSkyBox();
|
~FSkyBox();
|
||||||
const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out);
|
//const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out);
|
||||||
const uint8_t *GetPixels (FRenderStyle style);
|
const uint8_t *GetPixels (FRenderStyle style);
|
||||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf);
|
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf);
|
||||||
bool UseBasePalette();
|
bool UseBasePalette();
|
||||||
|
|
|
@ -231,40 +231,6 @@ FTexture::~FTexture ()
|
||||||
|
|
||||||
void FTexture::Unload()
|
void FTexture::Unload()
|
||||||
{
|
{
|
||||||
PixelsBgra = std::vector<uint32_t>();
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
const uint32_t *FTexture::GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out)
|
|
||||||
{
|
|
||||||
const uint32_t *pixels = GetPixelsBgra();
|
|
||||||
if (pixels == nullptr) return nullptr;
|
|
||||||
|
|
||||||
column %= Width;
|
|
||||||
|
|
||||||
if (spans_out != nullptr)
|
|
||||||
GetColumn(DefaultRenderStyle(), column, spans_out); // This isn't the right way to create the spans.
|
|
||||||
return pixels + column * Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint32_t *FTexture::GetPixelsBgra()
|
|
||||||
{
|
|
||||||
if (PixelsBgra.empty() || CheckModified(DefaultRenderStyle()))
|
|
||||||
{
|
|
||||||
if (!GetColumn(DefaultRenderStyle(), 0, nullptr))
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
FBitmap bitmap;
|
|
||||||
bitmap.Create(GetWidth(), GetHeight());
|
|
||||||
CopyTrueColorPixels(&bitmap, 0, 0);
|
|
||||||
GenerateBgraFromBitmap(bitmap);
|
|
||||||
}
|
|
||||||
return PixelsBgra.data();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -327,333 +293,6 @@ void FTexture::CalcBitSize ()
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FSoftwareTextureSpan **FTexture::CreateSpans (const uint8_t *pixels) const
|
|
||||||
{
|
|
||||||
FSoftwareTextureSpan **spans, *span;
|
|
||||||
|
|
||||||
if (!bMasked)
|
|
||||||
{ // Texture does not have holes, so it can use a simpler span structure
|
|
||||||
spans = (FSoftwareTextureSpan **)M_Malloc (sizeof(FSoftwareTextureSpan*)*Width + sizeof(FSoftwareTextureSpan)*2);
|
|
||||||
span = (FSoftwareTextureSpan *)&spans[Width];
|
|
||||||
for (int x = 0; x < Width; ++x)
|
|
||||||
{
|
|
||||||
spans[x] = span;
|
|
||||||
}
|
|
||||||
span[0].Length = Height;
|
|
||||||
span[0].TopOffset = 0;
|
|
||||||
span[1].Length = 0;
|
|
||||||
span[1].TopOffset = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // Texture might have holes, so build a complete span structure
|
|
||||||
int numcols = Width;
|
|
||||||
int numrows = Height;
|
|
||||||
int numspans = numcols; // One span to terminate each column
|
|
||||||
const uint8_t *data_p;
|
|
||||||
bool newspan;
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
data_p = pixels;
|
|
||||||
|
|
||||||
// Count the number of spans in this texture
|
|
||||||
for (x = numcols; x > 0; --x)
|
|
||||||
{
|
|
||||||
newspan = true;
|
|
||||||
for (y = numrows; y > 0; --y)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (*data_p++ == 0)
|
|
||||||
{
|
|
||||||
if (!newspan)
|
|
||||||
{
|
|
||||||
newspan = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (newspan)
|
|
||||||
{
|
|
||||||
newspan = false;
|
|
||||||
numspans++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocate space for the spans
|
|
||||||
spans = (FSoftwareTextureSpan **)M_Malloc (sizeof(FSoftwareTextureSpan*)*numcols + sizeof(FSoftwareTextureSpan)*numspans);
|
|
||||||
|
|
||||||
// Fill in the spans
|
|
||||||
for (x = 0, span = (FSoftwareTextureSpan *)&spans[numcols], data_p = pixels; x < numcols; ++x)
|
|
||||||
{
|
|
||||||
newspan = true;
|
|
||||||
spans[x] = span;
|
|
||||||
for (y = 0; y < numrows; ++y)
|
|
||||||
{
|
|
||||||
if (*data_p++ == 0)
|
|
||||||
{
|
|
||||||
if (!newspan)
|
|
||||||
{
|
|
||||||
newspan = true;
|
|
||||||
span++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (newspan)
|
|
||||||
{
|
|
||||||
newspan = false;
|
|
||||||
span->TopOffset = y;
|
|
||||||
span->Length = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
span->Length++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!newspan)
|
|
||||||
{
|
|
||||||
span++;
|
|
||||||
}
|
|
||||||
span->TopOffset = 0;
|
|
||||||
span->Length = 0;
|
|
||||||
span++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return spans;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FTexture::FreeSpans (FSoftwareTextureSpan **spans) const
|
|
||||||
{
|
|
||||||
M_Free (spans);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FTexture::GenerateBgraFromBitmap(const FBitmap &bitmap)
|
|
||||||
{
|
|
||||||
CreatePixelsBgraWithMipmaps();
|
|
||||||
|
|
||||||
// Transpose
|
|
||||||
const uint32_t *src = (const uint32_t *)bitmap.GetPixels();
|
|
||||||
uint32_t *dest = PixelsBgra.data();
|
|
||||||
for (int x = 0; x < Width; x++)
|
|
||||||
{
|
|
||||||
for (int y = 0; y < Height; y++)
|
|
||||||
{
|
|
||||||
dest[y + x * Height] = src[x + y * Width];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GenerateBgraMipmaps();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FTexture::CreatePixelsBgraWithMipmaps()
|
|
||||||
{
|
|
||||||
int levels = MipmapLevels();
|
|
||||||
int buffersize = 0;
|
|
||||||
for (int i = 0; i < levels; i++)
|
|
||||||
{
|
|
||||||
int w = MAX(Width >> i, 1);
|
|
||||||
int h = MAX(Height >> i, 1);
|
|
||||||
buffersize += w * h;
|
|
||||||
}
|
|
||||||
PixelsBgra.resize(buffersize, 0xffff0000);
|
|
||||||
}
|
|
||||||
|
|
||||||
int FTexture::MipmapLevels() const
|
|
||||||
{
|
|
||||||
int widthbits = 0;
|
|
||||||
while ((Width >> widthbits) != 0) widthbits++;
|
|
||||||
|
|
||||||
int heightbits = 0;
|
|
||||||
while ((Height >> heightbits) != 0) heightbits++;
|
|
||||||
|
|
||||||
return MAX(widthbits, heightbits);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FTexture::GenerateBgraMipmaps()
|
|
||||||
{
|
|
||||||
struct Color4f
|
|
||||||
{
|
|
||||||
float a, r, g, b;
|
|
||||||
Color4f operator*(const Color4f &v) const { return Color4f{ a * v.a, r * v.r, g * v.g, b * v.b }; }
|
|
||||||
Color4f operator/(const Color4f &v) const { return Color4f{ a / v.a, r / v.r, g / v.g, b / v.b }; }
|
|
||||||
Color4f operator+(const Color4f &v) const { return Color4f{ a + v.a, r + v.r, g + v.g, b + v.b }; }
|
|
||||||
Color4f operator-(const Color4f &v) const { return Color4f{ a - v.a, r - v.r, g - v.g, b - v.b }; }
|
|
||||||
Color4f operator*(float s) const { return Color4f{ a * s, r * s, g * s, b * s }; }
|
|
||||||
Color4f operator/(float s) const { return Color4f{ a / s, r / s, g / s, b / s }; }
|
|
||||||
Color4f operator+(float s) const { return Color4f{ a + s, r + s, g + s, b + s }; }
|
|
||||||
Color4f operator-(float s) const { return Color4f{ a - s, r - s, g - s, b - s }; }
|
|
||||||
};
|
|
||||||
|
|
||||||
int levels = MipmapLevels();
|
|
||||||
std::vector<Color4f> image(PixelsBgra.size());
|
|
||||||
|
|
||||||
// Convert to normalized linear colorspace
|
|
||||||
{
|
|
||||||
for (int x = 0; x < Width; x++)
|
|
||||||
{
|
|
||||||
for (int y = 0; y < Height; y++)
|
|
||||||
{
|
|
||||||
uint32_t c8 = PixelsBgra[x * Height + y];
|
|
||||||
Color4f c;
|
|
||||||
c.a = powf(APART(c8) * (1.0f / 255.0f), 2.2f);
|
|
||||||
c.r = powf(RPART(c8) * (1.0f / 255.0f), 2.2f);
|
|
||||||
c.g = powf(GPART(c8) * (1.0f / 255.0f), 2.2f);
|
|
||||||
c.b = powf(BPART(c8) * (1.0f / 255.0f), 2.2f);
|
|
||||||
image[x * Height + y] = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate mipmaps
|
|
||||||
{
|
|
||||||
std::vector<Color4f> smoothed(Width * Height);
|
|
||||||
Color4f *src = image.data();
|
|
||||||
Color4f *dest = src + Width * Height;
|
|
||||||
for (int i = 1; i < levels; i++)
|
|
||||||
{
|
|
||||||
int srcw = MAX(Width >> (i - 1), 1);
|
|
||||||
int srch = MAX(Height >> (i - 1), 1);
|
|
||||||
int w = MAX(Width >> i, 1);
|
|
||||||
int h = MAX(Height >> i, 1);
|
|
||||||
|
|
||||||
// Downscale
|
|
||||||
for (int x = 0; x < w; x++)
|
|
||||||
{
|
|
||||||
int sx0 = x * 2;
|
|
||||||
int sx1 = MIN((x + 1) * 2, srcw - 1);
|
|
||||||
for (int y = 0; y < h; y++)
|
|
||||||
{
|
|
||||||
int sy0 = y * 2;
|
|
||||||
int sy1 = MIN((y + 1) * 2, srch - 1);
|
|
||||||
|
|
||||||
Color4f src00 = src[sy0 + sx0 * srch];
|
|
||||||
Color4f src01 = src[sy1 + sx0 * srch];
|
|
||||||
Color4f src10 = src[sy0 + sx1 * srch];
|
|
||||||
Color4f src11 = src[sy1 + sx1 * srch];
|
|
||||||
Color4f c = (src00 + src01 + src10 + src11) * 0.25f;
|
|
||||||
|
|
||||||
dest[y + x * h] = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sharpen filter with a 3x3 kernel:
|
|
||||||
for (int x = 0; x < w; x++)
|
|
||||||
{
|
|
||||||
for (int y = 0; y < h; y++)
|
|
||||||
{
|
|
||||||
Color4f c = { 0.0f, 0.0f, 0.0f, 0.0f };
|
|
||||||
for (int kx = -1; kx < 2; kx++)
|
|
||||||
{
|
|
||||||
for (int ky = -1; ky < 2; ky++)
|
|
||||||
{
|
|
||||||
int a = y + ky;
|
|
||||||
int b = x + kx;
|
|
||||||
if (a < 0) a = h - 1;
|
|
||||||
if (a == h) a = 0;
|
|
||||||
if (b < 0) b = w - 1;
|
|
||||||
if (b == w) b = 0;
|
|
||||||
c = c + dest[a + b * h];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c = c * (1.0f / 9.0f);
|
|
||||||
smoothed[y + x * h] = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
float k = 0.08f;
|
|
||||||
for (int j = 0; j < w * h; j++)
|
|
||||||
dest[j] = dest[j] + (dest[j] - smoothed[j]) * k;
|
|
||||||
|
|
||||||
src = dest;
|
|
||||||
dest += w * h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert to bgra8 sRGB colorspace
|
|
||||||
{
|
|
||||||
Color4f *src = image.data() + Width * Height;
|
|
||||||
uint32_t *dest = PixelsBgra.data() + Width * Height;
|
|
||||||
for (int i = 1; i < levels; i++)
|
|
||||||
{
|
|
||||||
int w = MAX(Width >> i, 1);
|
|
||||||
int h = MAX(Height >> i, 1);
|
|
||||||
for (int j = 0; j < w * h; j++)
|
|
||||||
{
|
|
||||||
uint32_t a = (uint32_t)clamp(powf(MAX(src[j].a, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f);
|
|
||||||
uint32_t r = (uint32_t)clamp(powf(MAX(src[j].r, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f);
|
|
||||||
uint32_t g = (uint32_t)clamp(powf(MAX(src[j].g, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f);
|
|
||||||
uint32_t b = (uint32_t)clamp(powf(MAX(src[j].b, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f);
|
|
||||||
dest[j] = (a << 24) | (r << 16) | (g << 8) | b;
|
|
||||||
}
|
|
||||||
src += w * h;
|
|
||||||
dest += w * h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FTexture::GenerateBgraMipmapsFast()
|
|
||||||
{
|
|
||||||
uint32_t *src = PixelsBgra.data();
|
|
||||||
uint32_t *dest = src + Width * Height;
|
|
||||||
int levels = MipmapLevels();
|
|
||||||
for (int i = 1; i < levels; i++)
|
|
||||||
{
|
|
||||||
int srcw = MAX(Width >> (i - 1), 1);
|
|
||||||
int srch = MAX(Height >> (i - 1), 1);
|
|
||||||
int w = MAX(Width >> i, 1);
|
|
||||||
int h = MAX(Height >> i, 1);
|
|
||||||
|
|
||||||
for (int x = 0; x < w; x++)
|
|
||||||
{
|
|
||||||
int sx0 = x * 2;
|
|
||||||
int sx1 = MIN((x + 1) * 2, srcw - 1);
|
|
||||||
|
|
||||||
for (int y = 0; y < h; y++)
|
|
||||||
{
|
|
||||||
int sy0 = y * 2;
|
|
||||||
int sy1 = MIN((y + 1) * 2, srch - 1);
|
|
||||||
|
|
||||||
uint32_t src00 = src[sy0 + sx0 * srch];
|
|
||||||
uint32_t src01 = src[sy1 + sx0 * srch];
|
|
||||||
uint32_t src10 = src[sy0 + sx1 * srch];
|
|
||||||
uint32_t src11 = src[sy1 + sx1 * srch];
|
|
||||||
|
|
||||||
uint32_t alpha = (APART(src00) + APART(src01) + APART(src10) + APART(src11) + 2) / 4;
|
|
||||||
uint32_t red = (RPART(src00) + RPART(src01) + RPART(src10) + RPART(src11) + 2) / 4;
|
|
||||||
uint32_t green = (GPART(src00) + GPART(src01) + GPART(src10) + GPART(src11) + 2) / 4;
|
|
||||||
uint32_t blue = (BPART(src00) + BPART(src01) + BPART(src10) + BPART(src11) + 2) / 4;
|
|
||||||
|
|
||||||
dest[y + x * h] = (alpha << 24) | (red << 16) | (green << 8) | blue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
src = dest;
|
|
||||||
dest += w * h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, int ypos, int rotate, const uint8_t *translation, FRenderStyle style)
|
void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, int ypos, int rotate, const uint8_t *translation, FRenderStyle style)
|
||||||
{
|
{
|
||||||
const uint8_t *pixels = GetPixels(style);
|
const uint8_t *pixels = GetPixels(style);
|
||||||
|
@ -1454,11 +1093,6 @@ void FTexture::SetSpriteAdjust()
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
const uint8_t *FTexture::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t *FTexture::GetPixels(FRenderStyle style)
|
const uint8_t *FTexture::GetPixels(FRenderStyle style)
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -214,12 +214,6 @@ enum FTextureFormat : uint32_t
|
||||||
class FSoftwareTexture;
|
class FSoftwareTexture;
|
||||||
class FGLRenderState;
|
class FGLRenderState;
|
||||||
|
|
||||||
struct FSoftwareTextureSpan
|
|
||||||
{
|
|
||||||
uint16_t TopOffset;
|
|
||||||
uint16_t Length; // A length of 0 terminates this column
|
|
||||||
};
|
|
||||||
|
|
||||||
struct spriteframewithrotate;
|
struct spriteframewithrotate;
|
||||||
class FSerializer;
|
class FSerializer;
|
||||||
namespace OpenGLRenderer
|
namespace OpenGLRenderer
|
||||||
|
@ -388,19 +382,9 @@ protected:
|
||||||
int shaderindex = 0;
|
int shaderindex = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Returns a single column of the texture
|
|
||||||
virtual const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out);
|
|
||||||
|
|
||||||
// Returns a single column of the texture, in BGRA8 format
|
|
||||||
virtual const uint32_t *GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out);
|
|
||||||
|
|
||||||
// Returns the whole texture, stored in column-major order
|
// Returns the whole texture, stored in column-major order
|
||||||
virtual const uint8_t *GetPixels(FRenderStyle style);
|
virtual const uint8_t *GetPixels(FRenderStyle style);
|
||||||
|
|
||||||
// Returns the whole texture, stored in column-major order, in BGRA8 format
|
|
||||||
virtual const uint32_t *GetPixelsBgra();
|
|
||||||
|
|
||||||
// Returns true if GetPixelsBgra includes mipmaps
|
// Returns true if GetPixelsBgra includes mipmaps
|
||||||
virtual bool Mipmapped() { return true; }
|
virtual bool Mipmapped() { return true; }
|
||||||
|
|
||||||
|
@ -535,8 +519,6 @@ protected:
|
||||||
|
|
||||||
FTexture (const char *name = NULL, int lumpnum = -1);
|
FTexture (const char *name = NULL, int lumpnum = -1);
|
||||||
|
|
||||||
FSoftwareTextureSpan **CreateSpans (const uint8_t *pixels) const;
|
|
||||||
void FreeSpans (FSoftwareTextureSpan **spans) const;
|
|
||||||
void CalcBitSize ();
|
void CalcBitSize ();
|
||||||
void CopyInfo(FTexture *other)
|
void CopyInfo(FTexture *other)
|
||||||
{
|
{
|
||||||
|
@ -545,13 +527,6 @@ protected:
|
||||||
Rotations = other->Rotations;
|
Rotations = other->Rotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint32_t> PixelsBgra;
|
|
||||||
|
|
||||||
void GenerateBgraFromBitmap(const FBitmap &bitmap);
|
|
||||||
void CreatePixelsBgraWithMipmaps();
|
|
||||||
void GenerateBgraMipmaps();
|
|
||||||
void GenerateBgraMipmapsFast();
|
|
||||||
int MipmapLevels() const;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -577,112 +552,6 @@ public:
|
||||||
friend class FTextureManager;
|
friend class FTextureManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
// For now this is just a minimal wrapper around FTexture. Once the software renderer no longer accesses FTexture directly, it is time for cleaning up.
|
|
||||||
class FSoftwareTexture
|
|
||||||
{
|
|
||||||
FTexture *mTexture;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
FSoftwareTexture(FTexture *tex)
|
|
||||||
{
|
|
||||||
mTexture = tex;
|
|
||||||
}
|
|
||||||
|
|
||||||
FTexture *GetTexture() const
|
|
||||||
{
|
|
||||||
return mTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The feature from hell... :(
|
|
||||||
bool useWorldPanning() const
|
|
||||||
{
|
|
||||||
return mTexture->bWorldPanning;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isMasked()
|
|
||||||
{
|
|
||||||
return mTexture->bMasked;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UseBasePalette() const { return mTexture->UseBasePalette(); }
|
|
||||||
int GetSkyOffset() const { return mTexture->GetSkyOffset(); }
|
|
||||||
PalEntry GetSkyCapColor(bool bottom) const { return mTexture->GetSkyCapColor(bottom); }
|
|
||||||
|
|
||||||
int GetWidth () { return mTexture->GetWidth(); }
|
|
||||||
int GetHeight () { return mTexture->GetHeight(); }
|
|
||||||
int GetWidthBits() { return mTexture->WidthBits; }
|
|
||||||
int GetHeightBits() { return mTexture->HeightBits; }
|
|
||||||
bool Mipmapped() { return mTexture->Mipmapped(); }
|
|
||||||
|
|
||||||
int GetScaledWidth () { return mTexture->GetScaledWidth(); }
|
|
||||||
int GetScaledHeight () { return mTexture->GetScaledHeight(); }
|
|
||||||
double GetScaledWidthDouble () { return mTexture->GetScaledWidthDouble(); }
|
|
||||||
double GetScaledHeightDouble () { return mTexture->GetScaledHeightDouble(); }
|
|
||||||
double GetScaleY() const { return mTexture->GetScaleY(); }
|
|
||||||
|
|
||||||
// Now with improved offset adjustment.
|
|
||||||
int GetLeftOffset(int adjusted) { return mTexture->GetLeftOffset(adjusted); }
|
|
||||||
int GetTopOffset(int adjusted) { return mTexture->GetTopOffset(adjusted); }
|
|
||||||
int GetScaledLeftOffset (int adjusted) { return mTexture->GetScaledLeftOffset(adjusted); }
|
|
||||||
int GetScaledTopOffset (int adjusted) { return mTexture->GetScaledTopOffset(adjusted); }
|
|
||||||
double GetScaledLeftOffsetDouble(int adjusted) { return mTexture->GetScaledLeftOffsetDouble(adjusted); }
|
|
||||||
double GetScaledTopOffsetDouble(int adjusted) { return mTexture->GetScaledTopOffsetDouble(adjusted); }
|
|
||||||
|
|
||||||
// Interfaces for the different renderers. Everything that needs to check renderer-dependent offsets
|
|
||||||
// should use these, so that if changes are needed, this is the only place to edit.
|
|
||||||
|
|
||||||
// For the original software renderer
|
|
||||||
int GetLeftOffsetSW() { return GetLeftOffset(r_spriteadjustSW); }
|
|
||||||
int GetTopOffsetSW() { return GetTopOffset(r_spriteadjustSW); }
|
|
||||||
int GetScaledLeftOffsetSW() { return GetScaledLeftOffset(r_spriteadjustSW); }
|
|
||||||
int GetScaledTopOffsetSW() { return GetScaledTopOffset(r_spriteadjustSW); }
|
|
||||||
|
|
||||||
// For the softpoly renderer, in case it wants adjustment
|
|
||||||
int GetLeftOffsetPo() { return GetLeftOffset(r_spriteadjustSW); }
|
|
||||||
int GetTopOffsetPo() { return GetTopOffset(r_spriteadjustSW); }
|
|
||||||
int GetScaledLeftOffsetPo() { return GetScaledLeftOffset(r_spriteadjustSW); }
|
|
||||||
int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); }
|
|
||||||
|
|
||||||
DVector2 GetScale() const { return mTexture->Scale; }
|
|
||||||
|
|
||||||
// Returns a single column of the texture
|
|
||||||
const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out)
|
|
||||||
{
|
|
||||||
return mTexture->GetColumn(style, column, spans_out);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a single column of the texture, in BGRA8 format
|
|
||||||
const uint32_t *GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out)
|
|
||||||
{
|
|
||||||
return mTexture->GetColumnBgra(column, spans_out);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the whole texture, stored in column-major order
|
|
||||||
const uint8_t *GetPixels(FRenderStyle style)
|
|
||||||
{
|
|
||||||
return mTexture->GetPixels(style);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the whole texture, stored in column-major order, in BGRA8 format
|
|
||||||
const uint32_t *GetPixelsBgra()
|
|
||||||
{
|
|
||||||
return mTexture->GetPixelsBgra();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Unload()
|
|
||||||
{
|
|
||||||
mTexture->Unload();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
inline FSoftwareTexture *FTexture::GetSoftwareTexture()
|
|
||||||
{
|
|
||||||
if (!SoftwareTexture) SoftwareTexture = new FSoftwareTexture(this);
|
|
||||||
return SoftwareTexture;
|
|
||||||
}
|
|
||||||
|
|
||||||
class FxAddSub;
|
class FxAddSub;
|
||||||
// Texture manager
|
// Texture manager
|
||||||
|
@ -883,17 +752,14 @@ class FWorldTexture : public FTexture
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
uint8_t *Pixeldata[2] = { nullptr, nullptr };
|
uint8_t *Pixeldata[2] = { nullptr, nullptr };
|
||||||
FSoftwareTextureSpan **Spandata[2] = { nullptr, nullptr };
|
|
||||||
uint8_t PixelsAreStatic = 0; // can be set by subclasses which provide static pixel buffers.
|
uint8_t PixelsAreStatic = 0; // can be set by subclasses which provide static pixel buffers.
|
||||||
|
|
||||||
FWorldTexture(const char *name = nullptr, int lumpnum = -1);
|
FWorldTexture(const char *name = nullptr, int lumpnum = -1);
|
||||||
~FWorldTexture();
|
~FWorldTexture();
|
||||||
|
|
||||||
const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) override;
|
|
||||||
const uint8_t *GetPixels(FRenderStyle style) override;
|
|
||||||
void Unload() override;
|
void Unload() override;
|
||||||
|
const uint8_t *GetPixels(FRenderStyle style) override;
|
||||||
virtual uint8_t *MakeTexture(FRenderStyle style) = 0;
|
virtual uint8_t *MakeTexture(FRenderStyle style) = 0;
|
||||||
void FreeAllSpans();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// A texture that doesn't really exist
|
// A texture that doesn't really exist
|
||||||
|
@ -914,7 +780,7 @@ public:
|
||||||
|
|
||||||
virtual int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate=0, FCopyInfo *inf = NULL) override;
|
virtual int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate=0, FCopyInfo *inf = NULL) override;
|
||||||
virtual int CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, PalEntry *remap, FCopyInfo *inf = NULL) override;
|
virtual int CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, PalEntry *remap, FCopyInfo *inf = NULL) override;
|
||||||
const uint32_t *GetPixelsBgra() override;
|
//const uint32_t *GetPixelsBgra() override;
|
||||||
bool CheckModified (FRenderStyle) override;
|
bool CheckModified (FRenderStyle) override;
|
||||||
|
|
||||||
float GetSpeed() const { return Speed; }
|
float GetSpeed() const { return Speed; }
|
||||||
|
@ -943,9 +809,10 @@ public:
|
||||||
FCanvasTexture (const char *name, int width, int height);
|
FCanvasTexture (const char *name, int width, int height);
|
||||||
~FCanvasTexture ();
|
~FCanvasTexture ();
|
||||||
|
|
||||||
const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out);
|
//const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out);
|
||||||
|
//const uint32_t *GetPixelsBgra() override;
|
||||||
|
|
||||||
const uint8_t *GetPixels (FRenderStyle style);
|
const uint8_t *GetPixels (FRenderStyle style);
|
||||||
const uint32_t *GetPixelsBgra() override;
|
|
||||||
void Unload ();
|
void Unload ();
|
||||||
bool CheckModified (FRenderStyle) override;
|
bool CheckModified (FRenderStyle) override;
|
||||||
void NeedUpdate() { bNeedsUpdate=true; }
|
void NeedUpdate() { bNeedsUpdate=true; }
|
||||||
|
@ -962,7 +829,7 @@ protected:
|
||||||
DCanvas *CanvasBgra = nullptr;
|
DCanvas *CanvasBgra = nullptr;
|
||||||
uint8_t *Pixels = nullptr;
|
uint8_t *Pixels = nullptr;
|
||||||
uint32_t *PixelsBgra = nullptr;
|
uint32_t *PixelsBgra = nullptr;
|
||||||
FSoftwareTextureSpan DummySpans[2];
|
//FSoftwareTextureSpan DummySpans[2];
|
||||||
bool bNeedsUpdate = true;
|
bool bNeedsUpdate = true;
|
||||||
bool bDidUpdate = false;
|
bool bDidUpdate = false;
|
||||||
bool bPixelsAllocated = false;
|
bool bPixelsAllocated = false;
|
||||||
|
|
|
@ -171,7 +171,6 @@ class FFontChar1 : public FTexture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FFontChar1 (FTexture *sourcelump);
|
FFontChar1 (FTexture *sourcelump);
|
||||||
const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out);
|
|
||||||
const uint8_t *GetPixels (FRenderStyle style);
|
const uint8_t *GetPixels (FRenderStyle style);
|
||||||
void SetSourceRemap(const uint8_t *sourceremap);
|
void SetSourceRemap(const uint8_t *sourceremap);
|
||||||
void Unload ();
|
void Unload ();
|
||||||
|
@ -192,7 +191,6 @@ public:
|
||||||
FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0);
|
FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0);
|
||||||
~FFontChar2 ();
|
~FFontChar2 ();
|
||||||
|
|
||||||
const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out);
|
|
||||||
const uint8_t *GetPixels (FRenderStyle style);
|
const uint8_t *GetPixels (FRenderStyle style);
|
||||||
void SetSourceRemap(const uint8_t *sourceremap);
|
void SetSourceRemap(const uint8_t *sourceremap);
|
||||||
void Unload ();
|
void Unload ();
|
||||||
|
@ -201,7 +199,6 @@ protected:
|
||||||
int SourceLump;
|
int SourceLump;
|
||||||
int SourcePos;
|
int SourcePos;
|
||||||
uint8_t *Pixels;
|
uint8_t *Pixels;
|
||||||
FSoftwareTextureSpan **Spans;
|
|
||||||
const uint8_t *SourceRemap;
|
const uint8_t *SourceRemap;
|
||||||
|
|
||||||
void MakeTexture ();
|
void MakeTexture ();
|
||||||
|
@ -1607,23 +1604,6 @@ void FFontChar1::MakeTexture ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// FFontChar1 :: GetColumn
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
const uint8_t *FFontChar1::GetColumn(FRenderStyle, unsigned int column, const FSoftwareTextureSpan **spans_out)
|
|
||||||
{
|
|
||||||
if (Pixels == NULL)
|
|
||||||
{
|
|
||||||
MakeTexture ();
|
|
||||||
}
|
|
||||||
|
|
||||||
BaseTexture->GetColumn(DefaultRenderStyle(), column, spans_out);
|
|
||||||
return Pixels + column*Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FFontChar1 :: SetSourceRemap
|
// FFontChar1 :: SetSourceRemap
|
||||||
|
@ -1672,7 +1652,7 @@ FFontChar1::~FFontChar1 ()
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs, int topofs)
|
FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs, int topofs)
|
||||||
: SourceLump (sourcelump), SourcePos (sourcepos), Pixels (0), Spans (0), SourceRemap(NULL)
|
: SourceLump (sourcelump), SourcePos (sourcepos), Pixels (0), SourceRemap(NULL)
|
||||||
{
|
{
|
||||||
UseType = ETextureType::FontChar;
|
UseType = ETextureType::FontChar;
|
||||||
Width = width;
|
Width = width;
|
||||||
|
@ -1691,11 +1671,6 @@ FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, in
|
||||||
FFontChar2::~FFontChar2 ()
|
FFontChar2::~FFontChar2 ()
|
||||||
{
|
{
|
||||||
Unload ();
|
Unload ();
|
||||||
if (Spans != NULL)
|
|
||||||
{
|
|
||||||
FreeSpans (Spans);
|
|
||||||
Spans = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -1731,33 +1706,6 @@ const uint8_t *FFontChar2::GetPixels (FRenderStyle)
|
||||||
return Pixels;
|
return Pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// FFontChar2 :: GetColumn
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
const uint8_t *FFontChar2::GetColumn(FRenderStyle, unsigned int column, const FSoftwareTextureSpan **spans_out)
|
|
||||||
{
|
|
||||||
if (Pixels == NULL)
|
|
||||||
{
|
|
||||||
MakeTexture ();
|
|
||||||
}
|
|
||||||
if (column >= Width)
|
|
||||||
{
|
|
||||||
column = WidthMask;
|
|
||||||
}
|
|
||||||
if (spans_out != NULL)
|
|
||||||
{
|
|
||||||
if (Spans == NULL)
|
|
||||||
{
|
|
||||||
Spans = CreateSpans (Pixels);
|
|
||||||
}
|
|
||||||
*spans_out = Spans[column];
|
|
||||||
}
|
|
||||||
return Pixels + column*Height;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// FFontChar2 :: SetSourceRemap
|
// FFontChar2 :: SetSourceRemap
|
||||||
|
|
Loading…
Reference in a new issue