mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-10 14:51:46 +00:00
- removed the old software renderer framebuffers for Windows
This cannot be refactored with the old code still present and done properly both renderers should share what they can.
This commit is contained in:
parent
1e5fbc1423
commit
a001a5304d
70 changed files with 29 additions and 8286 deletions
|
@ -491,8 +491,6 @@ endif()
|
|||
set( PLAT_WIN32_SOURCES
|
||||
sound/mididevices/music_win_mididevice.cpp
|
||||
win32/critsec.cpp
|
||||
win32/fb_d3d9.cpp
|
||||
win32/fb_d3d9_wipe.cpp
|
||||
win32/hardware.cpp
|
||||
win32/helperthread.cpp
|
||||
win32/i_cd.cpp
|
||||
|
@ -835,7 +833,6 @@ set( FASTMATH_SOURCES
|
|||
sound/timiditypp/fft4g.cpp
|
||||
sound/timiditypp/reverb.cpp
|
||||
gl/utility/gl_clock.cpp
|
||||
gl/renderer/gl_2ddrawer.cpp
|
||||
gl/hqnx/init.cpp
|
||||
gl/hqnx/hq2x.cpp
|
||||
gl/hqnx/hq3x.cpp
|
||||
|
@ -1084,8 +1081,6 @@ set (PCH_SOURCES
|
|||
gl/stereo3d/gl_interleaved3d.cpp
|
||||
gl/system/gl_interface.cpp
|
||||
gl/system/gl_framebuffer.cpp
|
||||
gl/system/gl_swframebuffer.cpp
|
||||
gl/system/gl_swwipe.cpp
|
||||
gl/system/gl_debug.cpp
|
||||
gl/system/gl_menu.cpp
|
||||
gl/system/gl_wipe.cpp
|
||||
|
|
|
@ -145,7 +145,6 @@ void AdjustSpriteOffsets()
|
|||
}
|
||||
tex->LeftOffset=x;
|
||||
tex->TopOffset=y;
|
||||
tex->KillNative();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,494 +0,0 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2016 Christoph Oelckers
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
** gl_2ddrawer.h
|
||||
** Container class for drawing 2d graphics with a vertex buffer
|
||||
**
|
||||
**/
|
||||
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_2ddrawer.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/textures/gl_translate.h"
|
||||
#include "vectors.h"
|
||||
|
||||
#if 0
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FGL2DDrawer::AddData(const FGL2DDrawer::DataGeneric *data)
|
||||
{
|
||||
int addr = mData.Reserve(data->mLen);
|
||||
memcpy(&mData[addr], data, data->mLen);
|
||||
mLastLineCmd = -1;
|
||||
return addr;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Draws a texture
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGL2DDrawer::AddTexture(FTexture *img, DrawParms &parms)
|
||||
{
|
||||
double xscale = parms.destwidth / parms.texwidth;
|
||||
double yscale = parms.destheight / parms.texheight;
|
||||
double x = parms.x - parms.left * xscale;
|
||||
double y = parms.y - parms.top * yscale;
|
||||
double w = parms.destwidth;
|
||||
double h = parms.destheight;
|
||||
float u1, v1, u2, v2;
|
||||
int light = 255;
|
||||
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(img, false);
|
||||
if (gltex == nullptr) return;
|
||||
|
||||
DataTexture dg;
|
||||
|
||||
dg.mType = DrawTypeTexture;
|
||||
dg.mLen = (sizeof(dg) + 7) & ~7;
|
||||
dg.mVertCount = 4;
|
||||
dg.mRenderStyle = parms.style;
|
||||
dg.mMasked = !!parms.masked;
|
||||
dg.mTexture = gltex;
|
||||
|
||||
if (parms.colorOverlay && (parms.colorOverlay & 0xffffff) == 0)
|
||||
{
|
||||
// handle black overlays as reduced light.
|
||||
light = 255 - APART(parms.colorOverlay);
|
||||
parms.colorOverlay = 0;
|
||||
}
|
||||
dg.mVertIndex = (int)mVertices.Reserve(parms.colorOverlay == 0? 4 : 8);
|
||||
dg.mColorOverlay = parms.colorOverlay;
|
||||
dg.mTranslation = 0;
|
||||
|
||||
if (!img->bHasCanvas)
|
||||
{
|
||||
dg.mAlphaTexture = !!(parms.style.Flags & STYLEF_RedIsAlpha);
|
||||
|
||||
if (!dg.mAlphaTexture)
|
||||
{
|
||||
if (parms.remap != NULL && !parms.remap->Inactive)
|
||||
{
|
||||
GLTranslationPalette * pal = static_cast<GLTranslationPalette*>(parms.remap->GetNative());
|
||||
if (pal) dg.mTranslation = -pal->GetIndex();
|
||||
}
|
||||
}
|
||||
u1 = gltex->GetUL();
|
||||
v1 = gltex->GetVT();
|
||||
u2 = gltex->GetUR();
|
||||
v2 = gltex->GetVB();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
dg.mAlphaTexture = false;
|
||||
u1 = 0.f;
|
||||
v1 = 1.f;
|
||||
u2 = 1.f;
|
||||
v2 = 0.f;
|
||||
}
|
||||
|
||||
if (parms.flipX)
|
||||
std::swap(u1, u2);
|
||||
|
||||
|
||||
if (parms.windowleft > 0 || parms.windowright < parms.texwidth)
|
||||
{
|
||||
double wi = MIN(parms.windowright, parms.texwidth);
|
||||
x += parms.windowleft * xscale;
|
||||
w -= (parms.texwidth - wi + parms.windowleft) * xscale;
|
||||
|
||||
u1 = float(u1 + parms.windowleft / parms.texwidth);
|
||||
u2 = float(u2 - (parms.texwidth - wi) / parms.texwidth);
|
||||
}
|
||||
|
||||
PalEntry color;
|
||||
if (parms.style.Flags & STYLEF_ColorIsFixed)
|
||||
{
|
||||
color = parms.fillcolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = PalEntry(light, light, light);
|
||||
}
|
||||
color.a = (uint8_t)(parms.Alpha * 255);
|
||||
// red and blue channels are swapped to use value as vertex color
|
||||
color = PalEntry((color.a * parms.color.a) / 255, (color.b * parms.color.b) / 255, (color.g * parms.color.g) / 255, (color.r * parms.color.r) / 255);
|
||||
|
||||
// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
|
||||
dg.mScissor[0] = GLRenderer->ScreenToWindowX(parms.lclip);
|
||||
dg.mScissor[1] = GLRenderer->ScreenToWindowY(parms.dclip);
|
||||
dg.mScissor[2] = GLRenderer->ScreenToWindowX(parms.rclip) - dg.mScissor[0];
|
||||
dg.mScissor[3] = GLRenderer->ScreenToWindowY(parms.uclip) - dg.mScissor[1];
|
||||
|
||||
FSimpleVertex *ptr = &mVertices[dg.mVertIndex];
|
||||
ptr->Set(x, y, 0, u1, v1, color); ptr++;
|
||||
ptr->Set(x, y + h, 0, u1, v2, color); ptr++;
|
||||
ptr->Set(x + w, y, 0, u2, v1, color); ptr++;
|
||||
ptr->Set(x + w, y + h, 0, u2, v2, color); ptr++;
|
||||
if (parms.colorOverlay != 0)
|
||||
{
|
||||
color = parms.colorOverlay;
|
||||
std::swap(color.r, color.b);
|
||||
ptr->Set(x, y, 0, u1, v1, color); ptr++;
|
||||
ptr->Set(x, y + h, 0, u1, v2, color); ptr++;
|
||||
ptr->Set(x + w, y, 0, u2, v1, color); ptr++;
|
||||
ptr->Set(x + w, y + h, 0, u2, v2, color); ptr++;
|
||||
dg.mVertCount = 8;
|
||||
}
|
||||
AddData(&dg);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGL2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints,
|
||||
double originx, double originy, double scalex, double scaley,
|
||||
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel)
|
||||
{
|
||||
FMaterial *gltexture = FMaterial::ValidateTexture(texture, false);
|
||||
|
||||
if (gltexture == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
DataSimplePoly poly;
|
||||
|
||||
poly.mType = DrawTypePoly;
|
||||
poly.mLen = (sizeof(poly) + 7) & ~7;
|
||||
poly.mTexture = gltexture;
|
||||
poly.mColormap = colormap;
|
||||
poly.mLightLevel = lightlevel;
|
||||
poly.mVertCount = npoints;
|
||||
poly.mVertIndex = (int)mVertices.Reserve(npoints);
|
||||
poly.mFlatColor = flatcolor;
|
||||
|
||||
bool dorotate = rotation != 0;
|
||||
|
||||
float cosrot = cos(rotation.Radians());
|
||||
float sinrot = sin(rotation.Radians());
|
||||
|
||||
float uscale = float(1.f / (texture->GetScaledWidth() * scalex));
|
||||
float vscale = float(1.f / (texture->GetScaledHeight() * scaley));
|
||||
if (texture->bHasCanvas)
|
||||
{
|
||||
vscale = 0 - vscale;
|
||||
}
|
||||
float ox = float(originx);
|
||||
float oy = float(originy);
|
||||
|
||||
for (int i = 0; i < npoints; ++i)
|
||||
{
|
||||
float u = points[i].X - 0.5f - ox;
|
||||
float v = points[i].Y - 0.5f - oy;
|
||||
if (dorotate)
|
||||
{
|
||||
float t = u;
|
||||
u = t * cosrot - v * sinrot;
|
||||
v = v * cosrot + t * sinrot;
|
||||
}
|
||||
mVertices[poly.mVertIndex+i].Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale);
|
||||
}
|
||||
AddData(&poly);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FGL2DDrawer::AddDim(PalEntry color, float damount, int x1, int y1, int w, int h)
|
||||
{
|
||||
color.a = uint8_t(damount * 255);
|
||||
std::swap(color.r, color.b);
|
||||
|
||||
DataGeneric dg;
|
||||
|
||||
dg.mType = DrawTypeDim;
|
||||
dg.mLen = (sizeof(dg) + 7) & ~7;
|
||||
dg.mVertCount = 4;
|
||||
dg.mVertIndex = (int)mVertices.Reserve(4);
|
||||
FSimpleVertex *ptr = &mVertices[dg.mVertIndex];
|
||||
ptr->Set(x1, y1, 0, 0, 0, color); ptr++;
|
||||
ptr->Set(x1, y1 + h, 0, 0, 0, color); ptr++;
|
||||
ptr->Set(x1 + w, y1 + h, 0, 0, 0, color); ptr++;
|
||||
ptr->Set(x1 + w, y1, 0, 0, 0, color); ptr++;
|
||||
AddData(&dg);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGL2DDrawer::AddClear(int left, int top, int right, int bottom, int palcolor, uint32_t color)
|
||||
{
|
||||
PalEntry p = palcolor == -1 || color != 0 ? (PalEntry)color : GPalette.BaseColors[palcolor];
|
||||
AddDim(p, 1.f, left, top, right - left, bottom - top);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGL2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin)
|
||||
{
|
||||
float fU1, fU2, fV1, fV2;
|
||||
|
||||
FMaterial *gltexture = FMaterial::ValidateTexture(src, false);
|
||||
|
||||
if (!gltexture) return;
|
||||
|
||||
DataFlatFill dg;
|
||||
|
||||
dg.mType = DrawTypeFlatFill;
|
||||
dg.mLen = (sizeof(dg) + 7) & ~7;
|
||||
dg.mVertCount = 4;
|
||||
dg.mVertIndex = (int)mVertices.Reserve(4);
|
||||
dg.mTexture = gltexture;
|
||||
|
||||
// scaling is not used here.
|
||||
if (!local_origin)
|
||||
{
|
||||
fU1 = float(left) / src->GetWidth();
|
||||
fV1 = float(top) / src->GetHeight();
|
||||
fU2 = float(right) / src->GetWidth();
|
||||
fV2 = float(bottom) / src->GetHeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
fU1 = 0;
|
||||
fV1 = 0;
|
||||
fU2 = float(right - left) / src->GetWidth();
|
||||
fV2 = float(bottom - top) / src->GetHeight();
|
||||
}
|
||||
FSimpleVertex *ptr = &mVertices[dg.mVertIndex];
|
||||
ptr->Set(left, top, 0, fU1, fV1); ptr++;
|
||||
ptr->Set(left, bottom, 0, fU1, fV2); ptr++;
|
||||
ptr->Set(right, top, 0, fU2, fV1); ptr++;
|
||||
ptr->Set(right, bottom, 0, fU2, fV2); ptr++;
|
||||
AddData(&dg);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGL2DDrawer::AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color)
|
||||
{
|
||||
PalEntry p = color ? (PalEntry)color : GPalette.BaseColors[palcolor];
|
||||
p.a = 255;
|
||||
std::swap(p.r, p.b);
|
||||
|
||||
DataGeneric dg;
|
||||
|
||||
dg.mType = DrawTypeLine;
|
||||
dg.mLen = (sizeof(dg) + 7) & ~7;
|
||||
dg.mVertCount = 2;
|
||||
dg.mVertIndex = (int)mVertices.Reserve(2);
|
||||
mVertices[dg.mVertIndex].Set(x1, y1, 0, 0, 0, p);
|
||||
mVertices[dg.mVertIndex+1].Set(x2, y2, 0, 0, 0, p);
|
||||
|
||||
// Test if we can batch multiple line commands
|
||||
if (mLastLineCmd == -1)
|
||||
{
|
||||
mLastLineCmd = AddData(&dg);
|
||||
}
|
||||
else
|
||||
{
|
||||
DataGeneric *dg = (DataGeneric *)&mData[mLastLineCmd];
|
||||
dg->mVertCount += 2;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGL2DDrawer::AddPixel(int x1, int y1, int palcolor, uint32_t color)
|
||||
{
|
||||
PalEntry p = color ? (PalEntry)color : GPalette.BaseColors[palcolor];
|
||||
p.a = 255;
|
||||
std::swap(p.r, p.b);
|
||||
|
||||
DataGeneric dg;
|
||||
|
||||
dg.mType = DrawTypePixel;
|
||||
dg.mLen = (sizeof(dg) + 7) & ~7;
|
||||
dg.mVertCount = 2;
|
||||
dg.mVertIndex = (int)mVertices.Reserve(1);
|
||||
mVertices[dg.mVertIndex].Set(x1, y1, 0, 0, 0, p);
|
||||
AddData(&dg);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGL2DDrawer::Draw()
|
||||
{
|
||||
FGL2DDrawer::EDrawType lasttype = DrawTypeTexture;
|
||||
|
||||
if (mData.Size() == 0) return;
|
||||
int8_t savedlightmode = glset.lightmode;
|
||||
// lightmode is only relevant for automap subsectors,
|
||||
// but We cannot use the software light mode here because it doesn't properly calculate the light for 2D rendering.
|
||||
if (glset.lightmode == 8) glset.lightmode = 0;
|
||||
|
||||
set(&mVertices[0], mVertices.Size());
|
||||
for (unsigned i = 0; i < mData.Size();)
|
||||
{
|
||||
DataGeneric *dg = (DataGeneric *)&mData[i];
|
||||
// DrawTypePoly may not use the color part of the vertex buffer because it needs to use gl_SetColor to produce proper output.
|
||||
if (lasttype == DrawTypePoly && dg->mType != DrawTypePoly)
|
||||
{
|
||||
gl_RenderState.ResetColor(); // this is needed to reset the desaturation.
|
||||
EnableColorArray(true);
|
||||
}
|
||||
else if (lasttype != DrawTypePoly && dg->mType == DrawTypePoly)
|
||||
{
|
||||
EnableColorArray(false);
|
||||
}
|
||||
lasttype = dg->mType;
|
||||
|
||||
switch (dg->mType)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
|
||||
case DrawTypeTexture:
|
||||
{
|
||||
DataTexture *dt = static_cast<DataTexture*>(dg);
|
||||
|
||||
gl_SetRenderStyle(dt->mRenderStyle, !dt->mMasked, false);
|
||||
gl_RenderState.SetMaterial(dt->mTexture, CLAMP_XY_NOMIP, dt->mTranslation, -1, dt->mAlphaTexture);
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(dt->mScissor[0], dt->mScissor[1], dt->mScissor[2], dt->mScissor[3]);
|
||||
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, dt->mVertIndex, 4);
|
||||
|
||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
if (dt->mVertCount > 4)
|
||||
{
|
||||
gl_RenderState.SetTextureMode(TM_MASK);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, dt->mVertIndex + 4, 4);
|
||||
}
|
||||
|
||||
const auto &viewport = GLRenderer->mScreenViewport;
|
||||
glScissor(viewport.left, viewport.top, viewport.width, viewport.height);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
break;
|
||||
}
|
||||
|
||||
case DrawTypePoly:
|
||||
{
|
||||
DataSimplePoly *dsp = static_cast<DataSimplePoly*>(dg);
|
||||
|
||||
gl_SetColor(dsp->mLightLevel, 0, false, dsp->mColormap, 1.f);
|
||||
gl_RenderState.SetMaterial(dsp->mTexture, CLAMP_NONE, 0, -1, false);
|
||||
gl_RenderState.SetObjectColor(dsp->mFlatColor|0xff000000);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_TRIANGLE_FAN, dsp->mVertIndex, dsp->mVertCount);
|
||||
gl_RenderState.SetObjectColor(0xffffffff);
|
||||
break;
|
||||
}
|
||||
|
||||
case DrawTypeFlatFill:
|
||||
{
|
||||
DataFlatFill *dff = static_cast<DataFlatFill*>(dg);
|
||||
gl_RenderState.SetMaterial(dff->mTexture, CLAMP_NONE, 0, -1, false);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, dg->mVertIndex, dg->mVertCount);
|
||||
break;
|
||||
}
|
||||
|
||||
case DrawTypeDim:
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.AlphaFunc(GL_GREATER, 0);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_TRIANGLE_FAN, dg->mVertIndex, dg->mVertCount);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
break;
|
||||
|
||||
case DrawTypeLine:
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_LINES, dg->mVertIndex, dg->mVertCount);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
break;
|
||||
|
||||
case DrawTypePixel:
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_POINTS, dg->mVertIndex, dg->mVertCount);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
break;
|
||||
|
||||
}
|
||||
i += dg->mLen;
|
||||
}
|
||||
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
|
||||
glset.lightmode = savedlightmode;
|
||||
}
|
||||
|
||||
void FGL2DDrawer::Clear()
|
||||
{
|
||||
mVertices.Clear();
|
||||
mData.Clear();
|
||||
mLastLineCmd = -1;
|
||||
}
|
||||
#endif
|
|
@ -1,75 +0,0 @@
|
|||
#ifndef __2DDRAWER_H
|
||||
#define __2DDRAWER_H
|
||||
|
||||
#include "tarray.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
|
||||
class FGL2DDrawer : public FSimpleVertexBuffer
|
||||
{
|
||||
enum EDrawType
|
||||
{
|
||||
DrawTypeTexture,
|
||||
DrawTypeDim,
|
||||
DrawTypeFlatFill,
|
||||
DrawTypePoly,
|
||||
DrawTypeLine,
|
||||
DrawTypePixel
|
||||
};
|
||||
|
||||
struct DataGeneric
|
||||
{
|
||||
EDrawType mType;
|
||||
uint32_t mLen;
|
||||
int mVertIndex;
|
||||
int mVertCount;
|
||||
};
|
||||
|
||||
struct DataTexture : public DataGeneric
|
||||
{
|
||||
FMaterial *mTexture;
|
||||
int mScissor[4];
|
||||
uint32_t mColorOverlay;
|
||||
int mTranslation;
|
||||
FRenderStyle mRenderStyle;
|
||||
bool mMasked;
|
||||
bool mAlphaTexture;
|
||||
};
|
||||
|
||||
struct DataFlatFill : public DataGeneric
|
||||
{
|
||||
FMaterial *mTexture;
|
||||
};
|
||||
|
||||
struct DataSimplePoly : public DataGeneric
|
||||
{
|
||||
FMaterial *mTexture;
|
||||
int mLightLevel;
|
||||
FColormap mColormap;
|
||||
PalEntry mFlatColor;
|
||||
};
|
||||
|
||||
TArray<FSimpleVertex> mVertices;
|
||||
TArray<uint8_t> mData;
|
||||
int mLastLineCmd = -1; // consecutive lines can be batched into a single draw call so keep this info around.
|
||||
|
||||
int AddData(const DataGeneric *data);
|
||||
|
||||
public:
|
||||
void AddTexture(FTexture *img, DrawParms &parms);
|
||||
void AddDim(PalEntry color, float damount, int x1, int y1, int w, int h);
|
||||
void AddClear(int left, int top, int right, int bottom, int palcolor, uint32_t color);
|
||||
void AddFlatFill(int left, int top, int right, int bottom, FTexture *src, bool local_origin);
|
||||
|
||||
void AddPoly(FTexture *texture, FVector2 *points, int npoints,
|
||||
double originx, double originy, double scalex, double scaley,
|
||||
DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel);
|
||||
|
||||
void AddLine(int x1, int y1, int x2, int y2, int palcolor, uint32_t color);
|
||||
void AddPixel(int x1, int y1, int palcolor, uint32_t color);
|
||||
|
||||
void Draw();
|
||||
void Clear();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -63,7 +63,6 @@
|
|||
#include "gl/shaders/gl_fxaashader.h"
|
||||
#include "gl/shaders/gl_presentshader.h"
|
||||
#include "gl/shaders/gl_postprocessshader.h"
|
||||
#include "gl/renderer/gl_2ddrawer.h"
|
||||
#include "gl/stereo3d/gl_stereo3d.h"
|
||||
#include "r_videoscale.h"
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_renderbuffers.h"
|
||||
#include "gl/renderer/gl_2ddrawer.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,456 +0,0 @@
|
|||
#ifndef __GL_SWFRAMEBUFFER
|
||||
#define __GL_SWFRAMEBUFFER
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "win32iface.h"
|
||||
#include "win32gliface.h"
|
||||
#endif
|
||||
|
||||
#include "SkylineBinPack.h"
|
||||
#include "textures.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class FGLDebug;
|
||||
|
||||
#ifdef _WIN32
|
||||
class OpenGLSWFrameBuffer : public Win32GLFrameBuffer
|
||||
{
|
||||
typedef Win32GLFrameBuffer Super;
|
||||
#else
|
||||
#include "sdlglvideo.h"
|
||||
class OpenGLSWFrameBuffer : public SDLGLFB
|
||||
{
|
||||
typedef SDLGLFB Super; //[C]commented, DECLARE_CLASS defines this in linux
|
||||
#endif
|
||||
|
||||
DSimpleCanvas *RenderBuffer;
|
||||
DCanvas *MappedBuffer;
|
||||
|
||||
public:
|
||||
|
||||
explicit OpenGLSWFrameBuffer() {}
|
||||
OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra);
|
||||
~OpenGLSWFrameBuffer();
|
||||
|
||||
bool LockCanvas() override;
|
||||
void UnlockCanvas() override;
|
||||
|
||||
virtual DCanvas *GetCanvas() { return RenderBuffer; }
|
||||
void Update() override;
|
||||
PalEntry *GetPalette() override;
|
||||
void GetFlashedPalette(PalEntry palette[256]) override;
|
||||
void UpdatePalette() override;
|
||||
bool SetGamma(float gamma) override;
|
||||
bool SetFlash(PalEntry rgb, int amount) override;
|
||||
void GetFlash(PalEntry &rgb, int &amount) override;
|
||||
int GetPageCount() override;
|
||||
void SetVSync(bool vsync) override;
|
||||
void NewRefreshRate() override;
|
||||
void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) override;
|
||||
void ReleaseScreenshotBuffer() override;
|
||||
void SetBlendingRect(int x1, int y1, int x2, int y2) override;
|
||||
bool Begin2D(bool copy3d) override;
|
||||
void DrawBlendingRect() override;
|
||||
FNativeTexture *CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping) override;
|
||||
FNativePalette *CreatePalette(FRemapTable *remap) override;
|
||||
bool WipeStartScreen(int type) override;
|
||||
void WipeEndScreen() override;
|
||||
bool WipeDo(int ticks) override;
|
||||
void WipeCleanup() override;
|
||||
|
||||
#ifdef WIN32
|
||||
int GetTrueHeight() override { return TrueHeight; }
|
||||
#endif
|
||||
|
||||
void ScaleCoordsFromWindow(int16_t &x, int16_t &y) override;
|
||||
|
||||
private:
|
||||
struct FBVERTEX
|
||||
{
|
||||
float x, y, z, rhw;
|
||||
uint32_t color0, color1;
|
||||
float tu, tv;
|
||||
};
|
||||
|
||||
struct BURNVERTEX
|
||||
{
|
||||
float x, y, z, rhw;
|
||||
float tu0, tv0;
|
||||
float tu1, tv1;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PSCONST_Desaturation,
|
||||
PSCONST_PaletteMod,
|
||||
PSCONST_Weights,
|
||||
PSCONST_Gamma,
|
||||
PSCONST_ScreenSize,
|
||||
NumPSCONST
|
||||
};
|
||||
|
||||
struct GammaRamp
|
||||
{
|
||||
uint16_t red[256], green[256], blue[256];
|
||||
};
|
||||
|
||||
struct LTRBRect
|
||||
{
|
||||
int left, top, right, bottom;
|
||||
};
|
||||
|
||||
class HWTexture
|
||||
{
|
||||
public:
|
||||
HWTexture() { Buffers[0] = 0; Buffers[1] = 0; }
|
||||
~HWTexture();
|
||||
|
||||
int Texture = 0;
|
||||
int Buffers[2];
|
||||
int CurrentBuffer = 0;
|
||||
int WrapS = 0;
|
||||
int WrapT = 0;
|
||||
int Format = 0;
|
||||
|
||||
std::vector<uint8_t> MapBuffer;
|
||||
};
|
||||
|
||||
class HWFrameBuffer
|
||||
{
|
||||
public:
|
||||
~HWFrameBuffer();
|
||||
|
||||
int Framebuffer = 0;
|
||||
std::unique_ptr<HWTexture> Texture;
|
||||
};
|
||||
|
||||
|
||||
class HWVertexBuffer
|
||||
{
|
||||
public:
|
||||
~HWVertexBuffer();
|
||||
|
||||
FBVERTEX *Lock();
|
||||
void Unlock();
|
||||
|
||||
int VertexArray = 0;
|
||||
int Buffer = 0;
|
||||
int Size = 0;
|
||||
};
|
||||
|
||||
class HWIndexBuffer
|
||||
{
|
||||
public:
|
||||
~HWIndexBuffer();
|
||||
|
||||
uint16_t *Lock();
|
||||
void Unlock();
|
||||
|
||||
int Buffer = 0;
|
||||
int Size = 0;
|
||||
|
||||
private:
|
||||
int LockedOldBinding = 0;
|
||||
};
|
||||
|
||||
class HWPixelShader
|
||||
{
|
||||
public:
|
||||
~HWPixelShader();
|
||||
|
||||
int Program = 0;
|
||||
int VertexShader = 0;
|
||||
int FragmentShader = 0;
|
||||
|
||||
int ConstantLocations[NumPSCONST];
|
||||
int ImageLocation = -1;
|
||||
int PaletteLocation = -1;
|
||||
int NewScreenLocation = -1;
|
||||
int BurnLocation = -1;
|
||||
};
|
||||
|
||||
std::unique_ptr<HWFrameBuffer> CreateFrameBuffer(const FString &name, int width, int height);
|
||||
std::unique_ptr<HWPixelShader> CreatePixelShader(FString vertexsrc, FString fragmentsrc, const FString &defines);
|
||||
std::unique_ptr<HWVertexBuffer> CreateVertexBuffer(int size);
|
||||
std::unique_ptr<HWIndexBuffer> CreateIndexBuffer(int size);
|
||||
std::unique_ptr<HWTexture> CreateTexture(const FString &name, int width, int height, int levels, int format);
|
||||
|
||||
void SetGammaRamp(const GammaRamp *ramp);
|
||||
void SetPixelShaderConstantF(int uniformIndex, const float *data, int vec4fcount);
|
||||
void SetHWPixelShader(HWPixelShader *shader);
|
||||
void SetStreamSource(HWVertexBuffer *vertexBuffer);
|
||||
void SetIndices(HWIndexBuffer *indexBuffer);
|
||||
void DrawTriangleFans(int count, const FBVERTEX *vertices);
|
||||
void DrawTriangleFans(int count, const BURNVERTEX *vertices);
|
||||
void DrawPoints(int count, const FBVERTEX *vertices);
|
||||
void DrawLineList(int count);
|
||||
void DrawTriangleList(int minIndex, int numVertices, int startIndex, int primitiveCount);
|
||||
void Present();
|
||||
|
||||
void GetLetterboxFrame(int &x, int &y, int &width, int &height);
|
||||
|
||||
static void BgraToRgba(uint32_t *dest, const uint32_t *src, int width, int height, int srcpitch);
|
||||
|
||||
void BindFBBuffer();
|
||||
void *MappedMemBuffer = nullptr;
|
||||
bool UseMappedMemBuffer = true;
|
||||
|
||||
static uint32_t ColorARGB(uint32_t a, uint32_t r, uint32_t g, uint32_t b) { return ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | ((b) & 0xff); }
|
||||
static uint32_t ColorRGBA(uint32_t r, uint32_t g, uint32_t b, uint32_t a) { return ColorARGB(a, r, g, b); }
|
||||
static uint32_t ColorXRGB(uint32_t r, uint32_t g, uint32_t b) { return ColorARGB(0xff, r, g, b); }
|
||||
static uint32_t ColorValue(float r, float g, float b, float a) { return ColorRGBA((uint32_t)(r * 255.0f), (uint32_t)(g * 255.0f), (uint32_t)(b * 255.0f), (uint32_t)(a * 255.0f)); }
|
||||
|
||||
static void *MapBuffer(int target, int size);
|
||||
|
||||
// The number of points for the vertex buffer.
|
||||
enum { NUM_VERTS = 10240 };
|
||||
|
||||
// The number of indices for the index buffer.
|
||||
enum { NUM_INDEXES = ((NUM_VERTS * 6) / 4) };
|
||||
|
||||
// The number of quads we can batch together.
|
||||
enum { MAX_QUAD_BATCH = (NUM_INDEXES / 6) };
|
||||
|
||||
// The default size for a texture atlas.
|
||||
enum { DEF_ATLAS_WIDTH = 512 };
|
||||
enum { DEF_ATLAS_HEIGHT = 512 };
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
class OpenGLTex : public FNativeTexture
|
||||
{
|
||||
public:
|
||||
OpenGLTex(FTexture *tex, FTextureFormat fmt, OpenGLSWFrameBuffer *fb, bool wrapping);
|
||||
~OpenGLTex();
|
||||
|
||||
std::unique_ptr<HWTexture> Tex;
|
||||
|
||||
FTexture *GameTex;
|
||||
|
||||
OpenGLTex **Prev;
|
||||
OpenGLTex *Next;
|
||||
|
||||
bool IsGray;
|
||||
|
||||
bool Create(OpenGLSWFrameBuffer *fb, bool wrapping);
|
||||
bool Update();
|
||||
bool CheckWrapping(bool wrapping);
|
||||
int GetTexFormat();
|
||||
};
|
||||
|
||||
class OpenGLPal : public FNativePalette
|
||||
{
|
||||
public:
|
||||
OpenGLPal(FRemapTable *remap, OpenGLSWFrameBuffer *fb);
|
||||
~OpenGLPal();
|
||||
|
||||
OpenGLPal **Prev;
|
||||
OpenGLPal *Next;
|
||||
|
||||
std::unique_ptr<HWTexture> Tex;
|
||||
uint32_t BorderColor;
|
||||
|
||||
bool Update();
|
||||
|
||||
FRemapTable *Remap;
|
||||
int RoundedPaletteSize;
|
||||
};
|
||||
|
||||
// Flags for a buffered quad
|
||||
enum
|
||||
{
|
||||
BQF_GamePalette = 1,
|
||||
BQF_CustomPalette = 7,
|
||||
BQF_Paletted = 7,
|
||||
BQF_Bilinear = 8,
|
||||
BQF_WrapUV = 16,
|
||||
BQF_InvertSource = 32,
|
||||
BQF_DisableAlphaTest = 64,
|
||||
BQF_Desaturated = 128,
|
||||
};
|
||||
|
||||
// Shaders for a buffered quad
|
||||
enum
|
||||
{
|
||||
BQS_PalTex,
|
||||
BQS_Plain,
|
||||
BQS_RedToAlpha,
|
||||
BQS_ColorOnly,
|
||||
BQS_SpecialColormap,
|
||||
BQS_InGameColormap,
|
||||
};
|
||||
|
||||
struct BufferedTris
|
||||
{
|
||||
uint8_t Flags;
|
||||
uint8_t ShaderNum;
|
||||
int BlendOp;
|
||||
int SrcBlend;
|
||||
int DestBlend;
|
||||
|
||||
uint8_t Desat;
|
||||
OpenGLPal *Palette;
|
||||
HWTexture *Texture;
|
||||
uint16_t NumVerts; // Number of _unique_ vertices used by this set.
|
||||
uint16_t NumTris; // Number of triangles used by this set.
|
||||
|
||||
void ClearSetup()
|
||||
{
|
||||
Flags = 0;
|
||||
ShaderNum = 0;
|
||||
BlendOp = 0;
|
||||
SrcBlend = 0;
|
||||
DestBlend = 0;
|
||||
}
|
||||
|
||||
bool IsSameSetup(const BufferedTris &other) const
|
||||
{
|
||||
return Flags == other.Flags && ShaderNum == other.ShaderNum && BlendOp == other.BlendOp && SrcBlend == other.SrcBlend && DestBlend == other.DestBlend;
|
||||
}
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SHADER_NormalColor,
|
||||
SHADER_NormalColorPal,
|
||||
SHADER_NormalColorInv,
|
||||
SHADER_NormalColorPalInv,
|
||||
|
||||
SHADER_RedToAlpha,
|
||||
SHADER_RedToAlphaInv,
|
||||
|
||||
SHADER_VertexColor,
|
||||
|
||||
SHADER_SpecialColormap,
|
||||
SHADER_SpecialColormapPal,
|
||||
|
||||
SHADER_InGameColormap,
|
||||
SHADER_InGameColormapDesat,
|
||||
SHADER_InGameColormapInv,
|
||||
SHADER_InGameColormapInvDesat,
|
||||
SHADER_InGameColormapPal,
|
||||
SHADER_InGameColormapPalDesat,
|
||||
SHADER_InGameColormapPalInv,
|
||||
SHADER_InGameColormapPalInvDesat,
|
||||
|
||||
SHADER_BurnWipe,
|
||||
SHADER_GammaCorrection,
|
||||
|
||||
NUM_SHADERS
|
||||
};
|
||||
static const char *const ShaderDefines[NUM_SHADERS];
|
||||
|
||||
void Flip();
|
||||
void SetInitialState();
|
||||
bool CreateResources();
|
||||
void ReleaseResources();
|
||||
bool LoadShaders();
|
||||
bool CreateFBTexture();
|
||||
bool CreatePaletteTexture();
|
||||
bool CreateVertexes();
|
||||
void UploadPalette();
|
||||
void CalcFullscreenCoords(FBVERTEX verts[4], bool viewarea_only, uint32_t color0, uint32_t color1) const;
|
||||
bool Reset();
|
||||
std::unique_ptr<HWTexture> CopyCurrentScreen();
|
||||
void ReleaseDefaultPoolItems();
|
||||
void KillNativePals();
|
||||
void KillNativeTexs();
|
||||
void DrawLetterbox(int x, int y, int width, int height);
|
||||
void Draw3DPart(bool copy3d);
|
||||
static int GetStyleAlpha(int type);
|
||||
void CheckQuadBatch(int numtris = 2, int numverts = 4);
|
||||
void BeginQuadBatch();
|
||||
void EndQuadBatch();
|
||||
void BeginLineBatch();
|
||||
void EndLineBatch();
|
||||
void EndBatch();
|
||||
|
||||
// State
|
||||
void EnableAlphaTest(bool enabled);
|
||||
void SetAlphaBlend(int op, int srcblend = 0, int destblend = 0);
|
||||
void SetConstant(int cnum, float r, float g, float b, float a);
|
||||
void SetPixelShader(HWPixelShader *shader);
|
||||
void SetTexture(int tnum, HWTexture *texture);
|
||||
void SetSamplerWrapS(int tnum, int mode);
|
||||
void SetSamplerWrapT(int tnum, int mode);
|
||||
void SetPaletteTexture(HWTexture *texture, int count, uint32_t border_color);
|
||||
|
||||
bool Valid = false;
|
||||
std::shared_ptr<FGLDebug> Debug;
|
||||
|
||||
std::unique_ptr<HWVertexBuffer> StreamVertexBuffer, StreamVertexBufferBurn;
|
||||
float ShaderConstants[NumPSCONST * 4];
|
||||
HWPixelShader *CurrentShader = nullptr;
|
||||
|
||||
std::unique_ptr<HWFrameBuffer> OutputFB;
|
||||
|
||||
bool AlphaTestEnabled = false;
|
||||
bool AlphaBlendEnabled = false;
|
||||
int AlphaBlendOp = 0;
|
||||
int AlphaSrcBlend = 0;
|
||||
int AlphaDestBlend = 0;
|
||||
float Constant[3][4];
|
||||
uint32_t CurBorderColor;
|
||||
HWPixelShader *CurPixelShader;
|
||||
HWTexture *Texture[5];
|
||||
int SamplerWrapS[5], SamplerWrapT[5];
|
||||
|
||||
PalEntry SourcePalette[256];
|
||||
uint32_t BorderColor;
|
||||
uint32_t FlashColor0, FlashColor1;
|
||||
PalEntry FlashColor;
|
||||
int FlashAmount;
|
||||
int TrueHeight;
|
||||
int PixelDoubling;
|
||||
float Gamma;
|
||||
#ifdef _WIN32
|
||||
bool UpdatePending;
|
||||
#endif // _WIN32
|
||||
bool NeedPalUpdate;
|
||||
bool NeedGammaUpdate;
|
||||
LTRBRect BlendingRect;
|
||||
int In2D;
|
||||
bool InScene;
|
||||
bool GatheringWipeScreen;
|
||||
bool AALines;
|
||||
uint8_t BlockNum;
|
||||
OpenGLPal *Palettes = nullptr;
|
||||
OpenGLTex *Textures = nullptr;
|
||||
|
||||
std::unique_ptr<HWTexture> FBTexture;
|
||||
std::unique_ptr<HWTexture> PaletteTexture;
|
||||
std::unique_ptr<HWTexture> ScreenshotTexture;
|
||||
|
||||
std::unique_ptr<HWVertexBuffer> VertexBuffer;
|
||||
FBVERTEX *VertexData = nullptr;
|
||||
std::unique_ptr<HWIndexBuffer> IndexBuffer;
|
||||
uint16_t *IndexData = nullptr;
|
||||
BufferedTris *QuadExtra = nullptr;
|
||||
int VertexPos;
|
||||
int IndexPos;
|
||||
int QuadBatchPos;
|
||||
enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType;
|
||||
|
||||
std::unique_ptr<HWPixelShader> Shaders[NUM_SHADERS];
|
||||
|
||||
std::unique_ptr<HWTexture> InitialWipeScreen, FinalWipeScreen;
|
||||
|
||||
class Wiper
|
||||
{
|
||||
public:
|
||||
virtual ~Wiper();
|
||||
virtual bool Run(int ticks, OpenGLSWFrameBuffer *fb) = 0;
|
||||
|
||||
void DrawScreen(OpenGLSWFrameBuffer *fb, HWTexture *tex, int blendop = 0, uint32_t color0 = 0, uint32_t color1 = 0xFFFFFFF);
|
||||
};
|
||||
|
||||
class Wiper_Melt; friend class Wiper_Melt;
|
||||
class Wiper_Burn; friend class Wiper_Burn;
|
||||
class Wiper_Crossfade; friend class Wiper_Crossfade;
|
||||
|
||||
Wiper *ScreenWipe;
|
||||
};
|
||||
|
||||
|
||||
#endif //__GL_SWFRAMEBUFFER
|
|
@ -1,566 +0,0 @@
|
|||
/*
|
||||
** gl_swwipe.cpp
|
||||
** Implements the different screen wipes using OpenGL calls.
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2008 Randy Heit
|
||||
** 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.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "m_swap.h"
|
||||
#include "v_video.h"
|
||||
#include "doomstat.h"
|
||||
#include "m_png.h"
|
||||
#include "m_crc32.h"
|
||||
#include "vectors.h"
|
||||
#include "v_palette.h"
|
||||
#include "templates.h"
|
||||
|
||||
#include "c_dispatch.h"
|
||||
#include "templates.h"
|
||||
#include "i_system.h"
|
||||
#include "i_video.h"
|
||||
#include "v_pfx.h"
|
||||
#include "stats.h"
|
||||
#include "doomerrors.h"
|
||||
#include "r_data/r_translate.h"
|
||||
#include "f_wipe.h"
|
||||
#include "sbar.h"
|
||||
#include "w_wad.h"
|
||||
#include "r_data/colormaps.h"
|
||||
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/system/gl_swframebuffer.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/utility/gl_clock.h"
|
||||
#include "gl/utility/gl_templates.h"
|
||||
#include "gl/gl_functions.h"
|
||||
#include "gl_debug.h"
|
||||
#include "m_random.h"
|
||||
|
||||
class OpenGLSWFrameBuffer::Wiper_Crossfade : public OpenGLSWFrameBuffer::Wiper
|
||||
{
|
||||
public:
|
||||
Wiper_Crossfade();
|
||||
bool Run(int ticks, OpenGLSWFrameBuffer *fb);
|
||||
|
||||
private:
|
||||
int Clock;
|
||||
};
|
||||
|
||||
class OpenGLSWFrameBuffer::Wiper_Melt : public OpenGLSWFrameBuffer::Wiper
|
||||
{
|
||||
public:
|
||||
Wiper_Melt();
|
||||
bool Run(int ticks, OpenGLSWFrameBuffer *fb);
|
||||
|
||||
private:
|
||||
// Match the strip sizes that oldschool Doom used.
|
||||
static const int WIDTH = 160, HEIGHT = 200;
|
||||
int y[WIDTH];
|
||||
};
|
||||
|
||||
class OpenGLSWFrameBuffer::Wiper_Burn : public OpenGLSWFrameBuffer::Wiper
|
||||
{
|
||||
public:
|
||||
Wiper_Burn(OpenGLSWFrameBuffer *fb);
|
||||
~Wiper_Burn();
|
||||
bool Run(int ticks, OpenGLSWFrameBuffer *fb);
|
||||
|
||||
private:
|
||||
static const int WIDTH = 64, HEIGHT = 64;
|
||||
uint8_t BurnArray[WIDTH * (HEIGHT + 5)];
|
||||
std::unique_ptr<HWTexture> BurnTexture;
|
||||
int Density;
|
||||
int BurnTime;
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLSWFrameBuffer :: WipeStartScreen
|
||||
//
|
||||
// Called before the current screen has started rendering. This needs to
|
||||
// save what was drawn the previous frame so that it can be animated into
|
||||
// what gets drawn this frame.
|
||||
//
|
||||
// In fullscreen mode, we use GetFrontBufferData() to grab the data that
|
||||
// is visible on screen right now.
|
||||
//
|
||||
// In windowed mode, we can't do that because we'll get the whole desktop.
|
||||
// Instead, we can conveniently use the TempRenderTexture, which is normally
|
||||
// used for gamma-correcting copying the image to the back buffer.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool OpenGLSWFrameBuffer::WipeStartScreen(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case wipe_Melt:
|
||||
ScreenWipe = new Wiper_Melt;
|
||||
break;
|
||||
|
||||
case wipe_Burn:
|
||||
ScreenWipe = new Wiper_Burn(this);
|
||||
break;
|
||||
|
||||
case wipe_Fade:
|
||||
ScreenWipe = new Wiper_Crossfade;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
InitialWipeScreen = CopyCurrentScreen();
|
||||
|
||||
// Make even fullscreen model render to the TempRenderTexture, so
|
||||
// we can have a copy of the new screen readily available.
|
||||
GatheringWipeScreen = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLSWFrameBuffer :: WipeEndScreen
|
||||
//
|
||||
// The screen we want to animate to has just been drawn. This function is
|
||||
// called in place of Update(), so it has not been Presented yet.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void OpenGLSWFrameBuffer::WipeEndScreen()
|
||||
{
|
||||
// Don't do anything if there is no starting point.
|
||||
if (InitialWipeScreen == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If the whole screen was drawn without 2D accel, get it in to
|
||||
// video memory now.
|
||||
if (!In2D)
|
||||
{
|
||||
Begin2D(true);
|
||||
}
|
||||
|
||||
EndBatch(); // Make sure all batched primitives have been drawn.
|
||||
|
||||
FinalWipeScreen = CopyCurrentScreen();
|
||||
|
||||
// At this point, InitialWipeScreen holds the screen we are wiping from.
|
||||
// FinalWipeScreen holds the screen we are wiping to, which may be the
|
||||
// same texture as TempRenderTexture.
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLSWFrameBuffer :: WipeDo
|
||||
//
|
||||
// Perform the actual wipe animation. The number of tics since the last
|
||||
// time this function was called is passed in. Returns true when the wipe
|
||||
// is over. The first time this function has been called, the screen is
|
||||
// still locked from before and EndScene() still has not been called.
|
||||
// Successive times need to call BeginScene().
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool OpenGLSWFrameBuffer::WipeDo(int ticks)
|
||||
{
|
||||
// Sanity checks.
|
||||
if (InitialWipeScreen == NULL || FinalWipeScreen == NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (GatheringWipeScreen)
|
||||
{ // This is the first time we've been called for this wipe.
|
||||
GatheringWipeScreen = false;
|
||||
}
|
||||
else
|
||||
{ // This is the second or later time we've been called for this wipe.
|
||||
InScene = true;
|
||||
}
|
||||
|
||||
In2D = 3;
|
||||
|
||||
EnableAlphaTest(false);
|
||||
bool done = ScreenWipe->Run(ticks, this);
|
||||
return done;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLSWFrameBuffer :: WipeCleanup
|
||||
//
|
||||
// Release any resources that were specifically created for the wipe.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void OpenGLSWFrameBuffer::WipeCleanup()
|
||||
{
|
||||
if (ScreenWipe != NULL)
|
||||
{
|
||||
delete ScreenWipe;
|
||||
ScreenWipe = NULL;
|
||||
}
|
||||
InitialWipeScreen.reset();
|
||||
FinalWipeScreen.reset();
|
||||
GatheringWipeScreen = false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLSWFrameBuffer :: Wiper Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
OpenGLSWFrameBuffer::Wiper::~Wiper()
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLSWFrameBuffer :: Wiper :: DrawScreen
|
||||
//
|
||||
// Draw either the initial or target screen completely to the screen.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void OpenGLSWFrameBuffer::Wiper::DrawScreen(OpenGLSWFrameBuffer *fb, HWTexture *tex,
|
||||
int blendop, uint32_t color0, uint32_t color1)
|
||||
{
|
||||
FBVERTEX verts[4];
|
||||
|
||||
fb->CalcFullscreenCoords(verts, false, color0, color1);
|
||||
fb->SetTexture(0, tex);
|
||||
fb->SetAlphaBlend(blendop, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
fb->SetPixelShader(fb->Shaders[SHADER_NormalColor].get());
|
||||
fb->DrawTriangleFans(2, verts);
|
||||
}
|
||||
|
||||
// WIPE: CROSSFADE ---------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLSWFrameBuffer :: Wiper_Crossfade Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
OpenGLSWFrameBuffer::Wiper_Crossfade::Wiper_Crossfade()
|
||||
: Clock(0)
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLSWFrameBuffer :: Wiper_Crossfade :: Run
|
||||
//
|
||||
// Fades the old screen into the new one over 32 ticks.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool OpenGLSWFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLSWFrameBuffer *fb)
|
||||
{
|
||||
Clock += ticks;
|
||||
|
||||
// Put the initial screen back to the buffer.
|
||||
DrawScreen(fb, fb->InitialWipeScreen.get());
|
||||
|
||||
// Draw the new screen on top of it.
|
||||
DrawScreen(fb, fb->FinalWipeScreen.get(), GL_FUNC_ADD, ColorValue(0,0,0,Clock / 32.f), ColorRGBA(255,255,255,0));
|
||||
|
||||
return Clock >= 32;
|
||||
}
|
||||
|
||||
// WIPE: MELT --------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLSWFrameBuffer :: Wiper_Melt Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
OpenGLSWFrameBuffer::Wiper_Melt::Wiper_Melt()
|
||||
{
|
||||
int i, r;
|
||||
|
||||
// setup initial column positions
|
||||
// (y<0 => not ready to scroll yet)
|
||||
y[0] = -(M_Random() & 15);
|
||||
for (i = 1; i < WIDTH; ++i)
|
||||
{
|
||||
r = (M_Random()%3) - 1;
|
||||
y[i] = clamp(y[i-1] + r, -15, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLSWFrameBuffer :: Wiper_Melt :: Run
|
||||
//
|
||||
// Fades the old screen into the new one over 32 ticks.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool OpenGLSWFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLSWFrameBuffer *fb)
|
||||
{
|
||||
// Draw the new screen on the bottom.
|
||||
DrawScreen(fb, fb->FinalWipeScreen.get());
|
||||
|
||||
int i, dy;
|
||||
int fbwidth = fb->Width;
|
||||
int fbheight = fb->Height;
|
||||
bool done = true;
|
||||
|
||||
// Copy the old screen in vertical strips on top of the new one.
|
||||
while (ticks--)
|
||||
{
|
||||
done = true;
|
||||
for (i = 0; i < WIDTH; i++)
|
||||
{
|
||||
if (y[i] < 0)
|
||||
{
|
||||
y[i]++;
|
||||
done = false;
|
||||
}
|
||||
else if (y[i] < HEIGHT)
|
||||
{
|
||||
dy = (y[i] < 16) ? y[i]+1 : 8;
|
||||
y[i] = MIN(y[i] + dy, HEIGHT);
|
||||
done = false;
|
||||
}
|
||||
if (ticks == 0)
|
||||
{ // Only draw for the final tick.
|
||||
LTRBRect rect;
|
||||
struct Point { int x, y; } dpt;
|
||||
|
||||
dpt.x = i * fbwidth / WIDTH;
|
||||
dpt.y = MAX(0, y[i] * fbheight / HEIGHT);
|
||||
rect.left = dpt.x;
|
||||
rect.top = 0;
|
||||
rect.right = (i + 1) * fbwidth / WIDTH;
|
||||
rect.bottom = fbheight - dpt.y;
|
||||
if (rect.bottom > rect.top)
|
||||
{
|
||||
fb->CheckQuadBatch();
|
||||
|
||||
BufferedTris *quad = &fb->QuadExtra[fb->QuadBatchPos];
|
||||
FBVERTEX *vert = &fb->VertexData[fb->VertexPos];
|
||||
uint16_t *index = &fb->IndexData[fb->IndexPos];
|
||||
|
||||
quad->ClearSetup();
|
||||
quad->Flags = BQF_DisableAlphaTest;
|
||||
quad->ShaderNum = BQS_Plain;
|
||||
quad->Palette = NULL;
|
||||
quad->Texture = fb->InitialWipeScreen.get();
|
||||
quad->NumVerts = 4;
|
||||
quad->NumTris = 2;
|
||||
|
||||
// Fill the vertex buffer.
|
||||
float u0 = rect.left / float(fb->Width);
|
||||
float v0 = 0;
|
||||
float u1 = rect.right / float(fb->Width);
|
||||
float v1 = (rect.bottom - rect.top) / float(fb->Height);
|
||||
|
||||
float x0 = float(rect.left);
|
||||
float x1 = float(rect.right);
|
||||
float y0 = float(dpt.y);
|
||||
float y1 = float(fbheight);
|
||||
|
||||
vert[0].x = x0;
|
||||
vert[0].y = y0;
|
||||
vert[0].z = 0;
|
||||
vert[0].rhw = 1;
|
||||
vert[0].color0 = 0;
|
||||
vert[0].color1 = 0xFFFFFFF;
|
||||
vert[0].tu = u0;
|
||||
vert[0].tv = v0;
|
||||
|
||||
vert[1].x = x1;
|
||||
vert[1].y = y0;
|
||||
vert[1].z = 0;
|
||||
vert[1].rhw = 1;
|
||||
vert[1].color0 = 0;
|
||||
vert[1].color1 = 0xFFFFFFF;
|
||||
vert[1].tu = u1;
|
||||
vert[1].tv = v0;
|
||||
|
||||
vert[2].x = x1;
|
||||
vert[2].y = y1;
|
||||
vert[2].z = 0;
|
||||
vert[2].rhw = 1;
|
||||
vert[2].color0 = 0;
|
||||
vert[2].color1 = 0xFFFFFFF;
|
||||
vert[2].tu = u1;
|
||||
vert[2].tv = v1;
|
||||
|
||||
vert[3].x = x0;
|
||||
vert[3].y = y1;
|
||||
vert[3].z = 0;
|
||||
vert[3].rhw = 1;
|
||||
vert[3].color0 = 0;
|
||||
vert[3].color1 = 0xFFFFFFF;
|
||||
vert[3].tu = u0;
|
||||
vert[3].tv = v1;
|
||||
|
||||
// Fill the vertex index buffer.
|
||||
index[0] = fb->VertexPos;
|
||||
index[1] = fb->VertexPos + 1;
|
||||
index[2] = fb->VertexPos + 2;
|
||||
index[3] = fb->VertexPos;
|
||||
index[4] = fb->VertexPos + 2;
|
||||
index[5] = fb->VertexPos + 3;
|
||||
|
||||
// Batch the quad.
|
||||
fb->QuadBatchPos++;
|
||||
fb->VertexPos += 4;
|
||||
fb->IndexPos += 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fb->EndQuadBatch();
|
||||
return done;
|
||||
}
|
||||
|
||||
// WIPE: BURN --------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLSWFrameBuffer :: Wiper_Burn Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
OpenGLSWFrameBuffer::Wiper_Burn::Wiper_Burn(OpenGLSWFrameBuffer *fb)
|
||||
{
|
||||
Density = 4;
|
||||
BurnTime = 0;
|
||||
memset(BurnArray, 0, sizeof(BurnArray));
|
||||
if (fb->Shaders[SHADER_BurnWipe] == nullptr)
|
||||
{
|
||||
BurnTexture = nullptr;
|
||||
}
|
||||
|
||||
BurnTexture = fb->CreateTexture("BurnWipe", WIDTH, HEIGHT, 1, GL_R8);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLSWFrameBuffer :: Wiper_Burn Destructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
OpenGLSWFrameBuffer::Wiper_Burn::~Wiper_Burn()
|
||||
{
|
||||
BurnTexture.reset();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// OpenGLSWFrameBuffer :: Wiper_Burn :: Run
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool OpenGLSWFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLSWFrameBuffer *fb)
|
||||
{
|
||||
bool done;
|
||||
|
||||
BurnTime += ticks;
|
||||
ticks *= 2;
|
||||
|
||||
// Make the fire burn
|
||||
done = false;
|
||||
while (!done && ticks--)
|
||||
{
|
||||
Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density);
|
||||
done = (Density < 0);
|
||||
}
|
||||
|
||||
// Update the burn texture with the new burn data
|
||||
|
||||
if (BurnTexture->Buffers[0] == 0)
|
||||
{
|
||||
glGenBuffers(2, (GLuint*)BurnTexture->Buffers);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BurnTexture->Buffers[0]);
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, WIDTH * HEIGHT, nullptr, GL_STREAM_DRAW);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BurnTexture->Buffers[1]);
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, WIDTH * HEIGHT, nullptr, GL_STREAM_DRAW);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, BurnTexture->Buffers[BurnTexture->CurrentBuffer]);
|
||||
BurnTexture->CurrentBuffer = (BurnTexture->CurrentBuffer + 1) & 1;
|
||||
}
|
||||
|
||||
uint8_t *dest = (uint8_t*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, WIDTH * HEIGHT, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
if (dest)
|
||||
{
|
||||
memcpy(dest, BurnArray, WIDTH * HEIGHT);
|
||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||
|
||||
GLint oldBinding = 0;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldBinding);
|
||||
glBindTexture(GL_TEXTURE_2D, BurnTexture->Texture);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, WIDTH, HEIGHT, GL_RED, GL_UNSIGNED_BYTE, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, oldBinding);
|
||||
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
}
|
||||
|
||||
// Put the initial screen back to the buffer.
|
||||
DrawScreen(fb, fb->InitialWipeScreen.get());
|
||||
|
||||
// Burn the new screen on top of it.
|
||||
float right = float(fb->Width);
|
||||
float bot = float(fb->Height);
|
||||
|
||||
BURNVERTEX verts[4] =
|
||||
{
|
||||
{ 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0, 0 },
|
||||
{ right, 0.f, 0.f, 1.f, 1.f, 0.f, 1, 0 },
|
||||
{ right, bot, 0.f, 1.f, 1.f, 1.f, 1, 1 },
|
||||
{ 0.f, bot, 0.f, 1.f, 0.f, 1.f, 0, 1 }
|
||||
};
|
||||
|
||||
fb->SetTexture(0, fb->FinalWipeScreen.get());
|
||||
fb->SetTexture(1, BurnTexture.get());
|
||||
fb->SetAlphaBlend(GL_FUNC_ADD, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
fb->SetPixelShader(fb->Shaders[SHADER_BurnWipe].get());
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
fb->DrawTriangleFans(2, verts);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
// The fire may not always stabilize, so the wipe is forced to end
|
||||
// after an arbitrary maximum time.
|
||||
return done || (BurnTime > 40);
|
||||
}
|
|
@ -44,7 +44,6 @@
|
|||
#include "gl/textures/gl_samplers.h"
|
||||
#include "gl/utility/gl_templates.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/renderer/gl_2ddrawer.h"
|
||||
|
||||
|
||||
//===========================================================================
|
||||
|
|
|
@ -521,14 +521,7 @@ DFrameBuffer* CocoaVideo::CreateFrameBuffer(const int width, const int height, c
|
|||
|
||||
DFrameBuffer* fb = NULL;
|
||||
|
||||
if (1 == currentrenderer)
|
||||
{
|
||||
fb = new OpenGLFrameBuffer(NULL, width, height, 32, 60, fullscreen);
|
||||
}
|
||||
else
|
||||
{
|
||||
fb = CreateGLSWFrameBuffer(width, height, bgra, fullscreen);
|
||||
}
|
||||
fb = new OpenGLFrameBuffer(NULL, width, height, 32, 60, fullscreen);
|
||||
|
||||
fb->SetFlash(flashColor, flashAmount);
|
||||
|
||||
|
|
|
@ -170,14 +170,7 @@ DFrameBuffer *SDLGLVideo::CreateFrameBuffer (int width, int height, bool bgra, b
|
|||
}
|
||||
|
||||
SDLBaseFB *fb;
|
||||
if (vid_renderer == 1)
|
||||
{
|
||||
fb = new OpenGLFrameBuffer(0, width, height, 32, 60, fullscreen);
|
||||
}
|
||||
else
|
||||
{
|
||||
fb = (SDLBaseFB*)CreateGLSWFrameBuffer(width, height, bgra, fullscreen);
|
||||
}
|
||||
fb = new OpenGLFrameBuffer(0, width, height, 32, 60, fullscreen);
|
||||
|
||||
retry = 0;
|
||||
|
||||
|
|
|
@ -172,7 +172,6 @@ FTexture::~FTexture ()
|
|||
{
|
||||
FTexture *link = Wads.GetLinkedTexture(SourceLump);
|
||||
if (link == this) Wads.SetLinkedTexture(SourceLump, NULL);
|
||||
KillNative();
|
||||
}
|
||||
|
||||
void FTexture::Unload()
|
||||
|
@ -711,40 +710,6 @@ void FTexture::FlipNonSquareBlockRemap (uint8_t *dst, const uint8_t *src, int x,
|
|||
}
|
||||
}
|
||||
|
||||
FNativeTexture *FTexture::GetNative(FTextureFormat fmt, bool wrapping)
|
||||
{
|
||||
if (Native[fmt] != NULL)
|
||||
{
|
||||
if (!Native[fmt]->CheckWrapping(wrapping))
|
||||
{ // Texture's wrapping mode is not compatible.
|
||||
// Destroy it and get a new one.
|
||||
delete Native[fmt];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CheckModified(DefaultRenderStyle()))
|
||||
{
|
||||
Native[fmt]->Update();
|
||||
}
|
||||
return Native[fmt];
|
||||
}
|
||||
}
|
||||
Native[fmt] = screen->CreateTexture(this, fmt, wrapping);
|
||||
return Native[fmt];
|
||||
}
|
||||
|
||||
void FTexture::KillNative()
|
||||
{
|
||||
for (auto &nat : Native)
|
||||
{
|
||||
if (nat != nullptr)
|
||||
{
|
||||
delete nat;
|
||||
nat = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FTexture::FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat fmt)
|
||||
{
|
||||
const uint8_t *pix;
|
||||
|
|
|
@ -163,10 +163,6 @@ enum FTextureFormat : uint32_t
|
|||
TEX_Count
|
||||
};
|
||||
|
||||
class FNativeTexture;
|
||||
|
||||
|
||||
|
||||
// Base texture class
|
||||
class FTexture
|
||||
{
|
||||
|
@ -237,12 +233,6 @@ public:
|
|||
// Returns the native pixel format for this image
|
||||
virtual FTextureFormat GetFormat();
|
||||
|
||||
// Returns a native 3D representation of the texture
|
||||
FNativeTexture *GetNative(FTextureFormat fmt, bool wrapping);
|
||||
|
||||
// Frees the native 3D representation of the texture
|
||||
void KillNative();
|
||||
|
||||
// Fill the native texture buffer with pixel data for this image
|
||||
virtual void FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat fmt);
|
||||
|
||||
|
@ -291,7 +281,6 @@ public:
|
|||
protected:
|
||||
uint16_t Width, Height, WidthMask;
|
||||
static uint8_t GrayMap[256];
|
||||
FNativeTexture *Native[TEX_Count] = { nullptr }; // keep a slot for each type, because some render modes do not work with the base texture
|
||||
uint8_t *GetRemap(FRenderStyle style, bool srcisgrayscale = false)
|
||||
{
|
||||
if (style.Flags & STYLEF_RedIsAlpha)
|
||||
|
@ -380,9 +369,6 @@ public:
|
|||
static void FlipNonSquareBlockBgra (uint32_t *blockto, const uint32_t *blockfrom, int x, int y, int srcpitch);
|
||||
static void FlipNonSquareBlockRemap (uint8_t *blockto, const uint8_t *blockfrom, int x, int y, int srcpitch, const uint8_t *remap);
|
||||
|
||||
friend class FNativeTexture;
|
||||
friend class OpenGLSWFrameBuffer;
|
||||
|
||||
public:
|
||||
|
||||
struct MiscGLInfo
|
||||
|
|
|
@ -965,54 +965,6 @@ void FFont::LoadTranslations()
|
|||
delete[] luminosity;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FFont :: Preload
|
||||
//
|
||||
// Loads most of the 7-bit ASCII characters. In the case of D3DFB, this
|
||||
// means all the characters of a font have a better chance of being packed
|
||||
// into the same hardware texture.
|
||||
//
|
||||
// (Note that this is a rather dumb implementation. The atlasing should
|
||||
// occur at a higher level, independently of the renderer being used.)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFont::Preload() const
|
||||
{
|
||||
// First and last char are the same? Wait until it's actually needed
|
||||
// since nothing is gained by preloading now.
|
||||
if (FirstChar == LastChar)
|
||||
{
|
||||
return;
|
||||
}
|
||||
for (int i = MAX(FirstChar, 0x21); i < MIN(LastChar, 0x7e); ++i)
|
||||
{
|
||||
int foo;
|
||||
FTexture *pic = GetChar(i, &foo);
|
||||
if (pic != NULL)
|
||||
{
|
||||
pic->GetNative(pic->GetFormat(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FFont :: StaticPreloadFonts
|
||||
//
|
||||
// Preloads all the defined fonts.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFont::StaticPreloadFonts()
|
||||
{
|
||||
for (FFont *font = FirstFont; font != NULL; font = font->Next)
|
||||
{
|
||||
font->Preload();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FFont :: FFont - default constructor
|
||||
|
|
|
@ -90,11 +90,9 @@ public:
|
|||
int GetHeight () const { return FontHeight; }
|
||||
int GetDefaultKerning () const { return GlobalKerning; }
|
||||
virtual void LoadTranslations();
|
||||
void Preload() const;
|
||||
FName GetName() const { return FontName; }
|
||||
|
||||
static FFont *FindFont(FName fontname);
|
||||
static void StaticPreloadFonts();
|
||||
|
||||
// Return width of string in pixels (unscaled)
|
||||
int StringWidth (const uint8_t *str) const;
|
||||
|
|
|
@ -882,21 +882,6 @@ void DFrameBuffer::DrawBlendingRect()
|
|||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DFrameBuffer :: CreateTexture
|
||||
//
|
||||
// Creates a native texture for a game texture, if supported.
|
||||
// The hardware renderer does not use this interface because it is
|
||||
// far too limited
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FNativeTexture *DFrameBuffer::CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DFrameBuffer :: CreatePalette
|
||||
|
@ -983,20 +968,6 @@ FNativePalette::~FNativePalette()
|
|||
{
|
||||
}
|
||||
|
||||
FNativeTexture::~FNativeTexture()
|
||||
{
|
||||
// Remove link from the game texture
|
||||
if (mGameTex != nullptr)
|
||||
{
|
||||
mGameTex->Native[mFormat] = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool FNativeTexture::CheckWrapping(bool wrapping)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
CCMD(clean)
|
||||
{
|
||||
|
@ -1018,10 +989,6 @@ bool V_DoModeSetup (int width, int height, int bits)
|
|||
screen = buff;
|
||||
screen->SetGamma (Gamma);
|
||||
|
||||
// Load fonts now so they can be packed into textures straight away,
|
||||
// if D3DFB is being used for the display.
|
||||
FFont::StaticPreloadFonts();
|
||||
|
||||
DisplayBits = bits;
|
||||
V_UpdateModeSize(screen->GetWidth(), screen->GetHeight());
|
||||
|
||||
|
|
|
@ -259,18 +259,6 @@ public:
|
|||
void Resize(int width, int height);
|
||||
};
|
||||
|
||||
// This class represents a native texture, as opposed to an FTexture.
|
||||
class FNativeTexture
|
||||
{
|
||||
protected:
|
||||
FTexture * mGameTex;
|
||||
FTextureFormat mFormat;
|
||||
public:
|
||||
FNativeTexture(FTexture *tex, FTextureFormat fmt) : mGameTex(tex), mFormat(fmt) {}
|
||||
virtual ~FNativeTexture();
|
||||
virtual bool Update() = 0;
|
||||
virtual bool CheckWrapping(bool wrapping);
|
||||
};
|
||||
|
||||
// This class represents a texture lookup palette.
|
||||
class FNativePalette
|
||||
|
@ -381,9 +369,6 @@ public:
|
|||
// accelerated 2D mode.
|
||||
virtual void DrawBlendingRect();
|
||||
|
||||
// Create a native texture from a game texture.
|
||||
virtual FNativeTexture *CreateTexture(FTexture *gametex, FTextureFormat fmt, bool wrapping);
|
||||
|
||||
// Create a palette texture from a remap/palette table.
|
||||
virtual FNativePalette *CreatePalette(FRemapTable *remap);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,627 +0,0 @@
|
|||
/*
|
||||
** fb_d3d9_wipe.cpp
|
||||
** Implements the different screen wipes using Direct3D calls.
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2008 Randy Heit
|
||||
** 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.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define D3D_DEBUG_INFO
|
||||
#endif
|
||||
#define DIRECT3D_VERSION 0x0900
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <windows.h>
|
||||
#include <d3d9.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "f_wipe.h"
|
||||
#include "win32iface.h"
|
||||
#include "win32swiface.h"
|
||||
#include "templates.h"
|
||||
#include "m_random.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
class D3DFB::Wiper_Crossfade : public D3DFB::Wiper
|
||||
{
|
||||
public:
|
||||
Wiper_Crossfade();
|
||||
bool Run(int ticks, D3DFB *fb);
|
||||
|
||||
private:
|
||||
int Clock;
|
||||
};
|
||||
|
||||
class D3DFB::Wiper_Melt : public D3DFB::Wiper
|
||||
{
|
||||
public:
|
||||
Wiper_Melt();
|
||||
bool Run(int ticks, D3DFB *fb);
|
||||
|
||||
private:
|
||||
// Match the strip sizes that oldschool Doom used.
|
||||
static const int WIDTH = 160, HEIGHT = 200;
|
||||
int y[WIDTH];
|
||||
};
|
||||
|
||||
class D3DFB::Wiper_Burn : public D3DFB::Wiper
|
||||
{
|
||||
public:
|
||||
Wiper_Burn(D3DFB *fb);
|
||||
~Wiper_Burn();
|
||||
bool Run(int ticks, D3DFB *fb);
|
||||
|
||||
private:
|
||||
static const int WIDTH = 64, HEIGHT = 64;
|
||||
uint8_t BurnArray[WIDTH * (HEIGHT + 5)];
|
||||
IDirect3DTexture9 *BurnTexture;
|
||||
int Density;
|
||||
int BurnTime;
|
||||
|
||||
struct BURNVERTEX
|
||||
{
|
||||
FLOAT x, y, z, rhw;
|
||||
FLOAT tu0, tv0;
|
||||
FLOAT tu1, tv1;
|
||||
};
|
||||
#define D3DFVF_BURNVERTEX (D3DFVF_XYZRHW|D3DFVF_TEX2)
|
||||
};
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: WipeStartScreen
|
||||
//
|
||||
// Called before the current screen has started rendering. This needs to
|
||||
// save what was drawn the previous frame so that it can be animated into
|
||||
// what gets drawn this frame.
|
||||
//
|
||||
// In fullscreen mode, we use GetFrontBufferData() to grab the data that
|
||||
// is visible on screen right now.
|
||||
//
|
||||
// In windowed mode, we can't do that because we'll get the whole desktop.
|
||||
// Instead, we can conveniently use the TempRenderTexture, which is normally
|
||||
// used for gamma-correcting copying the image to the back buffer.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool D3DFB::WipeStartScreen(int type)
|
||||
{
|
||||
IDirect3DSurface9 *tsurf;
|
||||
D3DSURFACE_DESC desc;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case wipe_Melt:
|
||||
ScreenWipe = new Wiper_Melt;
|
||||
break;
|
||||
|
||||
case wipe_Burn:
|
||||
ScreenWipe = new Wiper_Burn(this);
|
||||
break;
|
||||
|
||||
case wipe_Fade:
|
||||
ScreenWipe = new Wiper_Crossfade;
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
InitialWipeScreen = GetCurrentScreen(D3DPOOL_DEFAULT);
|
||||
|
||||
// Create another texture to copy the final wipe screen to so
|
||||
// we can still gamma correct the wipe. Since this is just for
|
||||
// gamma correction, it's okay to fail (though not desirable.)
|
||||
if (PixelDoubling || Windowed)
|
||||
{
|
||||
if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &tsurf)))
|
||||
{
|
||||
if (FAILED(tsurf->GetDesc(&desc)) ||
|
||||
FAILED(D3DDevice->CreateTexture(desc.Width, desc.Height,
|
||||
1, D3DUSAGE_RENDERTARGET, desc.Format, D3DPOOL_DEFAULT,
|
||||
&FinalWipeScreen, NULL)))
|
||||
{
|
||||
(FinalWipeScreen = TempRenderTexture)->AddRef();
|
||||
}
|
||||
tsurf->Release();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(FinalWipeScreen = TempRenderTexture)->AddRef();
|
||||
}
|
||||
|
||||
// Make even fullscreen model render to the TempRenderTexture, so
|
||||
// we can have a copy of the new screen readily available.
|
||||
GatheringWipeScreen = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: WipeEndScreen
|
||||
//
|
||||
// The screen we want to animate to has just been drawn. This function is
|
||||
// called in place of Update(), so it has not been Presented yet.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void D3DFB::WipeEndScreen()
|
||||
{
|
||||
// Don't do anything if there is no starting point.
|
||||
if (InitialWipeScreen == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If the whole screen was drawn without 2D accel, get it in to
|
||||
// video memory now.
|
||||
if (!In2D)
|
||||
{
|
||||
Begin2D(true);
|
||||
}
|
||||
|
||||
EndQuadBatch(); // Make sure all batched primitives have been drawn.
|
||||
|
||||
// Don't do anything if there is no ending point.
|
||||
if (OldRenderTarget == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If these are different, reverse their roles so we don't need to
|
||||
// waste time copying from TempRenderTexture to FinalWipeScreen.
|
||||
if (FinalWipeScreen != TempRenderTexture)
|
||||
{
|
||||
swapvalues(RenderTexture[CurrRenderTexture], FinalWipeScreen);
|
||||
TempRenderTexture = RenderTexture[CurrRenderTexture];
|
||||
}
|
||||
|
||||
// At this point, InitialWipeScreen holds the screen we are wiping from.
|
||||
// FinalWipeScreen holds the screen we are wiping to, which may be the
|
||||
// same texture as TempRenderTexture.
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: WipeDo
|
||||
//
|
||||
// Perform the actual wipe animation. The number of tics since the last
|
||||
// time this function was called is passed in. Returns true when the wipe
|
||||
// is over. The first time this function has been called, the screen is
|
||||
// still locked from before and EndScene() still has not been called.
|
||||
// Successive times need to call BeginScene().
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool D3DFB::WipeDo(int ticks)
|
||||
{
|
||||
// Sanity checks.
|
||||
if (InitialWipeScreen == NULL || FinalWipeScreen == NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (GatheringWipeScreen)
|
||||
{ // This is the first time we've been called for this wipe.
|
||||
GatheringWipeScreen = false;
|
||||
|
||||
if (OldRenderTarget == NULL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
D3DDevice->SetRenderTarget(0, OldRenderTarget);
|
||||
}
|
||||
else
|
||||
{ // This is the second or later time we've been called for this wipe.
|
||||
D3DDevice->BeginScene();
|
||||
InScene = true;
|
||||
}
|
||||
SAFE_RELEASE( OldRenderTarget );
|
||||
if (TempRenderTexture != NULL && TempRenderTexture != FinalWipeScreen)
|
||||
{
|
||||
IDirect3DSurface9 *targetsurf;
|
||||
if (SUCCEEDED(TempRenderTexture->GetSurfaceLevel(0, &targetsurf)))
|
||||
{
|
||||
if (SUCCEEDED(D3DDevice->GetRenderTarget(0, &OldRenderTarget)))
|
||||
{
|
||||
if (FAILED(D3DDevice->SetRenderTarget(0, targetsurf)))
|
||||
{
|
||||
// Setting the render target failed.
|
||||
}
|
||||
}
|
||||
targetsurf->Release();
|
||||
}
|
||||
}
|
||||
In2D = 3;
|
||||
|
||||
EnableAlphaTest(FALSE);
|
||||
bool done = ScreenWipe->Run(ticks, this);
|
||||
DrawLetterbox();
|
||||
return done;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: WipeCleanup
|
||||
//
|
||||
// Release any resources that were specifically created for the wipe.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void D3DFB::WipeCleanup()
|
||||
{
|
||||
if (ScreenWipe != NULL)
|
||||
{
|
||||
delete ScreenWipe;
|
||||
ScreenWipe = NULL;
|
||||
}
|
||||
SAFE_RELEASE( InitialWipeScreen );
|
||||
SAFE_RELEASE( FinalWipeScreen );
|
||||
GatheringWipeScreen = false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
D3DFB::Wiper::~Wiper()
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper :: DrawScreen
|
||||
//
|
||||
// Draw either the initial or target screen completely to the screen.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void D3DFB::Wiper::DrawScreen(D3DFB *fb, IDirect3DTexture9 *tex,
|
||||
D3DBLENDOP blendop, D3DCOLOR color0, D3DCOLOR color1)
|
||||
{
|
||||
FBVERTEX verts[4];
|
||||
|
||||
fb->CalcFullscreenCoords(verts, false, false, color0, color1);
|
||||
fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX);
|
||||
fb->SetTexture(0, tex);
|
||||
fb->SetAlphaBlend(blendop, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
fb->SetPixelShader(fb->Shaders[SHADER_NormalColor]);
|
||||
fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(FBVERTEX));
|
||||
}
|
||||
|
||||
// WIPE: CROSSFADE ---------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper_Crossfade Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
D3DFB::Wiper_Crossfade::Wiper_Crossfade()
|
||||
: Clock(0)
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper_Crossfade :: Run
|
||||
//
|
||||
// Fades the old screen into the new one over 32 ticks.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool D3DFB::Wiper_Crossfade::Run(int ticks, D3DFB *fb)
|
||||
{
|
||||
Clock += ticks;
|
||||
|
||||
// Put the initial screen back to the buffer.
|
||||
DrawScreen(fb, fb->InitialWipeScreen);
|
||||
|
||||
// Draw the new screen on top of it.
|
||||
DrawScreen(fb, fb->FinalWipeScreen, D3DBLENDOP_ADD,
|
||||
D3DCOLOR_COLORVALUE(0,0,0,Clock / 32.f), D3DCOLOR_RGBA(255,255,255,0));
|
||||
|
||||
return Clock >= 32;
|
||||
}
|
||||
|
||||
// WIPE: MELT --------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper_Melt Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
D3DFB::Wiper_Melt::Wiper_Melt()
|
||||
{
|
||||
int i, r;
|
||||
|
||||
// setup initial column positions
|
||||
// (y<0 => not ready to scroll yet)
|
||||
y[0] = -(M_Random() & 15);
|
||||
for (i = 1; i < WIDTH; ++i)
|
||||
{
|
||||
r = (M_Random()%3) - 1;
|
||||
y[i] = clamp(y[i-1] + r, -15, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper_Melt :: Run
|
||||
//
|
||||
// Fades the old screen into the new one over 32 ticks.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool D3DFB::Wiper_Melt::Run(int ticks, D3DFB *fb)
|
||||
{
|
||||
// Draw the new screen on the bottom.
|
||||
DrawScreen(fb, fb->FinalWipeScreen);
|
||||
|
||||
int i, dy;
|
||||
int fbwidth = fb->Width;
|
||||
int fbheight = fb->Height;
|
||||
bool done = true;
|
||||
|
||||
// Copy the old screen in vertical strips on top of the new one.
|
||||
while (ticks--)
|
||||
{
|
||||
done = true;
|
||||
for (i = 0; i < WIDTH; i++)
|
||||
{
|
||||
if (y[i] < 0)
|
||||
{
|
||||
y[i]++;
|
||||
done = false;
|
||||
}
|
||||
else if (y[i] < HEIGHT)
|
||||
{
|
||||
dy = (y[i] < 16) ? y[i]+1 : 8;
|
||||
y[i] = MIN(y[i] + dy, HEIGHT);
|
||||
done = false;
|
||||
}
|
||||
if (ticks == 0)
|
||||
{ // Only draw for the final tick.
|
||||
RECT rect;
|
||||
POINT dpt;
|
||||
|
||||
dpt.x = i * fbwidth / WIDTH;
|
||||
dpt.y = MAX(0, y[i] * fbheight / HEIGHT);
|
||||
rect.left = dpt.x;
|
||||
rect.top = 0;
|
||||
rect.right = (i + 1) * fbwidth / WIDTH;
|
||||
rect.bottom = fbheight - dpt.y;
|
||||
if (rect.bottom > rect.top)
|
||||
{
|
||||
fb->CheckQuadBatch();
|
||||
|
||||
BufferedTris *quad = &fb->QuadExtra[fb->QuadBatchPos];
|
||||
FBVERTEX *vert = &fb->VertexData[fb->VertexPos];
|
||||
uint16_t *index = &fb->IndexData[fb->IndexPos];
|
||||
|
||||
quad->Group1 = 0;
|
||||
quad->Flags = BQF_DisableAlphaTest;
|
||||
quad->ShaderNum = BQS_Plain;
|
||||
quad->Palette = NULL;
|
||||
quad->Texture = fb->InitialWipeScreen;
|
||||
quad->NumVerts = 4;
|
||||
quad->NumTris = 2;
|
||||
|
||||
// Fill the vertex buffer.
|
||||
float u0 = rect.left / float(fb->FBWidth);
|
||||
float v0 = 0;
|
||||
float u1 = rect.right / float(fb->FBWidth);
|
||||
float v1 = (rect.bottom - rect.top) / float(fb->FBHeight);
|
||||
|
||||
float x0 = float(rect.left) - 0.5f;
|
||||
float x1 = float(rect.right) - 0.5f;
|
||||
float y0 = float(dpt.y + fb->LBOffsetI) - 0.5f;
|
||||
float y1 = float(fbheight + fb->LBOffsetI) - 0.5f;
|
||||
|
||||
vert[0].x = x0;
|
||||
vert[0].y = y0;
|
||||
vert[0].z = 0;
|
||||
vert[0].rhw = 1;
|
||||
vert[0].color0 = 0;
|
||||
vert[0].color1 = 0xFFFFFFF;
|
||||
vert[0].tu = u0;
|
||||
vert[0].tv = v0;
|
||||
|
||||
vert[1].x = x1;
|
||||
vert[1].y = y0;
|
||||
vert[1].z = 0;
|
||||
vert[1].rhw = 1;
|
||||
vert[1].color0 = 0;
|
||||
vert[1].color1 = 0xFFFFFFF;
|
||||
vert[1].tu = u1;
|
||||
vert[1].tv = v0;
|
||||
|
||||
vert[2].x = x1;
|
||||
vert[2].y = y1;
|
||||
vert[2].z = 0;
|
||||
vert[2].rhw = 1;
|
||||
vert[2].color0 = 0;
|
||||
vert[2].color1 = 0xFFFFFFF;
|
||||
vert[2].tu = u1;
|
||||
vert[2].tv = v1;
|
||||
|
||||
vert[3].x = x0;
|
||||
vert[3].y = y1;
|
||||
vert[3].z = 0;
|
||||
vert[3].rhw = 1;
|
||||
vert[3].color0 = 0;
|
||||
vert[3].color1 = 0xFFFFFFF;
|
||||
vert[3].tu = u0;
|
||||
vert[3].tv = v1;
|
||||
|
||||
// Fill the vertex index buffer.
|
||||
index[0] = fb->VertexPos;
|
||||
index[1] = fb->VertexPos + 1;
|
||||
index[2] = fb->VertexPos + 2;
|
||||
index[3] = fb->VertexPos;
|
||||
index[4] = fb->VertexPos + 2;
|
||||
index[5] = fb->VertexPos + 3;
|
||||
|
||||
// Batch the quad.
|
||||
fb->QuadBatchPos++;
|
||||
fb->VertexPos += 4;
|
||||
fb->IndexPos += 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fb->EndQuadBatch();
|
||||
return done;
|
||||
}
|
||||
|
||||
// WIPE: BURN --------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper_Burn Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
D3DFB::Wiper_Burn::Wiper_Burn(D3DFB *fb)
|
||||
{
|
||||
Density = 4;
|
||||
BurnTime = 0;
|
||||
memset(BurnArray, 0, sizeof(BurnArray));
|
||||
if (fb->Shaders[SHADER_BurnWipe] == NULL || FAILED(fb->D3DDevice->CreateTexture(WIDTH, HEIGHT, 1,
|
||||
D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &BurnTexture, NULL)))
|
||||
{
|
||||
BurnTexture = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper_Burn Destructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
D3DFB::Wiper_Burn::~Wiper_Burn()
|
||||
{
|
||||
SAFE_RELEASE( BurnTexture );
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// D3DFB :: Wiper_Burn :: Run
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool D3DFB::Wiper_Burn::Run(int ticks, D3DFB *fb)
|
||||
{
|
||||
bool done;
|
||||
|
||||
BurnTime += ticks;
|
||||
ticks *= 2;
|
||||
|
||||
// Make the fire burn
|
||||
done = false;
|
||||
while (!done && ticks--)
|
||||
{
|
||||
Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density);
|
||||
done = (Density < 0);
|
||||
}
|
||||
|
||||
// Update the burn texture with the new burn data
|
||||
D3DLOCKED_RECT lrect;
|
||||
if (SUCCEEDED(BurnTexture->LockRect(0, &lrect, NULL, D3DLOCK_DISCARD)))
|
||||
{
|
||||
const uint8_t *src = BurnArray;
|
||||
uint8_t *dest = (uint8_t *)lrect.pBits;
|
||||
for (int y = HEIGHT; y != 0; --y)
|
||||
{
|
||||
for (int x = WIDTH; x != 0; --x)
|
||||
{
|
||||
*dest++ = *src++;
|
||||
}
|
||||
dest += lrect.Pitch - WIDTH;
|
||||
}
|
||||
BurnTexture->UnlockRect(0);
|
||||
}
|
||||
|
||||
// Put the initial screen back to the buffer.
|
||||
DrawScreen(fb, fb->InitialWipeScreen);
|
||||
|
||||
// Burn the new screen on top of it.
|
||||
float top = fb->LBOffset - 0.5f;
|
||||
float right = float(fb->Width) - 0.5f;
|
||||
float bot = float(fb->Height) + top;
|
||||
float texright = float(fb->Width) / float(fb->FBWidth);
|
||||
float texbot = float(fb->Height) / float(fb->FBHeight);
|
||||
|
||||
BURNVERTEX verts[4] =
|
||||
{
|
||||
{ -0.5f, top, 0.5f, 1.f, 0.f, 0.f, 0, 0 },
|
||||
{ right, top, 0.5f, 1.f, texright, 0.f, 1, 0 },
|
||||
{ right, bot, 0.5f, 1.f, texright, texbot, 1, 1 },
|
||||
{ -0.5f, bot, 0.5f, 1.f, 0.f, texbot, 0, 1 }
|
||||
};
|
||||
|
||||
fb->D3DDevice->SetFVF(D3DFVF_BURNVERTEX);
|
||||
fb->SetTexture(0, fb->FinalWipeScreen);
|
||||
fb->SetTexture(1, BurnTexture);
|
||||
fb->SetAlphaBlend(D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA);
|
||||
fb->SetPixelShader(fb->Shaders[SHADER_BurnWipe]);
|
||||
fb->D3DDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
|
||||
fb->D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(BURNVERTEX));
|
||||
fb->D3DDevice->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
|
||||
fb->D3DDevice->SetFVF(D3DFVF_FBVERTEX);
|
||||
|
||||
// The fire may not always stabilize, so the wipe is forced to end
|
||||
// after an arbitrary maximum time.
|
||||
return done || (BurnTime > 40);
|
||||
}
|
|
@ -178,13 +178,7 @@ void I_InitGraphics ()
|
|||
val.Bool = !!Args->CheckParm ("-devparm");
|
||||
ticker.SetGenericRepDefault (val, CVAR_Bool);
|
||||
|
||||
if (currentcanvas == 0) // Software Canvas: 0 = D3D or DirectDraw, 1 = OpenGL
|
||||
if (currentrenderer == 1)
|
||||
Video = gl_CreateVideo();
|
||||
else
|
||||
Video = new Win32Video(0);
|
||||
else
|
||||
Video = gl_CreateVideo();
|
||||
Video = gl_CreateVideo();
|
||||
|
||||
if (Video == NULL)
|
||||
I_FatalError ("Failed to initialize display");
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/system/gl_swframebuffer.h"
|
||||
|
||||
extern HWND Window;
|
||||
extern BOOL AppActive;
|
||||
|
@ -501,10 +500,7 @@ DFrameBuffer *Win32GLVideo::CreateFrameBuffer(int width, int height, bool bgra,
|
|||
//old->GetFlash(flashColor, flashAmount);
|
||||
delete old;
|
||||
}
|
||||
if (vid_renderer == 1)
|
||||
fb = new OpenGLFrameBuffer(m_hMonitor, m_DisplayWidth, m_DisplayHeight, m_DisplayBits, m_DisplayHz, fs);
|
||||
else
|
||||
fb = new OpenGLSWFrameBuffer(m_hMonitor, m_DisplayWidth, m_DisplayHeight, m_DisplayBits, m_DisplayHz, fs, bgra);
|
||||
fb = new OpenGLFrameBuffer(m_hMonitor, m_DisplayWidth, m_DisplayHeight, m_DisplayBits, m_DisplayHz, fs);
|
||||
return fb;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,64 +39,8 @@
|
|||
|
||||
EXTERN_CVAR (Bool, vid_vsync)
|
||||
|
||||
class D3DTex;
|
||||
class D3DPal;
|
||||
struct FSoftwareRenderer;
|
||||
|
||||
class Win32Video : public IVideo
|
||||
{
|
||||
public:
|
||||
Win32Video (int parm);
|
||||
~Win32Video ();
|
||||
|
||||
bool InitD3D9();
|
||||
|
||||
EDisplayType GetDisplayType () { return DISPLAY_Both; }
|
||||
void SetWindowedScale (float scale);
|
||||
|
||||
DFrameBuffer *CreateFrameBuffer (int width, int height, bool bgra, bool fs, DFrameBuffer *old);
|
||||
|
||||
void StartModeIterator (int bits, bool fs);
|
||||
bool NextMode (int *width, int *height, bool *letterbox);
|
||||
|
||||
bool GoFullscreen (bool yes);
|
||||
|
||||
void DumpAdapters ();
|
||||
void AddMode(int x, int y, int bits, int baseHeight, int doubling);
|
||||
|
||||
private:
|
||||
struct ModeInfo
|
||||
{
|
||||
ModeInfo (int inX, int inY, int inBits, int inRealY, int inDoubling)
|
||||
: next (NULL),
|
||||
width (inX),
|
||||
height (inY),
|
||||
bits (inBits),
|
||||
realheight (inRealY),
|
||||
doubling (inDoubling)
|
||||
{}
|
||||
|
||||
ModeInfo *next;
|
||||
int width, height, bits;
|
||||
int realheight;
|
||||
int doubling;
|
||||
} *m_Modes;
|
||||
|
||||
ModeInfo *m_IteratorMode;
|
||||
int m_IteratorBits;
|
||||
bool m_IteratorFS;
|
||||
bool m_IsFullscreen;
|
||||
unsigned int m_Adapter;
|
||||
|
||||
void FreeModes ();
|
||||
|
||||
void AddD3DModes (unsigned adapter);
|
||||
void AddLowResModes ();
|
||||
void AddLetterboxModes ();
|
||||
void ScaleModes (int doubling);
|
||||
|
||||
friend class D3DFB;
|
||||
};
|
||||
|
||||
class BaseWinFB : public DFrameBuffer
|
||||
{
|
||||
|
|
|
@ -1,304 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef DIRECTDRAW_VERSION
|
||||
#define DIRECTDRAW_VERSION 0x0300
|
||||
#endif
|
||||
#ifndef DIRECT3D_VERSION
|
||||
#define DIRECT3D_VERSION 0x0900
|
||||
#endif
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <ddraw.h>
|
||||
#include <d3d9.h>
|
||||
|
||||
#define SAFE_RELEASE(x) { if (x != NULL) { x->Release(); x = NULL; } }
|
||||
|
||||
extern HANDLE FPSLimitEvent;
|
||||
|
||||
|
||||
class D3DFB : public BaseWinFB
|
||||
{
|
||||
typedef BaseWinFB Super;
|
||||
|
||||
DSimpleCanvas *RenderBuffer = nullptr;
|
||||
|
||||
public:
|
||||
D3DFB (UINT adapter, int width, int height, bool bgra, bool fullscreen);
|
||||
~D3DFB ();
|
||||
virtual DCanvas *GetCanvas() { return RenderBuffer; }
|
||||
|
||||
void Update ();
|
||||
void Flip ();
|
||||
PalEntry *GetPalette ();
|
||||
void GetFlashedPalette (PalEntry palette[256]);
|
||||
void UpdatePalette ();
|
||||
bool SetGamma (float gamma);
|
||||
bool SetFlash (PalEntry rgb, int amount);
|
||||
void GetFlash (PalEntry &rgb, int &amount);
|
||||
int GetPageCount ();
|
||||
bool IsFullscreen ();
|
||||
void SetVSync (bool vsync);
|
||||
void NewRefreshRate();
|
||||
void GetScreenshotBuffer(const uint8_t *&buffer, int &pitch, ESSType &color_type, float &gamma) override;
|
||||
void ReleaseScreenshotBuffer();
|
||||
void SetBlendingRect (int x1, int y1, int x2, int y2);
|
||||
bool Begin2D (bool copy3d);
|
||||
void DrawBlendingRect ();
|
||||
FNativeTexture *CreateTexture (FTexture *gametex, FTextureFormat fmt, bool wrapping);
|
||||
FNativePalette *CreatePalette (FRemapTable *remap);
|
||||
bool WipeStartScreen(int type);
|
||||
void WipeEndScreen();
|
||||
bool WipeDo(int ticks);
|
||||
void WipeCleanup();
|
||||
virtual int GetTrueHeight() { return TrueHeight; }
|
||||
|
||||
private:
|
||||
friend class D3DTex;
|
||||
friend class D3DPal;
|
||||
|
||||
struct PackedTexture;
|
||||
struct Atlas;
|
||||
|
||||
struct FBVERTEX
|
||||
{
|
||||
FLOAT x, y, z, rhw;
|
||||
D3DCOLOR color0, color1;
|
||||
FLOAT tu, tv;
|
||||
};
|
||||
#define D3DFVF_FBVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1)
|
||||
|
||||
struct BufferedTris
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t Flags;
|
||||
uint8_t ShaderNum:4;
|
||||
uint8_t BlendOp:4;
|
||||
uint8_t SrcBlend, DestBlend;
|
||||
};
|
||||
DWORD Group1;
|
||||
};
|
||||
uint8_t Desat;
|
||||
D3DPal *Palette;
|
||||
IDirect3DTexture9 *Texture;
|
||||
int NumVerts; // Number of _unique_ vertices used by this set.
|
||||
int NumTris; // Number of triangles used by this set.
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PSCONST_Desaturation = 1,
|
||||
PSCONST_PaletteMod = 2,
|
||||
PSCONST_Color1 = 3,
|
||||
PSCONST_Color2 = 4,
|
||||
PSCONST_BUFFERED_MAX,
|
||||
PSCONST_Weights = 6,
|
||||
PSCONST_Gamma = 7,
|
||||
|
||||
};
|
||||
enum
|
||||
{
|
||||
SHADER_NormalColor,
|
||||
SHADER_NormalColorPal,
|
||||
SHADER_NormalColorD,
|
||||
SHADER_NormalColorPalD,
|
||||
SHADER_NormalColorInv,
|
||||
SHADER_NormalColorPalInv,
|
||||
SHADER_NormalColorOpaq,
|
||||
SHADER_NormalColorPalOpaq,
|
||||
SHADER_NormalColorInvOpaq,
|
||||
SHADER_NormalColorPalInvOpaq,
|
||||
|
||||
SHADER_AlphaTex,
|
||||
SHADER_PalAlphaTex,
|
||||
SHADER_Stencil,
|
||||
SHADER_PalStencil,
|
||||
|
||||
SHADER_VertexColor,
|
||||
|
||||
SHADER_SpecialColormap,
|
||||
SHADER_SpecialColormapPal,
|
||||
|
||||
SHADER_BurnWipe,
|
||||
SHADER_GammaCorrection,
|
||||
|
||||
NUM_SHADERS
|
||||
};
|
||||
static const char *const ShaderNames[NUM_SHADERS];
|
||||
|
||||
void SetInitialState();
|
||||
bool CreateResources();
|
||||
void ReleaseResources();
|
||||
bool LoadShaders();
|
||||
void CreateBlockSurfaces();
|
||||
bool CreateFBTexture();
|
||||
bool CreatePaletteTexture();
|
||||
bool CreateGammaTexture();
|
||||
bool CreateVertexes(int numv, int numi);
|
||||
void UploadPalette();
|
||||
void UpdateGammaTexture(float igamma);
|
||||
void FillPresentParameters (D3DPRESENT_PARAMETERS *pp, bool fullscreen, bool vsync);
|
||||
void CalcFullscreenCoords (FBVERTEX verts[4], bool viewarea_only, bool can_double, D3DCOLOR color0, D3DCOLOR color1) const;
|
||||
bool Reset();
|
||||
IDirect3DTexture9 *GetCurrentScreen(D3DPOOL pool=D3DPOOL_SYSTEMMEM);
|
||||
void ReleaseDefaultPoolItems();
|
||||
void KillNativePals();
|
||||
void KillNativeTexs();
|
||||
PackedTexture *AllocPackedTexture(int width, int height, bool wrapping, D3DFORMAT format);
|
||||
void DrawLetterbox();
|
||||
void Draw3DPart(bool copy3d);
|
||||
static D3DBLEND GetStyleAlpha(int type);
|
||||
void DoWindowedGamma();
|
||||
void CheckQuadBatch(int numtris=2, int numverts=4);
|
||||
void BeginQuadBatch();
|
||||
void EndQuadBatch();
|
||||
void CopyNextFrontBuffer();
|
||||
void Draw2D() override;
|
||||
|
||||
D3DCAPS9 DeviceCaps;
|
||||
|
||||
// State
|
||||
void EnableAlphaTest(BOOL enabled);
|
||||
void SetAlphaBlend(D3DBLENDOP op, D3DBLEND srcblend=D3DBLEND(0), D3DBLEND destblend=D3DBLEND(0));
|
||||
void SetConstant(int cnum, float r, float g, float b, float a);
|
||||
void SetPixelShader(IDirect3DPixelShader9 *shader);
|
||||
void SetTexture(int tnum, IDirect3DTexture9 *texture);
|
||||
void SetPaletteTexture(IDirect3DTexture9 *texture, int count, D3DCOLOR border_color);
|
||||
|
||||
BOOL AlphaTestEnabled;
|
||||
BOOL AlphaBlendEnabled;
|
||||
D3DBLENDOP AlphaBlendOp;
|
||||
D3DBLEND AlphaSrcBlend;
|
||||
D3DBLEND AlphaDestBlend;
|
||||
float Constant[PSCONST_BUFFERED_MAX][4];
|
||||
D3DCOLOR CurBorderColor;
|
||||
IDirect3DPixelShader9 *CurPixelShader;
|
||||
IDirect3DTexture9 *Texture[5];
|
||||
|
||||
PalEntry SourcePalette[256];
|
||||
D3DCOLOR BorderColor;
|
||||
D3DCOLOR FlashColor0, FlashColor1;
|
||||
PalEntry FlashColor;
|
||||
int FlashAmount;
|
||||
int TrueHeight;
|
||||
int PixelDoubling;
|
||||
int SkipAt;
|
||||
int LBOffsetI;
|
||||
int RenderTextureToggle;
|
||||
int CurrRenderTexture;
|
||||
float LBOffset;
|
||||
float Gamma;
|
||||
bool UpdatePending;
|
||||
bool NeedPalUpdate;
|
||||
bool NeedGammaUpdate;
|
||||
int FBWidth, FBHeight;
|
||||
D3DFORMAT FBFormat;
|
||||
bool VSync;
|
||||
RECT BlendingRect;
|
||||
int In2D;
|
||||
bool InScene;
|
||||
bool GatheringWipeScreen;
|
||||
bool AALines;
|
||||
uint8_t BlockNum;
|
||||
D3DPal *Palettes;
|
||||
D3DTex *Textures;
|
||||
Atlas *Atlases;
|
||||
HRESULT LastHR;
|
||||
|
||||
UINT Adapter;
|
||||
IDirect3DDevice9 *D3DDevice;
|
||||
IDirect3DTexture9 *FBTexture;
|
||||
IDirect3DTexture9 *TempRenderTexture, *RenderTexture[2];
|
||||
IDirect3DTexture9 *PaletteTexture;
|
||||
IDirect3DTexture9 *GammaTexture;
|
||||
IDirect3DTexture9 *ScreenshotTexture;
|
||||
IDirect3DSurface9 *ScreenshotSurface;
|
||||
IDirect3DSurface9 *FrontCopySurface;
|
||||
|
||||
IDirect3DVertexBuffer9 *VertexBuffer;
|
||||
FBVERTEX *VertexData;
|
||||
IDirect3DIndexBuffer9 *IndexBuffer;
|
||||
uint16_t *IndexData;
|
||||
|
||||
// This stuff is still needed for the Wiper (which will be refactored later)
|
||||
BufferedTris *QuadExtra;
|
||||
int VertexPos;
|
||||
int IndexPos;
|
||||
int QuadBatchPos;
|
||||
enum { BATCH_None, BATCH_Quads, BATCH_Lines } BatchType;
|
||||
|
||||
unsigned int NumVertices = 0;
|
||||
unsigned int NumIndices = 0;
|
||||
|
||||
IDirect3DPixelShader9 *Shaders[NUM_SHADERS];
|
||||
IDirect3DPixelShader9 *GammaShader;
|
||||
|
||||
IDirect3DSurface9 *BlockSurface[2];
|
||||
IDirect3DSurface9 *OldRenderTarget;
|
||||
IDirect3DTexture9 *InitialWipeScreen, *FinalWipeScreen;
|
||||
|
||||
D3DFB() {}
|
||||
|
||||
class Wiper
|
||||
{
|
||||
public:
|
||||
virtual ~Wiper();
|
||||
virtual bool Run(int ticks, D3DFB *fb) = 0;
|
||||
|
||||
void DrawScreen(D3DFB *fb, IDirect3DTexture9 *tex,
|
||||
D3DBLENDOP blendop=D3DBLENDOP(0), D3DCOLOR color0=0, D3DCOLOR color1=0xFFFFFFF);
|
||||
};
|
||||
|
||||
class Wiper_Melt; friend class Wiper_Melt;
|
||||
class Wiper_Burn; friend class Wiper_Burn;
|
||||
class Wiper_Crossfade; friend class Wiper_Crossfade;
|
||||
|
||||
Wiper *ScreenWipe;
|
||||
};
|
||||
|
||||
// Flags for a buffered quad
|
||||
enum
|
||||
{
|
||||
BQF_GamePalette = 1,
|
||||
BQF_CustomPalette = 7,
|
||||
BQF_Paletted = 7,
|
||||
BQF_Bilinear = 8,
|
||||
BQF_WrapUV = 16,
|
||||
BQF_InvertSource = 32,
|
||||
BQF_DisableAlphaTest= 64,
|
||||
BQF_Desaturated = 128,
|
||||
};
|
||||
|
||||
// Shaders for a buffered quad
|
||||
enum
|
||||
{
|
||||
BQS_PalTex,
|
||||
BQS_Plain,
|
||||
BQS_RedToAlpha,
|
||||
BQS_ColorOnly,
|
||||
BQS_SpecialColormap,
|
||||
BQS_InGameColormap,
|
||||
};
|
||||
|
||||
#if _DEBUG && 0
|
||||
#define STARTLOG
|
||||
#define STOPLOG
|
||||
#define LOG(x) { OutputDebugString(x); }
|
||||
#define LOG1(x,y) { char poo[1024]; mysnprintf(poo, countof(poo), x, y); OutputDebugString(poo); }
|
||||
#define LOG2(x,y,z) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z); OutputDebugString(poo); }
|
||||
#define LOG3(x,y,z,zz) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z, zz); OutputDebugString(poo); }
|
||||
#define LOG4(x,y,z,a,b) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z, a, b); OutputDebugString(poo); }
|
||||
#define LOG5(x,y,z,a,b,c) { char poo[1024]; mysnprintf(poo, countof(poo), x, y, z, a, b, c); OutputDebugString(poo); }
|
||||
#else
|
||||
#define STARTLOG
|
||||
#define STOPLOG
|
||||
#define LOG(x)
|
||||
#define LOG1(x,y)
|
||||
#define LOG2(x,y,z)
|
||||
#define LOG3(x,y,z,zz)
|
||||
#define LOG4(x,y,z,a,b)
|
||||
#define LOG5(x,y,z,a,b,c)
|
||||
#endif
|
|
@ -68,11 +68,9 @@
|
|||
#include "m_argv.h"
|
||||
#include "r_defs.h"
|
||||
#include "v_text.h"
|
||||
#include "swrenderer/r_swrenderer.h"
|
||||
#include "version.h"
|
||||
|
||||
#include "win32iface.h"
|
||||
#include "win32swiface.h"
|
||||
|
||||
#include "optwin32.h"
|
||||
|
||||
|
@ -80,488 +78,26 @@
|
|||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
typedef IDirect3D9 *(WINAPI *DIRECT3DCREATE9FUNC)(UINT SDKVersion);
|
||||
typedef HRESULT (WINAPI *DIRECTDRAWCREATEFUNC)(GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter);
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
void DoBlending (const PalEntry *from, PalEntry *to, int count, int r, int g, int b, int a);
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static void StopFPSLimit();
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
extern HWND Window;
|
||||
extern IVideo *Video;
|
||||
extern BOOL AppActive;
|
||||
extern int SessionState;
|
||||
extern bool FullscreenReset;
|
||||
extern bool VidResizing;
|
||||
|
||||
EXTERN_CVAR (Bool, fullscreen)
|
||||
EXTERN_CVAR (Float, Gamma)
|
||||
EXTERN_CVAR (Bool, cl_capfps)
|
||||
EXTERN_CVAR(Int, vid_maxfps)
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
static HMODULE D3D9_dll;
|
||||
static UINT FPSLimitTimer;
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
IDirect3D9 *D3D;
|
||||
IDirect3DDevice9 *D3Device;
|
||||
HANDLE FPSLimitEvent;
|
||||
|
||||
CVAR (Int, vid_adapter, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
||||
#if VID_FILE_DEBUG
|
||||
FILE *dbg;
|
||||
#endif
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
Win32Video::Win32Video (int parm)
|
||||
: m_Modes (NULL),
|
||||
m_IsFullscreen (false),
|
||||
m_Adapter (D3DADAPTER_DEFAULT)
|
||||
{
|
||||
I_SetWndProc();
|
||||
InitD3D9();
|
||||
}
|
||||
|
||||
Win32Video::~Win32Video ()
|
||||
{
|
||||
FreeModes ();
|
||||
|
||||
if (D3D != NULL)
|
||||
{
|
||||
D3D->Release();
|
||||
D3D = NULL;
|
||||
}
|
||||
|
||||
STOPLOG;
|
||||
}
|
||||
|
||||
bool Win32Video::InitD3D9 ()
|
||||
{
|
||||
DIRECT3DCREATE9FUNC direct3d_create_9;
|
||||
|
||||
// Load the Direct3D 9 library.
|
||||
if ((D3D9_dll = LoadLibraryA ("d3d9.dll")) == NULL)
|
||||
{
|
||||
Printf("Unable to load d3d9.dll! Falling back to DirectDraw...\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Obtain an IDirect3D interface.
|
||||
if ((direct3d_create_9 = (DIRECT3DCREATE9FUNC)GetProcAddress (D3D9_dll, "Direct3DCreate9")) == NULL)
|
||||
{
|
||||
goto closelib;
|
||||
}
|
||||
if ((D3D = direct3d_create_9 (D3D_SDK_VERSION)) == NULL)
|
||||
{
|
||||
goto closelib;
|
||||
}
|
||||
|
||||
// Select adapter.
|
||||
m_Adapter = (vid_adapter < 1 || (UINT)vid_adapter > D3D->GetAdapterCount())
|
||||
? D3DADAPTER_DEFAULT : (UINT)vid_adapter - 1u;
|
||||
|
||||
// Check that we have at least PS 1.4 available.
|
||||
D3DCAPS9 devcaps;
|
||||
if (FAILED(D3D->GetDeviceCaps (m_Adapter, D3DDEVTYPE_HAL, &devcaps)))
|
||||
{
|
||||
goto d3drelease;
|
||||
}
|
||||
if ((devcaps.PixelShaderVersion & 0xFFFF) < 0x104)
|
||||
{
|
||||
goto d3drelease;
|
||||
}
|
||||
if (!(devcaps.Caps2 & D3DCAPS2_DYNAMICTEXTURES))
|
||||
{
|
||||
goto d3drelease;
|
||||
}
|
||||
|
||||
// Enumerate available display modes.
|
||||
FreeModes ();
|
||||
AddD3DModes (m_Adapter);
|
||||
AddD3DModes (m_Adapter);
|
||||
if (Args->CheckParm ("-2"))
|
||||
{ // Force all modes to be pixel-doubled.
|
||||
ScaleModes (1);
|
||||
}
|
||||
else if (Args->CheckParm ("-4"))
|
||||
{ // Force all modes to be pixel-quadrupled.
|
||||
ScaleModes (2);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLowResModes ();
|
||||
}
|
||||
AddLetterboxModes ();
|
||||
if (m_Modes == NULL)
|
||||
{ // Too bad. We didn't find any modes for D3D9. We probably won't find any
|
||||
// for DDraw either...
|
||||
goto d3drelease;
|
||||
}
|
||||
return true;
|
||||
|
||||
d3drelease:
|
||||
D3D->Release();
|
||||
D3D = NULL;
|
||||
closelib:
|
||||
FreeLibrary (D3D9_dll);
|
||||
Printf("Direct3D acceleration failed! Falling back to DirectDraw...\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI EnumDDModesCB(LPDDSURFACEDESC desc, void *data)
|
||||
{
|
||||
((Win32Video *)data)->AddMode(desc->dwWidth, desc->dwHeight, 8, desc->dwHeight, 0);
|
||||
return DDENUMRET_OK;
|
||||
}
|
||||
|
||||
|
||||
// Returns true if fullscreen, false otherwise
|
||||
bool Win32Video::GoFullscreen (bool yes)
|
||||
{
|
||||
// FIXME: Do this right for D3D.
|
||||
return yes;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Win32Video :: DumpAdapters
|
||||
//
|
||||
// Dumps the list of display adapters to the console. Only meaningful for
|
||||
// Direct3D.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void Win32Video::DumpAdapters()
|
||||
{
|
||||
using OptWin32::GetMonitorInfoA;
|
||||
|
||||
if (D3D == NULL)
|
||||
{
|
||||
Printf("Multi-monitor support requires Direct3D.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
UINT num_adapters = D3D->GetAdapterCount();
|
||||
|
||||
for (UINT i = 0; i < num_adapters; ++i)
|
||||
{
|
||||
D3DADAPTER_IDENTIFIER9 ai;
|
||||
char moreinfo[64] = "";
|
||||
|
||||
if (FAILED(D3D->GetAdapterIdentifier(i, 0, &ai)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Strip trailing whitespace from adapter description.
|
||||
for (char *p = ai.Description + strlen(ai.Description) - 1;
|
||||
p >= ai.Description && isspace(*p);
|
||||
--p)
|
||||
{
|
||||
*p = '\0';
|
||||
}
|
||||
HMONITOR hm = D3D->GetAdapterMonitor(i);
|
||||
MONITORINFOEX mi;
|
||||
mi.cbSize = sizeof(mi);
|
||||
|
||||
assert(GetMonitorInfo); // Missing in NT4, but so is D3D
|
||||
if (GetMonitorInfo(hm, &mi))
|
||||
{
|
||||
mysnprintf(moreinfo, countof(moreinfo), " [%ldx%ld @ (%ld,%ld)]%s",
|
||||
mi.rcMonitor.right - mi.rcMonitor.left,
|
||||
mi.rcMonitor.bottom - mi.rcMonitor.top,
|
||||
mi.rcMonitor.left, mi.rcMonitor.top,
|
||||
mi.dwFlags & MONITORINFOF_PRIMARY ? " (Primary)" : "");
|
||||
}
|
||||
Printf("%s%u. %s%s\n",
|
||||
i == m_Adapter ? TEXTCOLOR_BOLD : "",
|
||||
i + 1, ai.Description, moreinfo);
|
||||
}
|
||||
}
|
||||
|
||||
// Mode enumeration --------------------------------------------------------
|
||||
|
||||
void Win32Video::AddD3DModes (unsigned adapter)
|
||||
{
|
||||
for (D3DFORMAT format : { D3DFMT_X8R8G8B8, D3DFMT_R5G6B5})
|
||||
{
|
||||
UINT modecount, i;
|
||||
D3DDISPLAYMODE mode;
|
||||
|
||||
modecount = D3D->GetAdapterModeCount(adapter, format);
|
||||
for (i = 0; i < modecount; ++i)
|
||||
{
|
||||
if (D3D_OK == D3D->EnumAdapterModes(adapter, format, i, &mode))
|
||||
{
|
||||
AddMode(mode.Width, mode.Height, 8, mode.Height, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Win32Video :: AddLowResModes
|
||||
//
|
||||
// Recent NVidia drivers no longer support resolutions below 640x480, even
|
||||
// if you try to add them as a custom resolution. With D3DFB, pixel doubling
|
||||
// is quite easy to do and hardware-accelerated. If you have 1280x800, then
|
||||
// you can have 320x200, but don't be surprised if it shows up as widescreen
|
||||
// on a widescreen monitor, since that's what it is.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void Win32Video::AddLowResModes()
|
||||
{
|
||||
ModeInfo *mode, *nextmode;
|
||||
|
||||
for (mode = m_Modes; mode != NULL; mode = nextmode)
|
||||
{
|
||||
nextmode = mode->next;
|
||||
if (mode->realheight == mode->height &&
|
||||
mode->doubling == 0 &&
|
||||
mode->height >= 200*2 &&
|
||||
mode->height <= 480*2 &&
|
||||
mode->width >= 320*2 &&
|
||||
mode->width <= 640*2)
|
||||
{
|
||||
AddMode (mode->width / 2, mode->height / 2, mode->bits, mode->height / 2, 1);
|
||||
}
|
||||
}
|
||||
for (mode = m_Modes; mode != NULL; mode = nextmode)
|
||||
{
|
||||
nextmode = mode->next;
|
||||
if (mode->realheight == mode->height &&
|
||||
mode->doubling == 0 &&
|
||||
mode->height >= 200*4 &&
|
||||
mode->height <= 480*4 &&
|
||||
mode->width >= 320*4 &&
|
||||
mode->width <= 640*4)
|
||||
{
|
||||
AddMode (mode->width / 4, mode->height / 4, mode->bits, mode->height / 4, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add 16:9 and 16:10 resolutions you can use in a window or letterboxed
|
||||
void Win32Video::AddLetterboxModes ()
|
||||
{
|
||||
ModeInfo *mode, *nextmode;
|
||||
|
||||
for (mode = m_Modes; mode != NULL; mode = nextmode)
|
||||
{
|
||||
nextmode = mode->next;
|
||||
if (mode->realheight == mode->height && mode->height * 4/3 == mode->width)
|
||||
{
|
||||
if (mode->width >= 360)
|
||||
{
|
||||
AddMode (mode->width, mode->width * 9/16, mode->bits, mode->height, mode->doubling);
|
||||
}
|
||||
if (mode->width > 640)
|
||||
{
|
||||
AddMode (mode->width, mode->width * 10/16, mode->bits, mode->height, mode->doubling);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Win32Video::AddMode (int x, int y, int bits, int y2, int doubling)
|
||||
{
|
||||
// Reject modes that do not meet certain criteria.
|
||||
if ((x & 1) != 0 ||
|
||||
y > MAXHEIGHT ||
|
||||
x > MAXWIDTH ||
|
||||
y < 200 ||
|
||||
x < 320)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ModeInfo **probep = &m_Modes;
|
||||
ModeInfo *probe = m_Modes;
|
||||
|
||||
// This mode may have been already added to the list because it is
|
||||
// enumerated multiple times at different refresh rates. If it's
|
||||
// not present, add it to the right spot in the list; otherwise, do nothing.
|
||||
// Modes are sorted first by width, then by height, then by depth. In each
|
||||
// case the order is ascending.
|
||||
for (; probe != 0; probep = &probe->next, probe = probe->next)
|
||||
{
|
||||
if (probe->width > x) break;
|
||||
if (probe->width < x) continue;
|
||||
// Width is equal
|
||||
if (probe->height > y) break;
|
||||
if (probe->height < y) continue;
|
||||
// Height is equal
|
||||
if (probe->bits > bits) break;
|
||||
if (probe->bits < bits) continue;
|
||||
// Bits is equal
|
||||
return;
|
||||
}
|
||||
|
||||
*probep = new ModeInfo (x, y, bits, y2, doubling);
|
||||
(*probep)->next = probe;
|
||||
}
|
||||
|
||||
void Win32Video::FreeModes ()
|
||||
{
|
||||
ModeInfo *mode = m_Modes;
|
||||
|
||||
while (mode)
|
||||
{
|
||||
ModeInfo *tempmode = mode;
|
||||
mode = mode->next;
|
||||
delete tempmode;
|
||||
}
|
||||
m_Modes = NULL;
|
||||
}
|
||||
|
||||
// For every mode, set its scaling factor. Modes that end up with too
|
||||
// small a display area are discarded.
|
||||
|
||||
void Win32Video::ScaleModes (int doubling)
|
||||
{
|
||||
ModeInfo *mode, **prev;
|
||||
|
||||
prev = &m_Modes;
|
||||
mode = m_Modes;
|
||||
|
||||
while (mode != NULL)
|
||||
{
|
||||
assert(mode->doubling == 0);
|
||||
mode->width >>= doubling;
|
||||
mode->height >>= doubling;
|
||||
mode->realheight >>= doubling;
|
||||
mode->doubling = doubling;
|
||||
if ((mode->width & 7) != 0 || mode->width < 320 || mode->height < 200)
|
||||
{ // Mode became too small. Delete it.
|
||||
*prev = mode->next;
|
||||
delete mode;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = &mode->next;
|
||||
}
|
||||
mode = *prev;
|
||||
}
|
||||
}
|
||||
|
||||
void Win32Video::StartModeIterator (int bits, bool fs)
|
||||
{
|
||||
m_IteratorMode = m_Modes;
|
||||
m_IteratorBits = bits;
|
||||
m_IteratorFS = fs;
|
||||
}
|
||||
|
||||
bool Win32Video::NextMode (int *width, int *height, bool *letterbox)
|
||||
{
|
||||
if (m_IteratorMode)
|
||||
{
|
||||
while (m_IteratorMode && m_IteratorMode->bits != m_IteratorBits)
|
||||
{
|
||||
m_IteratorMode = m_IteratorMode->next;
|
||||
}
|
||||
|
||||
if (m_IteratorMode)
|
||||
{
|
||||
*width = m_IteratorMode->width;
|
||||
*height = m_IteratorMode->height;
|
||||
if (letterbox != NULL) *letterbox = m_IteratorMode->realheight != m_IteratorMode->height;
|
||||
m_IteratorMode = m_IteratorMode->next;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DFrameBuffer *Win32Video::CreateFrameBuffer (int width, int height, bool bgra, bool fullscreen, DFrameBuffer *old)
|
||||
{
|
||||
static int retry = 0;
|
||||
static int owidth, oheight;
|
||||
|
||||
BaseWinFB *fb;
|
||||
PalEntry flashColor;
|
||||
int flashAmount;
|
||||
|
||||
if (fullscreen)
|
||||
{
|
||||
I_ClosestResolution(&width, &height, D3D ? 32 : 8);
|
||||
}
|
||||
|
||||
LOG4 ("CreateFB %d %d %d %p\n", width, height, fullscreen, old);
|
||||
|
||||
if (old != NULL)
|
||||
{ // Reuse the old framebuffer if its attributes are the same
|
||||
BaseWinFB *fb = static_cast<BaseWinFB *> (old);
|
||||
if (fb->Width == width &&
|
||||
fb->Height == height &&
|
||||
fb->Windowed == !fullscreen &&
|
||||
fb->Bgra == bgra)
|
||||
{
|
||||
return old;
|
||||
}
|
||||
old->GetFlash (flashColor, flashAmount);
|
||||
if (old == screen) screen = nullptr;
|
||||
delete old;
|
||||
}
|
||||
else
|
||||
{
|
||||
flashColor = 0;
|
||||
flashAmount = 0;
|
||||
}
|
||||
|
||||
if (D3D != NULL)
|
||||
{
|
||||
fb = new D3DFB (m_Adapter, width, height, bgra, fullscreen);
|
||||
}
|
||||
else
|
||||
{
|
||||
I_FatalError("Unable to create framebuffer. Direct3D not found");
|
||||
}
|
||||
|
||||
LOG1 ("New fb created @ %p\n", fb);
|
||||
|
||||
fb->SetFlash (flashColor, flashAmount);
|
||||
return fb;
|
||||
}
|
||||
|
||||
void Win32Video::SetWindowedScale (float scale)
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// BaseWinFB :: ScaleCoordsFromWindow
|
||||
//
|
||||
// Given coordinates in window space, return coordinates in what the game
|
||||
// thinks screen space is.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void BaseWinFB::ScaleCoordsFromWindow(int16_t &x, int16_t &y)
|
||||
{
|
||||
RECT rect;
|
||||
|
||||
int TrueHeight = GetTrueHeight();
|
||||
if (GetClientRect(Window, &rect))
|
||||
{
|
||||
x = int16_t(x * Width / (rect.right - rect.left));
|
||||
y = int16_t(y * TrueHeight / (rect.bottom - rect.top));
|
||||
}
|
||||
// Subtract letterboxing borders
|
||||
y -= (TrueHeight - Height) / 2;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -641,4 +177,28 @@ void I_FPSLimit()
|
|||
{
|
||||
WaitForSingleObject(FPSLimitEvent, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// BaseWinFB :: ScaleCoordsFromWindow
|
||||
//
|
||||
// Given coordinates in window space, return coordinates in what the game
|
||||
// thinks screen space is.
|
||||
//
|
||||
//==========================================================================
|
||||
extern HWND Window;
|
||||
|
||||
void BaseWinFB::ScaleCoordsFromWindow(int16_t &x, int16_t &y)
|
||||
{
|
||||
RECT rect;
|
||||
|
||||
int TrueHeight = GetTrueHeight();
|
||||
if (GetClientRect(Window, &rect))
|
||||
{
|
||||
x = int16_t(x * Width / (rect.right - rect.left));
|
||||
y = int16_t(y * TrueHeight / (rect.bottom - rect.top));
|
||||
}
|
||||
// Subtract letterboxing borders
|
||||
y -= (TrueHeight - Height) / 2;
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
cd ..\sm20
|
||||
call build.bat
|
||||
|
||||
cd ..\sm30
|
||||
call build.bat
|
||||
|
||||
cd ..
|
|
@ -1,99 +0,0 @@
|
|||
sampler2D Image : register(s0);
|
||||
sampler1D Palette : register(s1);
|
||||
|
||||
float4 Desaturation : register(c1); // { Desat, 1 - Desat }
|
||||
float4 PaletteMod : register(c2);
|
||||
float4 Color1 : register(c3);
|
||||
float4 Color2 : register(c4);
|
||||
float4 Weights : register(c6); // RGB->Gray weighting { 77/256.0, 143/256.0, 37/256.0, 1 }
|
||||
float4 Gamma : register(c7);
|
||||
|
||||
float4 TextureLookup(float2 tex_coord)
|
||||
{
|
||||
#if PALTEX
|
||||
float index = tex2D(Image, tex_coord).x;
|
||||
index = index * PaletteMod.x + PaletteMod.y;
|
||||
return tex1D(Palette, index);
|
||||
#else
|
||||
return tex2D(Image, tex_coord);
|
||||
#endif
|
||||
}
|
||||
|
||||
float Grayscale(float4 rgb)
|
||||
{
|
||||
return dot(rgb.rgb, Weights.rgb);
|
||||
}
|
||||
|
||||
float4 SampleTexture(float2 tex_coord)
|
||||
{
|
||||
float4 texel = TextureLookup(tex_coord);
|
||||
#if INVERT
|
||||
texel.rgb = Weights.www - texel.xyz;
|
||||
#endif
|
||||
#if OPAQUE
|
||||
texel.a = 1.0;
|
||||
#endif
|
||||
#if STENCIL
|
||||
texel.rgb = Weights.www;
|
||||
#endif
|
||||
#if ALPHATEX
|
||||
texel.a *= Grayscale(texel);
|
||||
texel.rgb = Weights.www;
|
||||
#endif
|
||||
#if DESAT
|
||||
float3 intensity;
|
||||
intensity.rgb = Grayscale(texel) * Desaturation.x;
|
||||
texel.rgb = intensity.rgb + texel.rgb * Desaturation.y;
|
||||
#endif
|
||||
return texel;
|
||||
}
|
||||
|
||||
// Normal color calculation for most drawing modes.
|
||||
|
||||
float4 NormalColor(float2 tex_coord : TEXCOORD0, float4 VertexColor : COLOR0) : COLOR
|
||||
{
|
||||
return Color1 + SampleTexture(tex_coord) * VertexColor;
|
||||
}
|
||||
|
||||
|
||||
// Just return the value of c0.
|
||||
|
||||
float4 VertexColor(float4 color : COLOR0) : COLOR
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
// Emulate one of the special colormaps. (Invulnerability, gold, etc.)
|
||||
|
||||
float4 SpecialColormap(float2 tex_coord : TEXCOORD0) : COLOR
|
||||
{
|
||||
float4 color = SampleTexture(tex_coord);
|
||||
float4 range = Color2 - Color1;
|
||||
// We can't store values greater than 1.0 in a color register, so we multiply
|
||||
// the final result by 2 and expect the caller to divide the start and end by 2.
|
||||
color.rgb = 2 * (Color1 + Grayscale(color) * range).rgb;
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
// Windowed gamma correction.
|
||||
|
||||
float4 GammaCorrection(float2 tex_coord : TEXCOORD0) : COLOR
|
||||
{
|
||||
float4 color = tex2D(Image, tex_coord);
|
||||
color.rgb = pow(color.rgb, Gamma.rgb);
|
||||
return color;
|
||||
}
|
||||
|
||||
// The burn wipe effect.
|
||||
|
||||
sampler2D NewScreen : register(s0);
|
||||
sampler2D Burn : register(s1);
|
||||
|
||||
float4 BurnWipe(float2 coord[2] : TEXCOORD0) : COLOR
|
||||
{
|
||||
float4 color = tex2D(NewScreen, coord[0]);
|
||||
float4 alpha = tex2D(Burn, coord[1]);
|
||||
color.a = alpha.r * 2;
|
||||
return color;
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,29 +0,0 @@
|
|||
fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoNormalColor.pso
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoNormalColorPal.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=1 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorInv.pso
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=1 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalInv.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorOpaq.pso
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalOpaq.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=1 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorInvOpaq.pso
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=1 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalInvOpaq.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=1 -DALPHATEX=0 -DDESAT=0 /FoStencil.pso
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=1 -DALPHATEX=0 -DDESAT=0 /FoPalStencil.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=1 -DDESAT=0 /FoAlphaTex.pso
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=1 -DDESAT=0 /FoPalAlphaTex.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorD.pso
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalD.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /EVertexColor /FoVertexColor.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /ESpecialColormap -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoSpecialColormap.pso
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /ESpecialColormap -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoSpecialColormapPal.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /EBurnWipe /FoBurnWipe.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_2_0 /O3 /EGammaCorrection /FoGammaCorrection.pso
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,29 +0,0 @@
|
|||
fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoNormalColor.pso
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoNormalColorPal.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=1 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorInv.pso
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=1 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalInv.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorOpaq.pso
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalOpaq.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=1 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorInvOpaq.pso
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=1 -DOPAQUE=1 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalInvOpaq.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=1 -DALPHATEX=0 -DDESAT=0 /FoStencil.pso
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=1 -DALPHATEX=0 -DDESAT=0 /FoPalStencil.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=1 -DDESAT=0 /FoAlphaTex.pso
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=1 -DDESAT=0 /FoPalAlphaTex.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorD.pso
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /ENormalColor -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=1 /FoNormalColorPalD.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /EVertexColor /FoVertexColor.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /ESpecialColormap -DPALTEX=0 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoSpecialColormap.pso
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /ESpecialColormap -DPALTEX=1 -DINVERT=0 -DOPAQUE=0 -DSTENCIL=0 -DALPHATEX=0 -DDESAT=0 /FoSpecialColormapPal.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /EBurnWipe /FoBurnWipe.pso
|
||||
|
||||
fxc ..\shaders.ps /Tps_3_0 /O3 /EGammaCorrection /FoGammaCorrection.pso
|
|
@ -1,148 +0,0 @@
|
|||
|
||||
precision mediump float;
|
||||
|
||||
in vec4 PixelColor0;
|
||||
in vec4 PixelColor1;
|
||||
in vec4 PixelTexCoord0;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D Image;
|
||||
uniform sampler2D Palette;
|
||||
uniform sampler2D NewScreen;
|
||||
uniform sampler2D Burn;
|
||||
|
||||
uniform vec4 Desaturation; // { Desat, 1 - Desat }
|
||||
uniform vec4 PaletteMod;
|
||||
uniform vec4 Weights; // RGB->Gray weighting { 77/256.0, 143/256.0, 37/256.0, 1 }
|
||||
uniform vec4 Gamma;
|
||||
|
||||
vec4 TextureLookup(vec2 tex_coord)
|
||||
{
|
||||
#if defined(PALTEX)
|
||||
float index = texture(Image, tex_coord).x;
|
||||
index = index * PaletteMod.x + PaletteMod.y;
|
||||
return texture(Palette, vec2(index, 0.5));
|
||||
#else
|
||||
return texture(Image, tex_coord);
|
||||
#endif
|
||||
}
|
||||
|
||||
vec4 Invert(vec4 rgb)
|
||||
{
|
||||
#if defined(INVERT)
|
||||
rgb.rgb = Weights.www - rgb.xyz;
|
||||
#endif
|
||||
return rgb;
|
||||
}
|
||||
|
||||
float Grayscale(vec4 rgb)
|
||||
{
|
||||
return dot(rgb.rgb, Weights.rgb);
|
||||
}
|
||||
|
||||
vec4 SampleTexture(vec2 tex_coord)
|
||||
{
|
||||
return Invert(TextureLookup(tex_coord));
|
||||
}
|
||||
|
||||
// Normal color calculation for most drawing modes.
|
||||
|
||||
vec4 NormalColor(vec2 tex_coord, vec4 Flash, vec4 InvFlash)
|
||||
{
|
||||
return Flash + SampleTexture(tex_coord) * InvFlash;
|
||||
}
|
||||
|
||||
// Copy the red channel to the alpha channel. Pays no attention to palettes.
|
||||
|
||||
vec4 RedToAlpha(vec2 tex_coord, vec4 Flash, vec4 InvFlash)
|
||||
{
|
||||
vec4 color = Invert(texture(Image, tex_coord));
|
||||
color.a = color.r;
|
||||
return Flash + color * InvFlash;
|
||||
}
|
||||
|
||||
// Just return the value of c0.
|
||||
|
||||
vec4 VertexColor(vec4 color)
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
||||
// Emulate one of the special colormaps. (Invulnerability, gold, etc.)
|
||||
|
||||
vec4 SpecialColormap(vec2 tex_coord, vec4 start, vec4 end)
|
||||
{
|
||||
vec4 color = SampleTexture(tex_coord);
|
||||
vec4 range = end - start;
|
||||
// We can't store values greater than 1.0 in a color register, so we multiply
|
||||
// the final result by 2 and expect the caller to divide the start and end by 2.
|
||||
color.rgb = 2.0 * (start + Grayscale(color) * range).rgb;
|
||||
// Duplicate alpha semantics of NormalColor.
|
||||
color.a = start.a + color.a * end.a;
|
||||
return color;
|
||||
}
|
||||
|
||||
// In-game colormap effect: fade to a particular color and multiply by another, with
|
||||
// optional desaturation of the original color. Desaturation is stored in c1.
|
||||
// Fade level is packed int fade.a. Fade.rgb has been premultiplied by alpha.
|
||||
// Overall alpha is in color.a.
|
||||
vec4 InGameColormap(vec2 tex_coord, vec4 color, vec4 fade)
|
||||
{
|
||||
vec4 rgb = SampleTexture(tex_coord);
|
||||
|
||||
// Desaturate
|
||||
#if defined(DESAT)
|
||||
vec3 intensity;
|
||||
intensity.rgb = vec3(Grayscale(rgb) * Desaturation.x);
|
||||
rgb.rgb = intensity.rgb + rgb.rgb * Desaturation.y;
|
||||
#endif
|
||||
|
||||
// Fade
|
||||
rgb.rgb = rgb.rgb * fade.aaa + fade.rgb;
|
||||
|
||||
// Shade and Alpha
|
||||
rgb = rgb * color;
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
||||
// Windowed gamma correction.
|
||||
|
||||
vec4 GammaCorrection(vec2 tex_coord)
|
||||
{
|
||||
vec4 color = texture(Image, tex_coord);
|
||||
color.rgb = pow(color.rgb, Gamma.rgb);
|
||||
return color;
|
||||
}
|
||||
|
||||
// The burn wipe effect.
|
||||
|
||||
vec4 BurnWipe(vec4 coord)
|
||||
{
|
||||
vec4 color = texture(NewScreen, coord.xy);
|
||||
vec4 alpha = texture(Burn, coord.zw);
|
||||
color.a = alpha.r * 2.0;
|
||||
return color;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
#if defined(ENORMALCOLOR)
|
||||
FragColor = NormalColor(PixelTexCoord0.xy, PixelColor0, PixelColor1);
|
||||
#elif defined(EREDTOALPHA)
|
||||
FragColor = RedToAlpha(PixelTexCoord0.xy, PixelColor0, PixelColor1);
|
||||
#elif defined(EVERTEXCOLOR)
|
||||
FragColor = VertexColor(PixelColor0);
|
||||
#elif defined(ESPECIALCOLORMAP)
|
||||
FragColor = SpecialColormap(PixelTexCoord0.xy, PixelColor0, PixelColor1);
|
||||
#elif defined(EINGAMECOLORMAP)
|
||||
FragColor = InGameColormap(PixelTexCoord0.xy, PixelColor0, PixelColor1);
|
||||
#elif defined(EBURNWIPE)
|
||||
FragColor = BurnWipe(PixelTexCoord0);
|
||||
#elif defined(EGAMMACORRECTION)
|
||||
FragColor = GammaCorrection(PixelTexCoord0.xy);
|
||||
#else
|
||||
#error Entry point define is missing
|
||||
#endif
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
|
||||
in vec4 AttrPosition;
|
||||
in vec4 AttrColor0;
|
||||
in vec4 AttrColor1;
|
||||
in vec4 AttrTexCoord0;
|
||||
|
||||
out vec4 PixelColor0;
|
||||
out vec4 PixelColor1;
|
||||
out vec4 PixelTexCoord0;
|
||||
|
||||
uniform vec4 ScreenSize;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(AttrPosition.xy / ScreenSize.xy * 2.0 - 1.0, 1.0, 1.0);
|
||||
#if defined(EGAMMACORRECTION)
|
||||
gl_Position.y = -gl_Position.y;
|
||||
#endif
|
||||
PixelColor0 = AttrColor0.bgra;
|
||||
PixelColor1 = AttrColor1.bgra;
|
||||
PixelTexCoord0 = AttrTexCoord0;
|
||||
}
|
Loading…
Reference in a new issue