mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-28 06:53:58 +00:00
- implemented the 2D drawer for the hardware renderer. Not tested yet.
This commit is contained in:
parent
25999c1c6a
commit
70b6754299
14 changed files with 232 additions and 26 deletions
|
@ -9,7 +9,9 @@ struct lightlist_t;
|
|||
|
||||
enum EColorManipulation
|
||||
{
|
||||
|
||||
CM_SPECIAL2D = -3, // the special colormaps get passed as color pair from the 2D drawer so they need a different value here.
|
||||
CM_INGAME2D = -3, // ingame lighting mode for automap
|
||||
CM_PLAIN2D = -2, // regular 2D drawing.
|
||||
CM_INVALID=-1,
|
||||
CM_DEFAULT=0, // untranslated
|
||||
CM_FIRSTSPECIALCOLORMAP, // first special fixed colormap
|
||||
|
|
|
@ -138,7 +138,6 @@ void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend
|
|||
}
|
||||
else if (style.Flags & STYLEF_InvertSource)
|
||||
{
|
||||
// The only place where InvertSource is used is for inverted sprites with the infrared powerup.
|
||||
texturemode = TM_INVERSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -432,3 +432,170 @@ unsigned char *FGLRenderer::GetTextureBuffer(FTexture *tex, int &w, int &h)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Vertex buffer for 2D drawer
|
||||
//
|
||||
//===========================================================================
|
||||
#define TDiO ((F2DDrawer::TwoDVertex*)NULL)
|
||||
|
||||
class F2DVertexBuffer : public FVertexBuffer
|
||||
{
|
||||
uint32_t ibo_id;
|
||||
|
||||
public:
|
||||
|
||||
F2DVertexBuffer()
|
||||
{
|
||||
glGenBuffers(1, &ibo_id);
|
||||
}
|
||||
~F2DVertexBuffer()
|
||||
{
|
||||
if (ibo_id != 0)
|
||||
{
|
||||
glDeleteBuffers(1, &ibo_id);
|
||||
}
|
||||
}
|
||||
void UploadData(F2DDrawer::TwoDVertex *vertices, int vertcount, int *indices, int indexcount)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertcount * sizeof(vertices[0]), vertices, GL_STREAM_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexcount * sizeof(indices[0]), indices, GL_STREAM_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void BindVBO() override
|
||||
{
|
||||
// set up the vertex buffer for drawing the 2D elements.
|
||||
glGenBuffers(1, &vbo_id);
|
||||
glGenBuffers(1, &ibo_id);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FSimpleVertex), &TDiO->x);
|
||||
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FSimpleVertex), &TDiO->u);
|
||||
glVertexAttribPointer(VATTR_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(FSimpleVertex), &TDiO->color0);
|
||||
glEnableVertexAttribArray(VATTR_VERTEX);
|
||||
glEnableVertexAttribArray(VATTR_TEXCOORD);
|
||||
glEnableVertexAttribArray(VATTR_COLOR);
|
||||
glDisableVertexAttribArray(VATTR_VERTEX2);
|
||||
glDisableVertexAttribArray(VATTR_NORMAL);
|
||||
}
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Draws the 2D stuff. This is the version for OpenGL 3 and later.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FGLRenderer::Draw2D(F2DDrawer *drawer)
|
||||
{
|
||||
F2DDrawer::EDrawType lasttype = F2DDrawer::DrawTypeTriangles;
|
||||
auto &vertices = drawer->mVertices;
|
||||
auto &indices = drawer->mIndices;
|
||||
auto &commands = drawer->mData;
|
||||
|
||||
if (commands.Size() == 0) return;
|
||||
|
||||
for (auto &v : vertices)
|
||||
{
|
||||
// Change from BGRA to RGBA
|
||||
std::swap(v.color0.r, v.color0.b);
|
||||
}
|
||||
auto vb = new F2DVertexBuffer;
|
||||
vb->UploadData(&vertices[0], vertices.Size(), &indices[0], indices.Size());
|
||||
gl_RenderState.SetVertexBuffer(vb);
|
||||
|
||||
|
||||
for(auto &cmd : commands)
|
||||
{
|
||||
gl_RenderState.ResetColor(); // this is needed to reset the desaturation.
|
||||
int tm, sb, db, be;
|
||||
// The texture mode being returned here cannot be used, because the higher level code
|
||||
// already manipulated the data so that some cases will not be handled correctly.
|
||||
// Since we already get a proper mode from the calling code this doesn't really matter.
|
||||
gl_GetRenderStyle(cmd.mRenderStyle, false, false, &tm, &sb, &db, &be);
|
||||
gl_RenderState.BlendEquation(be);
|
||||
gl_RenderState.BlendFunc(sb, db);
|
||||
|
||||
// Rather than adding remapping code, let's enforce that the constants here are equal.
|
||||
static_assert(F2DDrawer::DTM_Normal == TM_MODULATE, "DTM_Normal != TM_MODULATE");
|
||||
static_assert(F2DDrawer::DTM_Opaque == TM_OPAQUE, "DTM_Opaque != TM_OPAQUE");
|
||||
static_assert(F2DDrawer::DTM_Invert == TM_INVERSE, "DTM_Invert != TM_INVERSE");
|
||||
static_assert(F2DDrawer::DTM_InvertOpaque == TM_INVERTOPAQUE, "DTM_InvertOpaque != TM_INVERTOPAQUE");
|
||||
static_assert(F2DDrawer::DTM_Stencil == TM_MASK, "DTM_Stencil != TM_MASK");
|
||||
static_assert(F2DDrawer::DTM_AlphaTexture == TM_REDTOALPHA, "DTM_AlphaTexture != TM_REDTOALPHA");
|
||||
gl_RenderState.SetTextureMode(cmd.mDrawMode);
|
||||
if (cmd.mFlags & F2DDrawer::DTF_Scissor)
|
||||
{
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
|
||||
glScissor(
|
||||
GLRenderer->ScreenToWindowX(cmd.mScissor[0]),
|
||||
GLRenderer->ScreenToWindowX(cmd.mScissor[1]),
|
||||
GLRenderer->ScreenToWindowX(cmd.mScissor[2] - cmd.mScissor[0]),
|
||||
GLRenderer->ScreenToWindowX(cmd.mScissor[3] - cmd.mScissor[1]));
|
||||
}
|
||||
else glDisable(GL_SCISSOR_TEST);
|
||||
gl_RenderState.SetObjectColor(cmd.mColor1);
|
||||
gl_RenderState.SetObjectColor2(cmd.mColor2);
|
||||
|
||||
if (cmd.mFlags & F2DDrawer::DTF_IngameLighting)
|
||||
{
|
||||
gl_RenderState.SetFixedColormap(CM_INGAME2D);
|
||||
}
|
||||
else if (cmd.mFlags & F2DDrawer::DTF_SpecialColormap)
|
||||
{
|
||||
gl_RenderState.SetFixedColormap(CM_SPECIAL2D);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.SetFixedColormap(CM_PLAIN2D);
|
||||
}
|
||||
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
|
||||
switch (cmd.mType)
|
||||
{
|
||||
case F2DDrawer::DrawTypeTriangles:
|
||||
if (cmd.mTexture != nullptr)
|
||||
{
|
||||
auto mat = FMaterial::ValidateTexture(cmd.mTexture, false);
|
||||
if (mat == nullptr) continue;
|
||||
int gltrans = GLTranslationPalette::GetInternalTranslation(cmd.mTranslation);
|
||||
gl_RenderState.SetMaterial(mat, cmd.mFlags & F2DDrawer::DTF_Wrap ? CLAMP_NONE : CLAMP_XY_NOMIP, gltrans, -1, false);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.EnableTexture(false);
|
||||
}
|
||||
gl_RenderState.Apply();
|
||||
glDrawElements(GL_TRIANGLES, cmd.mIndexCount, GL_UNSIGNED_INT, (const void *)(cmd.mIndexIndex * sizeof(unsigned int)));
|
||||
break;
|
||||
|
||||
case F2DDrawer::DrawTypeLines:
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_LINES, cmd.mVertIndex, cmd.mVertCount);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
break;
|
||||
|
||||
case F2DDrawer::DrawTypePoints:
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_POINTS, cmd.mVertIndex, cmd.mVertCount);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
gl_RenderState.SetVertexBuffer(nullptr);
|
||||
delete vb;
|
||||
}
|
|
@ -190,6 +190,7 @@ public:
|
|||
void DrawPresentTexture(const GL_IRECT &box, bool applyGamma);
|
||||
void Flush();
|
||||
void GetSpecialTextures();
|
||||
void Draw2D(F2DDrawer *data);
|
||||
|
||||
|
||||
bool StartOffscreen();
|
||||
|
|
|
@ -233,6 +233,27 @@ bool FRenderState::ApplyShader()
|
|||
{
|
||||
activeShader->muFixedColormap.Set(0);
|
||||
}
|
||||
else if (mColormapState == CM_PLAIN2D)
|
||||
{
|
||||
activeShader->muFixedColormap.Set(4);
|
||||
}
|
||||
else if (mColormapState == CM_INGAME2D)
|
||||
{
|
||||
activeShader->muFixedColormap.Set(5);
|
||||
}
|
||||
else if (mColormapState == CM_SPECIAL2D)
|
||||
{
|
||||
activeShader->muFixedColormap.Set(2);
|
||||
activeShader->muFixedColormap.Set(1);
|
||||
float startr = mObjectColor.r / 255;
|
||||
float startg = mObjectColor.g / 255;
|
||||
float startb = mObjectColor.b / 255;
|
||||
float ranger = mObjectColor2.r / 255 - startr;
|
||||
float rangeg = mObjectColor2.g / 255 - startg;
|
||||
float rangeb = mObjectColor2.b / 255 - startb;
|
||||
activeShader->muColormapStart.Set(startr, startg, startb, 0.f);
|
||||
activeShader->muColormapRange.Set(ranger, rangeg, rangeb, 0.f);
|
||||
}
|
||||
else if (mColormapState > CM_DEFAULT && mColormapState < CM_MAXCOLORMAP)
|
||||
{
|
||||
if (FGLRenderBuffers::IsEnabled())
|
||||
|
|
|
@ -144,7 +144,7 @@ public:
|
|||
|
||||
void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture)
|
||||
{
|
||||
// alpha textures need special treatment in the legacy renderer because withouz shaders they need a different texture.
|
||||
// alpha textures need special treatment in the legacy renderer because without shaders they need a different texture.
|
||||
if (alphatexture && gl.legacyMode) translation = INT_MAX;
|
||||
|
||||
if (mat->tex->bHasCanvas)
|
||||
|
|
|
@ -473,3 +473,15 @@ void OpenGLFrameBuffer::ScaleCoordsFromWindow(int16_t &x, int16_t &y)
|
|||
x = int16_t((x - letterboxX) * Width / letterboxWidth);
|
||||
y = int16_t((y - letterboxY) * Height / letterboxHeight);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// 2D drawing
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void OpenGLFrameBuffer::Draw2D()
|
||||
{
|
||||
//if (gl.legacyMode) Draw2DLegacy();
|
||||
if (GLRenderer != nullptr) GLRenderer->Draw2D(&m2DDrawer);
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ public:
|
|||
void SetVSync(bool vsync);
|
||||
|
||||
void ScaleCoordsFromWindow(int16_t &x, int16_t &y) override;
|
||||
void Draw2D() override;
|
||||
|
||||
bool HWGammaActive = false; // Are we using hardware or software gamma?
|
||||
std::shared_ptr<FGLDebug> mDebug; // Debug API
|
||||
|
|
|
@ -35,8 +35,7 @@ enum TexMode
|
|||
TM_INVERSE, // (1-r, 1-g, 1-b, a)
|
||||
TM_REDTOALPHA, // (1, 1, 1, r)
|
||||
TM_CLAMPY, // (r, g, b, (t >= 0.0 && t <= 1.0)? a:0)
|
||||
|
||||
TM_INVERTOPAQUE, // used by GL 2.x fallback code.
|
||||
TM_INVERTOPAQUE, // (1-r, 1-g, 1-b, 1)
|
||||
};
|
||||
|
||||
enum ELightMethod
|
||||
|
|
|
@ -62,14 +62,17 @@ bool GLTranslationPalette::Update()
|
|||
return true;
|
||||
}
|
||||
|
||||
int GLTranslationPalette::GetInternalTranslation(FRemapTable *remap)
|
||||
{
|
||||
if (remap == nullptr || remap->Inactive) return 0;
|
||||
|
||||
GLTranslationPalette *tpal = static_cast<GLTranslationPalette*>(remap->GetNative());
|
||||
if (tpal == nullptr) return 0;
|
||||
return tpal->GetIndex();
|
||||
}
|
||||
|
||||
int GLTranslationPalette::GetInternalTranslation(int trans)
|
||||
{
|
||||
if (trans <= 0) return 0;
|
||||
|
||||
FRemapTable *remap = TranslationToTable(trans);
|
||||
if (remap == NULL || remap->Inactive) return 0;
|
||||
|
||||
GLTranslationPalette *tpal = static_cast<GLTranslationPalette*>(remap->GetNative());
|
||||
if (tpal == NULL) return 0;
|
||||
return tpal->GetIndex();
|
||||
return GetInternalTranslation(TranslationToTable(trans));
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ public:
|
|||
|
||||
static GLTranslationPalette *CreatePalette(FRemapTable *remap);
|
||||
static int GetInternalTranslation(int trans);
|
||||
static int GetInternalTranslation(FRemapTable *trans);
|
||||
static PalEntry *GetPalette(unsigned int index)
|
||||
{
|
||||
return index > 0 && index <= AllPalettes.Size()? AllPalettes[index-1].pe : NULL;
|
||||
|
|
|
@ -25,9 +25,9 @@ public:
|
|||
DTM_Normal = 0,
|
||||
DTM_Stencil = 1,
|
||||
DTM_Opaque = 2,
|
||||
DTM_AlphaTexture = 3,
|
||||
DTM_Invert = 4,
|
||||
DTM_InvertOpaque = 5,
|
||||
DTM_Invert = 3,
|
||||
DTM_AlphaTexture = 4,
|
||||
DTM_InvertOpaque = 6,
|
||||
};
|
||||
|
||||
enum ETextureFlags : uint8_t
|
||||
|
|
|
@ -287,9 +287,8 @@ public:
|
|||
class DFrameBuffer
|
||||
{
|
||||
typedef DSimpleCanvas Super;
|
||||
F2DDrawer m2DDrawer;
|
||||
|
||||
protected:
|
||||
|
||||
void DrawTextureV(FTexture *img, double x, double y, uint32_t tag, va_list tags) = delete;
|
||||
void DrawTextureParms(FTexture *img, DrawParms &parms);
|
||||
|
||||
|
@ -297,6 +296,7 @@ protected:
|
|||
bool ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t tag, T& tags, DrawParms *parms, bool fortext) const;
|
||||
void DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms);
|
||||
|
||||
F2DDrawer m2DDrawer;
|
||||
int Width = 0;
|
||||
int Height = 0;
|
||||
bool Bgra = 0;
|
||||
|
|
|
@ -37,18 +37,18 @@ float4 SampleTexture(float2 tex_coord)
|
|||
|
||||
// Normal color calculation for most drawing modes.
|
||||
|
||||
float4 NormalColor(float2 tex_coord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR
|
||||
float4 NormalColor(float2 tex_coord : TEXCOORD0, float4 VertexColor : COLOR0, float4 Overlay : COLOR1) : COLOR
|
||||
{
|
||||
return Flash + SampleTexture(tex_coord) * InvFlash;
|
||||
return Overlay + SampleTexture(tex_coord) * VertexColor;
|
||||
}
|
||||
|
||||
// Copy the red channel to the alpha channel. Pays no attention to palettes.
|
||||
// Copy the red channel to the alpha channel. Pays no attention to palettes and only works with grayscale textures
|
||||
|
||||
float4 RedToAlpha(float2 tex_coord : TEXCOORD0, float4 Flash : COLOR0, float4 InvFlash : COLOR1) : COLOR
|
||||
float4 RedToAlpha(float2 tex_coord : TEXCOORD0, float4 VertexColor : COLOR0, float4 Overlay : COLOR1) : COLOR
|
||||
{
|
||||
float4 color = Invert(tex2D(Image, tex_coord));
|
||||
color.a = color.r;
|
||||
return Flash + color * InvFlash;
|
||||
color.a *= color.r;
|
||||
return Overlay + color * VertexColor;
|
||||
}
|
||||
|
||||
// Just return the value of c0.
|
||||
|
@ -87,12 +87,12 @@ float4 InGameColormap(float2 tex_coord : TEXCOORD0, float4 color : COLOR0, float
|
|||
rgb.rgb = intensity.rgb + rgb.rgb * Desaturation.y;
|
||||
#endif
|
||||
|
||||
// Fade
|
||||
rgb.rgb = rgb.rgb * fade.aaa + fade.rgb;
|
||||
|
||||
// Shade and Alpha
|
||||
rgb = rgb * color;
|
||||
|
||||
// Fade
|
||||
rgb.rgb = rgb.rgb * fade.aaa + fade.rgb;
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue