mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-10 14:52:01 +00:00
- hooked up the 2D drawer
compiles but not tested yet.
This commit is contained in:
parent
341ca9dd3a
commit
de829128ea
19 changed files with 676 additions and 63 deletions
|
@ -713,6 +713,8 @@ set (PCH_SOURCES
|
|||
glbackend/glbackend.cpp
|
||||
glbackend/gl_palmanager.cpp
|
||||
glbackend/gl_texture.cpp
|
||||
glbackend/gl_buffers.cpp
|
||||
glbackend/hw_draw2d.cpp
|
||||
|
||||
mact/src/animlib.cpp
|
||||
mact/src/control.cpp
|
||||
|
|
|
@ -108,6 +108,8 @@ enum ERenderAlpha
|
|||
STYLEALPHA_InvSrcCol, // Blend factor is 1.0 - color (HWR only)
|
||||
STYLEALPHA_DstCol, // Blend factor is dest. color (HWR only)
|
||||
STYLEALPHA_InvDstCol, // Blend factor is 1.0 - dest. color (HWR only)
|
||||
STYLEALPHA_Dst, // Blend factor is dest. alpha
|
||||
STYLEALPHA_InvDst, // Blend factor is 1.0 - dest. alpha
|
||||
STYLEALPHA_MAX
|
||||
};
|
||||
|
||||
|
|
|
@ -247,7 +247,7 @@ void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms)
|
|||
dg.mVertCount = 4;
|
||||
dg.mTexture = img;
|
||||
|
||||
dg.mTranslation = 0;
|
||||
dg.mRemapIndex = parms.remap;
|
||||
SetStyle(img, parms, vertexcolor, dg);
|
||||
|
||||
u1 = parms.srcx;
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
int mIndexCount;
|
||||
|
||||
FTexture *mTexture;
|
||||
FRemapTable *mTranslation;
|
||||
int mRemapIndex;
|
||||
PalEntry mSpecialColormap[2];
|
||||
int mScissor[4];
|
||||
int mDesaturate;
|
||||
|
@ -86,7 +86,7 @@ public:
|
|||
{
|
||||
return mTexture == other.mTexture &&
|
||||
mType == other.mType &&
|
||||
mTranslation == other.mTranslation &&
|
||||
mRemapIndex == other.mRemapIndex &&
|
||||
mSpecialColormap[0].d == other.mSpecialColormap[0].d &&
|
||||
mSpecialColormap[1].d == other.mSpecialColormap[1].d &&
|
||||
!memcmp(mScissor, other.mScissor, sizeof(mScissor)) &&
|
||||
|
|
|
@ -265,7 +265,7 @@ bool ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t tag, Va_Li
|
|||
parms->burn = false;
|
||||
parms->monospace = EMonospacing::Off;
|
||||
parms->spacing = 0;
|
||||
parms->remap = 0;
|
||||
parms->remap = -1;
|
||||
|
||||
// Parse the tag list for attributes. (For floating point attributes,
|
||||
// consider that the C ABI dictates that all floats be promoted to
|
||||
|
|
|
@ -126,7 +126,7 @@ void DrawTextCommon(F2DDrawer* drawer, FFont *font, int normalcolor, double x, d
|
|||
double cx;
|
||||
double cy;
|
||||
int boldcolor;
|
||||
FRemapTable *range;
|
||||
int range;
|
||||
int kerning;
|
||||
FTexture *pic;
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "myiswalpha.h"
|
||||
#include "fontchars.h"
|
||||
#include "imagehelpers.h"
|
||||
#include "glbackend/glbackend.h"
|
||||
|
||||
#include "fontinternals.h"
|
||||
|
||||
|
@ -219,7 +220,7 @@ void FFont::SetDefaultTranslation(uint32_t *othercolors)
|
|||
SimpleTranslation(mycolors, mytranslation, myreverse, myluminosity);
|
||||
SimpleTranslation(othercolors, othertranslation, otherreverse, otherluminosity);
|
||||
|
||||
FRemapTable remap(ActiveColors);
|
||||
FRemapTable remap;
|
||||
remap.Palette[0] = 0;
|
||||
|
||||
for (unsigned l = 1; l < myluminosity.Size(); l++)
|
||||
|
@ -247,7 +248,7 @@ void FFont::SetDefaultTranslation(uint32_t *othercolors)
|
|||
}
|
||||
}
|
||||
}
|
||||
Ranges[CR_UNTRANSLATED] = remap;
|
||||
Ranges[CR_UNTRANSLATED] = GLInterface.GetPaletteIndex(remap.Palette);
|
||||
forceremap = true;
|
||||
}
|
||||
|
||||
|
@ -355,7 +356,7 @@ void FFont::BuildTranslations (const double *luminosity, const uint8_t *identity
|
|||
int i, j;
|
||||
const TranslationParm *parmstart = (const TranslationParm *)ranges;
|
||||
|
||||
FRemapTable remap(total_colors);
|
||||
FRemapTable remap;
|
||||
|
||||
// Create different translations for different color ranges
|
||||
Ranges.Clear();
|
||||
|
@ -380,15 +381,14 @@ void FFont::BuildTranslations (const double *luminosity, const uint8_t *identity
|
|||
}
|
||||
else
|
||||
{
|
||||
remap = Ranges[0];
|
||||
}
|
||||
Ranges.Push(remap);
|
||||
Ranges.Push(GLInterface.GetPaletteIndex(remap.Palette));
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(parmstart->RangeStart >= 0);
|
||||
|
||||
remap.Palette[255] = 0;
|
||||
remap.Palette[0] = 0;
|
||||
|
||||
for (j = 0; j < ActiveColors; j++)
|
||||
{
|
||||
|
@ -414,7 +414,8 @@ void FFont::BuildTranslations (const double *luminosity, const uint8_t *identity
|
|||
b = clamp(b, 0, 255);
|
||||
remap.Palette[j] = PalEntry(255,r,g,b);
|
||||
}
|
||||
Ranges.Push(remap);
|
||||
|
||||
Ranges.Push(GLInterface.GetPaletteIndex(remap.Palette));
|
||||
|
||||
// Advance to the next color range.
|
||||
while (parmstart[1].RangeStart > parmstart[0].RangeEnd)
|
||||
|
@ -431,7 +432,7 @@ void FFont::BuildTranslations (const double *luminosity, const uint8_t *identity
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FRemapTable *FFont::GetColorTranslation (EColorRange range, PalEntry *color) const
|
||||
int FFont::GetColorTranslation (EColorRange range, PalEntry *color) const
|
||||
{
|
||||
if (noTranslate)
|
||||
{
|
||||
|
@ -444,11 +445,11 @@ FRemapTable *FFont::GetColorTranslation (EColorRange range, PalEntry *color) con
|
|||
if (color != nullptr) *color = retcolor;
|
||||
}
|
||||
if (ActiveColors == 0)
|
||||
return nullptr;
|
||||
return -1;
|
||||
else if (range >= NumTextColors)
|
||||
range = CR_UNTRANSLATED;
|
||||
//if (range == CR_UNTRANSLATED && !translateUntranslated) return nullptr;
|
||||
return &Ranges[range];
|
||||
return Ranges[range];
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -376,8 +376,8 @@ public:
|
|||
|
||||
SimpleTranslation(colors, othertranslation, otherreverse, otherluminosity);
|
||||
|
||||
FRemapTable remap(ActiveColors);
|
||||
remap.Palette[255] = 0;
|
||||
FRemapTable remap;
|
||||
remap.Palette[0] = 0;
|
||||
|
||||
for (unsigned l = 1; l < 18; l++)
|
||||
{
|
||||
|
|
|
@ -99,7 +99,7 @@ public:
|
|||
|
||||
virtual FTexture *GetChar (int code, int translation, int *const width, bool *redirected = nullptr) const;
|
||||
virtual int GetCharWidth (int code) const;
|
||||
FRemapTable *GetColorTranslation (EColorRange range, PalEntry *color = nullptr) const;
|
||||
int GetColorTranslation (EColorRange range, PalEntry *color = nullptr) const;
|
||||
int GetSpaceWidth () const { return SpaceWidth; }
|
||||
int GetHeight () const { return FontHeight; }
|
||||
int GetDefaultKerning () const { return GlobalKerning; }
|
||||
|
@ -164,7 +164,7 @@ protected:
|
|||
};
|
||||
TArray<CharData> Chars;
|
||||
int ActiveColors;
|
||||
TArray<FRemapTable> Ranges;
|
||||
TArray<int> Ranges;
|
||||
uint8_t PatchRemap[256];
|
||||
|
||||
FName FontName = NAME_None;
|
||||
|
@ -192,17 +192,7 @@ char* CleanseString(char* str);
|
|||
|
||||
struct FRemapTable
|
||||
{
|
||||
FRemapTable(int count = 256) {}
|
||||
~FRemapTable() { delete Palette; }
|
||||
|
||||
PalEntry *Palette = nullptr; // The ideal palette this maps to
|
||||
int PalIndex;
|
||||
int NumEntries; // # of elements in this table (usually 256)
|
||||
bool Inactive; // This table is inactive and should be treated as if it was passed as NULL
|
||||
|
||||
private:
|
||||
void Free();
|
||||
void Alloc(int count);
|
||||
PalEntry Palette[256] = { }; // The ideal palette this maps to
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
/*
|
||||
|
||||
OpenGL loader generated by glad 0.1.33 on Mon Sep 16 17:51:07 2019.
|
||||
|
|
83
source/glbackend/buffers.h
Normal file
83
source/glbackend/buffers.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
class FRenderState;
|
||||
|
||||
// The low level code needs to know which attributes exist.
|
||||
// OpenGL needs to change the state of all of them per buffer binding.
|
||||
// VAOs are mostly useless for this because they lump buffer and binding state together which the model code does not want.
|
||||
enum
|
||||
{
|
||||
VATTR_VERTEX,
|
||||
VATTR_TEXCOORD,
|
||||
VATTR_COLOR,
|
||||
VATTR_VERTEX2,
|
||||
VATTR_NORMAL,
|
||||
VATTR_NORMAL2,
|
||||
|
||||
VATTR_MAX
|
||||
};
|
||||
|
||||
enum EVertexAttributeFormat
|
||||
{
|
||||
VFmt_Float4,
|
||||
VFmt_Float3,
|
||||
VFmt_Float2,
|
||||
VFmt_Float,
|
||||
VFmt_Byte4,
|
||||
VFmt_Packed_A2R10G10B10,
|
||||
};
|
||||
|
||||
struct FVertexBufferAttribute
|
||||
{
|
||||
int binding;
|
||||
int location;
|
||||
int format;
|
||||
int offset;
|
||||
};
|
||||
|
||||
class IBuffer
|
||||
{
|
||||
protected:
|
||||
size_t buffersize = 0;
|
||||
void *map = nullptr;
|
||||
public:
|
||||
IBuffer() = default;
|
||||
IBuffer(const IBuffer &) = delete;
|
||||
IBuffer &operator=(const IBuffer &) = delete;
|
||||
virtual ~IBuffer() = default;
|
||||
|
||||
virtual void SetData(size_t size, const void *data, bool staticdata = true) = 0;
|
||||
virtual void SetSubData(size_t offset, size_t size, const void *data) = 0;
|
||||
virtual void *Lock(unsigned int size) = 0;
|
||||
virtual void Unlock() = 0;
|
||||
virtual void Resize(size_t newsize) = 0;
|
||||
virtual void Map() {} // Only needed by old OpenGL but this needs to be in the interface.
|
||||
virtual void Unmap() {}
|
||||
void *Memory() { assert(map); return map; }
|
||||
size_t Size() { return buffersize; }
|
||||
};
|
||||
|
||||
class IVertexBuffer : virtual public IBuffer
|
||||
{
|
||||
public:
|
||||
virtual void SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) = 0;
|
||||
};
|
||||
|
||||
// This merely exists to have a dedicated type for index buffers to inherit from.
|
||||
class IIndexBuffer : virtual public IBuffer
|
||||
{
|
||||
// Element size is fixed to 4, thanks to OpenGL requiring this info to be coded into the glDrawElements call.
|
||||
// This mostly prohibits a more flexible buffer setup but GZDoom doesn't use any other format anyway.
|
||||
// Ob Vulkam, element size is a buffer property and of no concern to the drawing functions (as it should be.)
|
||||
};
|
||||
|
||||
class IDataBuffer : virtual public IBuffer
|
||||
{
|
||||
// Can be either uniform or shader storage buffer, depending on its needs.
|
||||
public:
|
||||
virtual void BindRange(FRenderState *state, size_t start, size_t length) = 0;
|
||||
|
||||
};
|
218
source/glbackend/gl_buffers.cpp
Normal file
218
source/glbackend/gl_buffers.cpp
Normal file
|
@ -0,0 +1,218 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2018 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/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
** Low level vertex buffer class
|
||||
**
|
||||
**/
|
||||
|
||||
#include <algorithm>
|
||||
#include "glad/glad.h"
|
||||
#include "glbackend.h"
|
||||
#include "gl_buffers.h"
|
||||
|
||||
namespace OpenGLRenderer
|
||||
{
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// basic buffer implementation
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
GLBuffer::GLBuffer(int usetype)
|
||||
: mUseType(usetype)
|
||||
{
|
||||
glGenBuffers(1, &mBufferId);
|
||||
}
|
||||
|
||||
GLBuffer::~GLBuffer()
|
||||
{
|
||||
if (mBufferId != 0)
|
||||
{
|
||||
glBindBuffer(mUseType, mBufferId);
|
||||
glUnmapBuffer(mUseType);
|
||||
glBindBuffer(mUseType, 0);
|
||||
glDeleteBuffers(1, &mBufferId);
|
||||
}
|
||||
}
|
||||
|
||||
void GLBuffer::Bind()
|
||||
{
|
||||
glBindBuffer(mUseType, mBufferId);
|
||||
}
|
||||
|
||||
|
||||
void GLBuffer::SetData(size_t size, const void *data, bool staticdata)
|
||||
{
|
||||
Bind();
|
||||
if (data != nullptr)
|
||||
{
|
||||
glBufferData(mUseType, size, data, staticdata? GL_STATIC_DRAW : GL_STREAM_DRAW);
|
||||
}
|
||||
else
|
||||
{
|
||||
mPersistent = /*screen->BuffersArePersistent() &&*/ !staticdata;
|
||||
if (mPersistent)
|
||||
{
|
||||
glBufferStorage(mUseType, size, nullptr, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
map = glMapBufferRange(mUseType, 0, size, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferData(mUseType, size, nullptr, staticdata ? GL_STATIC_DRAW : GL_STREAM_DRAW);
|
||||
map = nullptr;
|
||||
}
|
||||
if (!staticdata) nomap = false;
|
||||
}
|
||||
buffersize = size;
|
||||
}
|
||||
|
||||
void GLBuffer::SetSubData(size_t offset, size_t size, const void *data)
|
||||
{
|
||||
Bind();
|
||||
glBufferSubData(mUseType, offset, size, data);
|
||||
}
|
||||
|
||||
void GLBuffer::Map()
|
||||
{
|
||||
assert(nomap == false); // do not allow mapping of static buffers. Vulkan cannot do that so it should be blocked in OpenGL, too.
|
||||
if (!mPersistent && !nomap)
|
||||
{
|
||||
Bind();
|
||||
map = glMapBufferRange(mUseType, 0, buffersize, GL_MAP_WRITE_BIT|GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
void GLBuffer::Unmap()
|
||||
{
|
||||
assert(nomap == false);
|
||||
if (!mPersistent && map != nullptr)
|
||||
{
|
||||
Bind();
|
||||
glUnmapBuffer(mUseType);
|
||||
map = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void *GLBuffer::Lock(unsigned int size)
|
||||
{
|
||||
// This initializes this buffer as a static object with no data.
|
||||
SetData(size, nullptr, true);
|
||||
return glMapBufferRange(mUseType, 0, size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
}
|
||||
|
||||
void GLBuffer::Unlock()
|
||||
{
|
||||
Bind();
|
||||
glUnmapBuffer(mUseType);
|
||||
}
|
||||
|
||||
void GLBuffer::Resize(size_t newsize)
|
||||
{
|
||||
assert(!nomap); // only mappable buffers can be resized.
|
||||
if (newsize > buffersize && !nomap)
|
||||
{
|
||||
// reallocate the buffer with twice the size
|
||||
unsigned int oldbuffer = mBufferId;
|
||||
|
||||
// first unmap the old buffer
|
||||
Bind();
|
||||
glUnmapBuffer(mUseType);
|
||||
|
||||
glGenBuffers(1, &mBufferId);
|
||||
SetData(newsize, nullptr, false);
|
||||
glBindBuffer(GL_COPY_READ_BUFFER, oldbuffer);
|
||||
|
||||
// copy contents and delete the old buffer.
|
||||
glCopyBufferSubData(GL_COPY_READ_BUFFER, mUseType, 0, 0, buffersize);
|
||||
glBindBuffer(GL_COPY_READ_BUFFER, 0);
|
||||
glDeleteBuffers(1, &oldbuffer);
|
||||
buffersize = newsize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Vertex buffer implementation
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void GLVertexBuffer::SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs)
|
||||
{
|
||||
static int VFmtToGLFmt[] = { GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE, GL_INT_2_10_10_10_REV };
|
||||
static uint8_t VFmtToSize[] = {4, 3, 2, 1, 4, 4};
|
||||
|
||||
mStride = stride;
|
||||
mNumBindingPoints = numBindingPoints;
|
||||
|
||||
for(int i = 0; i < numAttributes; i++)
|
||||
{
|
||||
if (attrs[i].location >= 0 && attrs[i].location < VATTR_MAX)
|
||||
{
|
||||
auto & attrinf = mAttributeInfo[attrs[i].location];
|
||||
attrinf.format = VFmtToGLFmt[attrs[i].format];
|
||||
attrinf.size = VFmtToSize[attrs[i].format];
|
||||
attrinf.offset = attrs[i].offset;
|
||||
attrinf.bindingpoint = attrs[i].binding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLVertexBuffer::Bind(int *offsets)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
// This is what gets called from RenderState.Apply. It shouldn't be called anywhere else if the render state is in use
|
||||
GLBuffer::Bind();
|
||||
for(auto &attrinf : mAttributeInfo)
|
||||
{
|
||||
if (attrinf.size == 0)
|
||||
{
|
||||
glDisableVertexAttribArray(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnableVertexAttribArray(i);
|
||||
size_t ofs = offsets == nullptr ? attrinf.offset : attrinf.offset + mStride * offsets[attrinf.bindingpoint];
|
||||
glVertexAttribPointer(i, attrinf.size, attrinf.format, attrinf.format != GL_FLOAT, (GLsizei)mStride, (void*)(intptr_t)ofs);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void GLDataBuffer::BindRange(FRenderState *state, size_t start, size_t length)
|
||||
{
|
||||
glBindBufferRange(mUseType, mBindingPoint, mBufferId, start, length);
|
||||
}
|
||||
|
||||
void GLDataBuffer::BindBase()
|
||||
{
|
||||
glBindBufferBase(mUseType, mBindingPoint, mBufferId);
|
||||
}
|
||||
|
||||
|
||||
GLVertexBuffer::GLVertexBuffer() : GLBuffer(GL_ARRAY_BUFFER) {}
|
||||
GLIndexBuffer::GLIndexBuffer() : GLBuffer(GL_ELEMENT_ARRAY_BUFFER) {}
|
||||
GLDataBuffer::GLDataBuffer(int bindingpoint, bool is_ssbo) : GLBuffer(is_ssbo ? GL_SHADER_STORAGE_BUFFER : GL_UNIFORM_BUFFER), mBindingPoint(bindingpoint) {}
|
||||
|
||||
}
|
73
source/glbackend/gl_buffers.h
Normal file
73
source/glbackend/gl_buffers.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
#pragma once
|
||||
|
||||
#include "buffers.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// silence bogus warning C4250: 'GLVertexBuffer': inherits 'GLBuffer::GLBuffer::SetData' via dominance
|
||||
// According to internet infos, the warning is erroneously emitted in this case.
|
||||
#pragma warning(disable:4250)
|
||||
#endif
|
||||
|
||||
namespace OpenGLRenderer
|
||||
{
|
||||
|
||||
class GLBuffer : virtual public IBuffer
|
||||
{
|
||||
protected:
|
||||
const int mUseType;
|
||||
unsigned int mBufferId;
|
||||
int mAllocationSize = 0;
|
||||
bool mPersistent = false;
|
||||
bool nomap = true;
|
||||
|
||||
GLBuffer(int usetype);
|
||||
~GLBuffer();
|
||||
void SetData(size_t size, const void *data, bool staticdata) override;
|
||||
void SetSubData(size_t offset, size_t size, const void *data) override;
|
||||
void Map() override;
|
||||
void Unmap() override;
|
||||
void Resize(size_t newsize) override;
|
||||
void *Lock(unsigned int size) override;
|
||||
void Unlock() override;
|
||||
public:
|
||||
void Bind();
|
||||
};
|
||||
|
||||
|
||||
class GLVertexBuffer : public IVertexBuffer, public GLBuffer
|
||||
{
|
||||
// If this could use the modern (since GL 4.3) binding system, things would be simpler... :(
|
||||
struct GLVertexBufferAttribute
|
||||
{
|
||||
int bindingpoint;
|
||||
int format;
|
||||
int size;
|
||||
int offset;
|
||||
};
|
||||
|
||||
int mNumBindingPoints;
|
||||
GLVertexBufferAttribute mAttributeInfo[VATTR_MAX] = {}; // Thanks to OpenGL's state system this needs to contain info about every attribute that may ever be in use throughout the entire renderer.
|
||||
size_t mStride = 0;
|
||||
|
||||
public:
|
||||
GLVertexBuffer();
|
||||
void SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) override;
|
||||
void Bind(int *offsets);
|
||||
};
|
||||
|
||||
class GLIndexBuffer : public IIndexBuffer, public GLBuffer
|
||||
{
|
||||
public:
|
||||
GLIndexBuffer();
|
||||
};
|
||||
|
||||
class GLDataBuffer : public IDataBuffer, public GLBuffer
|
||||
{
|
||||
int mBindingPoint;
|
||||
public:
|
||||
GLDataBuffer(int bindingpoint, bool is_ssbo);
|
||||
void BindRange(FRenderState* state, size_t start, size_t length);
|
||||
void BindBase();
|
||||
};
|
||||
|
||||
}
|
|
@ -40,6 +40,7 @@
|
|||
#include "baselayer.h"
|
||||
#include "resourcefile.h"
|
||||
#include "imagehelpers.h"
|
||||
#include "v_font.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "PalEntry.h"
|
||||
#include "gl_buffers.h"
|
||||
class PolymostShader;
|
||||
|
||||
enum PRSFlags
|
||||
|
@ -34,6 +35,10 @@ struct PolymostRenderState
|
|||
float NPOTEmulationXOffset;
|
||||
float Brightness = 1.f;
|
||||
PalEntry FogColor;
|
||||
|
||||
IVertexBuffer* VertexBuffer = nullptr;
|
||||
int VB_Offset[2] = {};
|
||||
IIndexBuffer* IndexBuffer = nullptr;
|
||||
|
||||
void Apply(PolymostShader *shader);
|
||||
};
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "polymost.h"
|
||||
#include "textures.h"
|
||||
#include "bitmap.h"
|
||||
#include "v_font.h"
|
||||
#include "../../glbackend/glbackend.h"
|
||||
|
||||
// Test CVARs.
|
||||
|
@ -155,10 +156,6 @@ FHardwareTexture* GLInstance::LoadTexture(FTexture* tex, int textype, int palid)
|
|||
|
||||
bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int method, int sampleroverride, float xpanning, float ypanning, FTexture *det, float detscale, FTexture *glow)
|
||||
{
|
||||
if (picnum == 3692)
|
||||
{
|
||||
int a = 0;
|
||||
}
|
||||
if (tex->GetWidth() <= 0 || tex->GetHeight() <= 0) return false;
|
||||
int usepalette = fixpalette >= 1 ? fixpalette - 1 : curbasepal;
|
||||
int usepalswap = fixpalswap >= 1 ? fixpalswap - 1 : palette;
|
||||
|
@ -180,7 +177,7 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
|
|||
else
|
||||
{
|
||||
// Only look up the palette if we really want to use it (i.e. when creating a true color texture of an ART tile.)
|
||||
if (!hw_useindexedcolortextures) lookuppal = palmanager.LookupPalette(usepalette, usepalswap, false);
|
||||
if (TextureType == TT_TRUECOLOR) lookuppal = palmanager.LookupPalette(usepalette, usepalswap, false);
|
||||
}
|
||||
|
||||
// Load the main texture
|
||||
|
@ -291,3 +288,21 @@ bool GLInstance::SetTextureInternal(int picnum, FTexture* tex, int palette, int
|
|||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Sets a named texture for 2D rendering. In this case the palette is
|
||||
// a direct index into the palette map.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool GLInstance::SetNamedTexture(FTexture* tex, int palette, int sampler)
|
||||
{
|
||||
auto mtex = LoadTexture(tex, palette>= 0? TT_TRUECOLOR : TT_HICREPLACE, palette);
|
||||
if (!mtex) return false;
|
||||
|
||||
renderState.Flags &= ~RF_UsePalette;
|
||||
BindTexture(0, mtex, sampler);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -208,15 +208,33 @@ void GLInstance::Draw(EDrawType type, size_t start, size_t count)
|
|||
if (activeShader == polymostShader)
|
||||
{
|
||||
renderState.Apply(polymostShader);
|
||||
if (renderState.VertexBuffer != LastVertexBuffer || LastVB_Offset[0] != renderState.VB_Offset[0] || LastVB_Offset[1] != renderState.VB_Offset[1])
|
||||
{
|
||||
static_cast<OpenGLRenderer::GLVertexBuffer*>(renderState.VertexBuffer)->Bind(renderState.VB_Offset);
|
||||
LastVertexBuffer = renderState.VertexBuffer;
|
||||
LastVB_Offset[0] = renderState.VB_Offset[0];
|
||||
LastVB_Offset[1] = renderState.VB_Offset[1];
|
||||
}
|
||||
if (renderState.IndexBuffer != LastIndexBuffer)
|
||||
{
|
||||
static_cast<OpenGLRenderer::GLIndexBuffer*>(renderState.IndexBuffer)->Bind();
|
||||
}
|
||||
}
|
||||
glBegin(primtypes[type]);
|
||||
auto p = &Buffer[start];
|
||||
for (size_t i = 0; i < count; i++, p++)
|
||||
if (!LastVertexBuffer)
|
||||
{
|
||||
glVertexAttrib2f(1, p->u, p->v);
|
||||
glVertexAttrib3f(0, p->x, p->y, p->z);
|
||||
glBegin(primtypes[type]);
|
||||
auto p = &Buffer[start];
|
||||
for (size_t i = 0; i < count; i++, p++)
|
||||
{
|
||||
glVertexAttrib2f(1, p->u, p->v);
|
||||
glVertexAttrib3f(0, p->x, p->y, p->z);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawElements(primtypes[type], count, GL_UNSIGNED_INT, (void*)(intptr_t)(start * sizeof(uint32_t)));
|
||||
}
|
||||
glEnd();
|
||||
if (MatrixChange) RestoreTextureProps();
|
||||
}
|
||||
|
||||
|
@ -281,6 +299,12 @@ void GLInstance::EnableDepthTest(bool on)
|
|||
else glDisable (GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void GLInstance::EnableMultisampling(bool on)
|
||||
{
|
||||
if (on) glEnable(GL_MULTISAMPLE);
|
||||
else glDisable(GL_MULTISAMPLE);
|
||||
}
|
||||
|
||||
void GLInstance::SetMatrix(int num, const VSMatrix *mat)
|
||||
{
|
||||
matrices[num] = *mat;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "gl_renderstate.h"
|
||||
#include "matrix.h"
|
||||
#include "palentry.h"
|
||||
#include "renderstyle.h"
|
||||
|
||||
class FSamplerManager;
|
||||
class FShader;
|
||||
|
@ -64,7 +65,6 @@ class PaletteManager
|
|||
|
||||
//OpenGLRenderer::GLDataBuffer* palswapBuffer = nullptr;
|
||||
|
||||
unsigned FindPalette(const uint8_t* paldata);
|
||||
unsigned FindPalswap(const uint8_t* paldata);
|
||||
|
||||
public:
|
||||
|
@ -80,6 +80,8 @@ public:
|
|||
int ActivePalswap() const { return lastsindex; }
|
||||
int LookupPalette(int palette, int palswap, bool brightmap);
|
||||
const PalEntry *GetPaletteData(int palid) const { return palettes[palid].colors; }
|
||||
unsigned FindPalette(const uint8_t* paldata);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -157,27 +159,6 @@ enum EDepthFunc
|
|||
Depth_LessEqual
|
||||
};
|
||||
|
||||
enum ERenderAlpha
|
||||
{
|
||||
STYLEALPHA_Zero, // Blend factor is 0.0
|
||||
STYLEALPHA_One, // Blend factor is 1.0
|
||||
STYLEALPHA_Src, // Blend factor is alpha
|
||||
STYLEALPHA_InvSrc, // Blend factor is 1.0 - alpha
|
||||
STYLEALPHA_SrcCol, // Blend factor is color (HWR only)
|
||||
STYLEALPHA_InvSrcCol, // Blend factor is 1.0 - color (HWR only)
|
||||
STYLEALPHA_DstCol, // Blend factor is dest. color (HWR only)
|
||||
STYLEALPHA_InvDstCol, // Blend factor is 1.0 - dest. color (HWR only)
|
||||
STYLEALPHA_Dst, // Blend factor is dest. alpha
|
||||
STYLEALPHA_InvDst, // Blend factor is 1.0 - dest. alpha
|
||||
STYLEALPHA_MAX
|
||||
};
|
||||
|
||||
enum ERenderOp
|
||||
{
|
||||
STYLEOP_Add, // Add source to destination
|
||||
STYLEOP_Sub, // Subtract source from destination
|
||||
STYLEOP_RevSub, // Subtract destination from source
|
||||
};
|
||||
|
||||
enum EWinding
|
||||
{
|
||||
|
@ -212,6 +193,10 @@ class GLInstance
|
|||
int TextureType;
|
||||
int MatrixChange = 0;
|
||||
|
||||
IVertexBuffer* LastVertexBuffer = nullptr;
|
||||
int LastVB_Offset[2] = {};
|
||||
IIndexBuffer* LastIndexBuffer = nullptr;
|
||||
|
||||
|
||||
VSMatrix matrices[NUMMATRICES];
|
||||
PolymostRenderState renderState;
|
||||
|
@ -251,6 +236,17 @@ public:
|
|||
void EnableBlend(bool on);
|
||||
void EnableAlphaTest(bool on);
|
||||
void EnableDepthTest(bool on);
|
||||
void EnableMultisampling(bool on);
|
||||
void SetVertexBuffer(IVertexBuffer* vb, int offset1, int offset2)
|
||||
{
|
||||
renderState.VertexBuffer = vb;
|
||||
renderState.VB_Offset[0] = offset1;
|
||||
renderState.VB_Offset[1] = offset2;
|
||||
}
|
||||
void SetIndexBuffer(IIndexBuffer* vb)
|
||||
{
|
||||
renderState.IndexBuffer = vb;
|
||||
}
|
||||
const VSMatrix &GetMatrix(int num)
|
||||
{
|
||||
return matrices[num];
|
||||
|
@ -396,12 +392,18 @@ public:
|
|||
{
|
||||
// not yet implemented - only relevant for hires replacements.
|
||||
}
|
||||
|
||||
int GetPaletteIndex(PalEntry* palette)
|
||||
{
|
||||
return palmanager.FindPalette((uint8_t*)palette);
|
||||
}
|
||||
|
||||
FHardwareTexture* CreateIndexedTexture(FTexture* tex);
|
||||
FHardwareTexture* CreateTrueColorTexture(FTexture* tex, int palid, bool checkfulltransparency = false, bool rgb8bit = false);
|
||||
FHardwareTexture *LoadTexture(FTexture* tex, int texturetype, int palid);
|
||||
bool SetTextureInternal(int globalpicnum, FTexture* tex, int palette, int method, int sampleroverride, float xpanning, float ypanning, FTexture *det, float detscale, FTexture *glow);
|
||||
|
||||
bool SetNamedTexture(FTexture* tex, int palette, int sampleroverride);
|
||||
|
||||
bool SetTexture(int globalpicnum, FTexture* tex, int palette, int method, int sampleroverride)
|
||||
{
|
||||
|
|
196
source/glbackend/hw_draw2d.cpp
Normal file
196
source/glbackend/hw_draw2d.cpp
Normal file
|
@ -0,0 +1,196 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2018 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/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
** 2d drawer
|
||||
** Renderer interface
|
||||
**
|
||||
*/
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "gl_buffers.h"
|
||||
#include "v_2ddrawer.h"
|
||||
#include "c_cvars.h"
|
||||
#include "glbackend.h"
|
||||
#include "v_draw.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Vertex buffer for 2D drawer
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
class F2DVertexBuffer
|
||||
{
|
||||
IVertexBuffer *mVertexBuffer;
|
||||
IIndexBuffer *mIndexBuffer;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
F2DVertexBuffer()
|
||||
{
|
||||
mVertexBuffer = new OpenGLRenderer::GLVertexBuffer();
|
||||
mIndexBuffer = new OpenGLRenderer::GLIndexBuffer();
|
||||
|
||||
static const FVertexBufferAttribute format[] = {
|
||||
{ 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(F2DDrawer::TwoDVertex, x) },
|
||||
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(F2DDrawer::TwoDVertex, u) },
|
||||
{ 0, VATTR_COLOR, VFmt_Byte4, (int)myoffsetof(F2DDrawer::TwoDVertex, color0) }
|
||||
};
|
||||
mVertexBuffer->SetFormat(1, 3, sizeof(F2DDrawer::TwoDVertex), format);
|
||||
}
|
||||
~F2DVertexBuffer()
|
||||
{
|
||||
delete mIndexBuffer;
|
||||
delete mVertexBuffer;
|
||||
}
|
||||
|
||||
void UploadData(F2DDrawer::TwoDVertex *vertices, int vertcount, int *indices, int indexcount)
|
||||
{
|
||||
mVertexBuffer->SetData(vertcount * sizeof(*vertices), vertices, false);
|
||||
mIndexBuffer->SetData(indexcount * sizeof(unsigned int), indices, false);
|
||||
}
|
||||
|
||||
std::pair<IVertexBuffer *, IIndexBuffer *> GetBufferObjects() const
|
||||
{
|
||||
return std::make_pair(mVertexBuffer, mIndexBuffer);
|
||||
}
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Draws the 2D stuff. This is the version for OpenGL 3 and later.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void Draw2D(F2DDrawer *drawer, FRenderState &state)
|
||||
{
|
||||
VSMatrix mat(0);
|
||||
GLInterface.SetMatrix(Matrix_View, mat.get());
|
||||
GLInterface.SetMatrix(Matrix_ModelView, mat.get());
|
||||
GLInterface.SetMatrix(Matrix_Detail, mat.get());
|
||||
mat.ortho(0, xdim, ydim, 0, -1, 1);
|
||||
GLInterface.SetMatrix(Matrix_Projection, mat.get());
|
||||
GLInterface.SetViewport(0, 0, xdim, ydim);
|
||||
GLInterface.EnableDepthTest(false);
|
||||
GLInterface.EnableMultisampling(false);
|
||||
|
||||
auto &vertices = drawer->mVertices;
|
||||
auto &indices = drawer->mIndices;
|
||||
auto &commands = drawer->mData;
|
||||
|
||||
if (commands.Size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (drawer->mIsFirstPass)
|
||||
{
|
||||
for (auto &v : vertices)
|
||||
{
|
||||
// Change from BGRA to RGBA
|
||||
std::swap(v.color0.r, v.color0.b);
|
||||
}
|
||||
}
|
||||
F2DVertexBuffer vb;
|
||||
vb.UploadData(&vertices[0], vertices.Size(), &indices[0], indices.Size());
|
||||
GLInterface.SetVertexBuffer(vb.GetBufferObjects().first, 0, 0);
|
||||
GLInterface.SetIndexBuffer(vb.GetBufferObjects().second);
|
||||
GLInterface.SetFadeDisable(true);
|
||||
|
||||
for(auto &cmd : commands)
|
||||
{
|
||||
|
||||
int gltrans = -1;
|
||||
//state.SetRenderStyle(cmd.mRenderStyle);
|
||||
//state.EnableBrightmap(!(cmd.mRenderStyle.Flags & STYLEF_ColorIsFixed));
|
||||
//state.SetTextureMode(cmd.mDrawMode);
|
||||
|
||||
int sciX, sciY, sciW, sciH;
|
||||
if (cmd.mFlags & F2DDrawer::DTF_Scissor)
|
||||
{
|
||||
// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
|
||||
// Note that the origin here is the lower left corner!
|
||||
sciX = /*screen->ScreenToWindowX*/(cmd.mScissor[0]);
|
||||
sciY = /*screen->ScreenToWindowY*/(cmd.mScissor[3]);
|
||||
sciW = /*screen->ScreenToWindowX*/(cmd.mScissor[2]) - sciX;
|
||||
sciH = /*screen->ScreenToWindowY*/(cmd.mScissor[1]) - sciY;
|
||||
}
|
||||
else
|
||||
{
|
||||
sciX = sciY = sciW = sciH = -1;
|
||||
}
|
||||
//GLInterface.SetScissor(sciX, sciY, sciW, sciH);
|
||||
|
||||
//state.SetFog(cmd.mColor1, 0);
|
||||
GLInterface.SetColor(1, 1, 1);
|
||||
//state.SetColor(1, 1, 1, 1, cmd.mDesaturate);
|
||||
|
||||
GLInterface.SetAlphaThreshold(0.0f);
|
||||
|
||||
if (cmd.mTexture != nullptr)
|
||||
{
|
||||
auto tex = cmd.mTexture;
|
||||
GLInterface.SetNamedTexture(cmd.mTexture, cmd.mRemapIndex, cmd.mFlags & F2DDrawer::DTF_Wrap ? SamplerRepeat : SamplerClampXY);
|
||||
GLInterface.UseColorOnly(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
GLInterface.UseColorOnly(true);
|
||||
}
|
||||
|
||||
switch (cmd.mType)
|
||||
{
|
||||
case F2DDrawer::DrawTypeTriangles:
|
||||
GLInterface.Draw(DT_TRIANGLES, cmd.mIndexIndex, cmd.mIndexCount);
|
||||
break;
|
||||
|
||||
case F2DDrawer::DrawTypeLines:
|
||||
GLInterface.Draw(DT_LINES, cmd.mVertIndex, cmd.mVertCount);
|
||||
break;
|
||||
|
||||
case F2DDrawer::DrawTypePoints:
|
||||
//GLInterface.Draw(DT_POINTS, cmd.mVertIndex, cmd.mVertCount);
|
||||
break;
|
||||
|
||||
}
|
||||
/*
|
||||
state.SetObjectColor(0xffffffff);
|
||||
state.SetObjectColor2(0);
|
||||
state.SetAddColor(0);
|
||||
state.EnableTextureMatrix(false);
|
||||
state.SetEffect(EFF_NONE);
|
||||
*/
|
||||
|
||||
}
|
||||
//state.SetScissor(-1, -1, -1, -1);
|
||||
|
||||
//state.SetRenderStyle(STYLE_Translucent);
|
||||
GLInterface.SetVertexBuffer(nullptr, 0, 0);
|
||||
GLInterface.SetIndexBuffer(nullptr);
|
||||
GLInterface.UseColorOnly(false);
|
||||
//state.EnableBrightmap(true);
|
||||
//state.SetTextureMode(TM_NORMAL);
|
||||
GLInterface.SetFadeDisable(false);
|
||||
GLInterface.SetColor(1, 1, 1);
|
||||
//drawer->mIsFirstPass = false;
|
||||
}
|
Loading…
Reference in a new issue