mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-27 20:20:40 +00:00
- backend update from GZDoom.
This commit is contained in:
parent
7b72fccfa2
commit
e7ab4cd176
16 changed files with 333 additions and 188 deletions
|
@ -34,6 +34,8 @@
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "templates.h"
|
#include "templates.h"
|
||||||
|
#include "v_2ddrawer.h"
|
||||||
|
#include "vectors.h"
|
||||||
#include "vm.h"
|
#include "vm.h"
|
||||||
#include "c_cvars.h"
|
#include "c_cvars.h"
|
||||||
#include "v_draw.h"
|
#include "v_draw.h"
|
||||||
|
@ -107,7 +109,6 @@ IMPLEMENT_CLASS(DShape2D, false, false)
|
||||||
static void Shape2D_SetTransform(DShape2D* self, DShape2DTransform *transform)
|
static void Shape2D_SetTransform(DShape2D* self, DShape2DTransform *transform)
|
||||||
{
|
{
|
||||||
self->transform = transform->transform;
|
self->transform = transform->transform;
|
||||||
self->dirty = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, SetTransform, Shape2D_SetTransform)
|
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, SetTransform, Shape2D_SetTransform)
|
||||||
|
@ -120,13 +121,10 @@ DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, SetTransform, Shape2D_SetTransform)
|
||||||
|
|
||||||
static void Shape2D_Clear(DShape2D* self, int which)
|
static void Shape2D_Clear(DShape2D* self, int which)
|
||||||
{
|
{
|
||||||
if (which & C_Verts)
|
if (which & C_Verts) self->mVertices.Clear();
|
||||||
{
|
|
||||||
self->mVertices.Clear();
|
|
||||||
self->dirty = true;
|
|
||||||
}
|
|
||||||
if (which & C_Coords) self->mCoords.Clear();
|
if (which & C_Coords) self->mCoords.Clear();
|
||||||
if (which & C_Indices) self->mIndices.Clear();
|
if (which & C_Indices) self->mIndices.Clear();
|
||||||
|
self->needsVertexUpload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, Clear, Shape2D_Clear)
|
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, Clear, Shape2D_Clear)
|
||||||
|
@ -140,7 +138,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, Clear, Shape2D_Clear)
|
||||||
static void Shape2D_PushVertex(DShape2D* self, double x, double y)
|
static void Shape2D_PushVertex(DShape2D* self, double x, double y)
|
||||||
{
|
{
|
||||||
self->mVertices.Push(DVector2(x, y));
|
self->mVertices.Push(DVector2(x, y));
|
||||||
self->dirty = true;
|
self->needsVertexUpload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushVertex, Shape2D_PushVertex)
|
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushVertex, Shape2D_PushVertex)
|
||||||
|
@ -155,6 +153,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushVertex, Shape2D_PushVertex)
|
||||||
static void Shape2D_PushCoord(DShape2D* self, double u, double v)
|
static void Shape2D_PushCoord(DShape2D* self, double u, double v)
|
||||||
{
|
{
|
||||||
self->mCoords.Push(DVector2(u, v));
|
self->mCoords.Push(DVector2(u, v));
|
||||||
|
self->needsVertexUpload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushCoord, Shape2D_PushCoord)
|
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushCoord, Shape2D_PushCoord)
|
||||||
|
@ -171,6 +170,7 @@ static void Shape2D_PushTriangle(DShape2D* self, int a, int b, int c)
|
||||||
self->mIndices.Push(a);
|
self->mIndices.Push(a);
|
||||||
self->mIndices.Push(b);
|
self->mIndices.Push(b);
|
||||||
self->mIndices.Push(c);
|
self->mIndices.Push(c);
|
||||||
|
self->needsVertexUpload = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushTriangle, Shape2D_PushTriangle)
|
DEFINE_ACTION_FUNCTION_NATIVE(DShape2D, PushTriangle, Shape2D_PushTriangle)
|
||||||
|
@ -556,26 +556,33 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
|
||||||
if (!img->isHardwareCanvas() && parms.TranslationId != -1)
|
if (!img->isHardwareCanvas() && parms.TranslationId != -1)
|
||||||
dg.mTranslationId = parms.TranslationId;
|
dg.mTranslationId = parms.TranslationId;
|
||||||
|
|
||||||
if (shape->dirty) {
|
|
||||||
if (shape->mVertices.Size() != shape->mTransformedVertices.Size())
|
|
||||||
shape->mTransformedVertices.Resize(shape->mVertices.Size());
|
|
||||||
for (int i = 0; i < dg.mVertCount; i++) {
|
|
||||||
shape->mTransformedVertices[i] = (shape->transform * DVector3(shape->mVertices[i], 1.0)).XY();
|
|
||||||
}
|
|
||||||
shape->dirty = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto osave = offset;
|
auto osave = offset;
|
||||||
if (parms.nooffset) offset = { 0,0 };
|
if (parms.nooffset) offset = { 0,0 };
|
||||||
|
|
||||||
double minx = 16383, miny = 16383, maxx = -16384, maxy = -16384;
|
if (shape->needsVertexUpload)
|
||||||
for ( int i=0; i<dg.mVertCount; i++ )
|
|
||||||
{
|
{
|
||||||
if ( shape->mTransformedVertices[i].X < minx ) minx = shape->mTransformedVertices[i].X;
|
shape->minx = 16383;
|
||||||
if ( shape->mTransformedVertices[i].Y < miny ) miny = shape->mTransformedVertices[i].Y;
|
shape->miny = 16383;
|
||||||
if ( shape->mTransformedVertices[i].X > maxx ) maxx = shape->mTransformedVertices[i].X;
|
shape->maxx = -16384;
|
||||||
if ( shape->mTransformedVertices[i].Y > maxy ) maxy = shape->mTransformedVertices[i].Y;
|
shape->maxy = -16384;
|
||||||
|
for ( int i=0; i<dg.mVertCount; i++ )
|
||||||
|
{
|
||||||
|
if ( shape->mVertices[i].X < shape->minx ) shape->minx = shape->mVertices[i].X;
|
||||||
|
if ( shape->mVertices[i].Y < shape->miny ) shape->miny = shape->mVertices[i].Y;
|
||||||
|
if ( shape->mVertices[i].X > shape->maxx ) shape->maxx = shape->mVertices[i].X;
|
||||||
|
if ( shape->mVertices[i].Y > shape->maxy ) shape->maxy = shape->mVertices[i].Y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
auto tCorners = {
|
||||||
|
(shape->transform * DVector3(shape->minx, shape->miny, 1.0)).XY(),
|
||||||
|
(shape->transform * DVector3(shape->minx, shape->maxy, 1.0)).XY(),
|
||||||
|
(shape->transform * DVector3(shape->maxx, shape->miny, 1.0)).XY(),
|
||||||
|
(shape->transform * DVector3(shape->maxx, shape->maxy, 1.0)).XY()
|
||||||
|
};
|
||||||
|
double minx = std::min_element(tCorners.begin(), tCorners.end(), [] (auto d0, auto d1) { return d0.X < d1.X; })->X;
|
||||||
|
double maxx = std::max_element(tCorners.begin(), tCorners.end(), [] (auto d0, auto d1) { return d0.X < d1.X; })->X;
|
||||||
|
double miny = std::min_element(tCorners.begin(), tCorners.end(), [] (auto d0, auto d1) { return d0.Y < d1.Y; })->Y;
|
||||||
|
double maxy = std::max_element(tCorners.begin(), tCorners.end(), [] (auto d0, auto d1) { return d0.Y < d1.Y; })->Y;
|
||||||
if (minx < (double)parms.lclip || miny < (double)parms.uclip || maxx >(double)parms.rclip || maxy >(double)parms.dclip)
|
if (minx < (double)parms.lclip || miny < (double)parms.uclip || maxx >(double)parms.rclip || maxy >(double)parms.dclip)
|
||||||
{
|
{
|
||||||
dg.mScissor[0] = parms.lclip + int(offset.X);
|
dg.mScissor[0] = parms.lclip + int(offset.X);
|
||||||
|
@ -587,24 +594,39 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
|
||||||
else
|
else
|
||||||
memset(dg.mScissor, 0, sizeof(dg.mScissor));
|
memset(dg.mScissor, 0, sizeof(dg.mScissor));
|
||||||
|
|
||||||
dg.mVertIndex = (int)mVertices.Reserve(dg.mVertCount);
|
dg.useTransform = true;
|
||||||
TwoDVertex *ptr = &mVertices[dg.mVertIndex];
|
dg.transform = shape->transform;
|
||||||
for ( int i=0; i<dg.mVertCount; i++ )
|
dg.transform.Cells[0][2] += offset.X;
|
||||||
Set(&ptr[i], shape->mTransformedVertices[i].X, shape->mTransformedVertices[i].Y, 0, shape->mCoords[i].X, shape->mCoords[i].Y, vertexcolor);
|
dg.transform.Cells[1][2] += offset.Y;
|
||||||
dg.mIndexIndex = mIndices.Size();
|
dg.shape2D = shape;
|
||||||
dg.mIndexCount += shape->mIndices.Size();
|
dg.shape2DIndexCount = shape->mIndices.Size();
|
||||||
for ( int i=0; i<int(shape->mIndices.Size()); i+=3 )
|
if (shape->needsVertexUpload)
|
||||||
{
|
{
|
||||||
// [MK] bail out if any indices are out of bounds
|
shape->bufIndex += 1;
|
||||||
for ( int j=0; j<3; j++ )
|
|
||||||
|
shape->buffers.Reserve(1);
|
||||||
|
auto buf = &shape->buffers[shape->bufIndex];
|
||||||
|
|
||||||
|
auto verts = TArray<TwoDVertex>(dg.mVertCount, true);
|
||||||
|
for ( int i=0; i<dg.mVertCount; i++ )
|
||||||
|
verts[i].Set(shape->mVertices[i].X, shape->mVertices[i].Y, 0, shape->mCoords[i].X, shape->mCoords[i].Y, vertexcolor);
|
||||||
|
|
||||||
|
for ( int i=0; i<int(shape->mIndices.Size()); i+=3 )
|
||||||
{
|
{
|
||||||
if ( shape->mIndices[i+j] < 0 )
|
// [MK] bail out if any indices are out of bounds
|
||||||
ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Triangle %u index %u is negative: %i\n", i/3, j, shape->mIndices[i+j]);
|
for ( int j=0; j<3; j++ )
|
||||||
if ( shape->mIndices[i+j] >= dg.mVertCount )
|
{
|
||||||
ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Triangle %u index %u: %u, max: %u\n", i/3, j, shape->mIndices[i+j], dg.mVertCount-1);
|
if ( shape->mIndices[i+j] < 0 )
|
||||||
|
ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Triangle %u index %u is negative: %i\n", i/3, j, shape->mIndices[i+j]);
|
||||||
|
if ( shape->mIndices[i+j] >= dg.mVertCount )
|
||||||
|
ThrowAbortException(X_ARRAY_OUT_OF_BOUNDS, "Triangle %u index %u: %u, max: %u\n", i/3, j, shape->mIndices[i+j], dg.mVertCount-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
AddIndices(dg.mVertIndex, 3, shape->mIndices[i], shape->mIndices[i+1], shape->mIndices[i+2]);
|
|
||||||
|
buf->UploadData(&verts[0], dg.mVertCount, &shape->mIndices[0], shape->mIndices.Size());
|
||||||
|
shape->needsVertexUpload = false;
|
||||||
}
|
}
|
||||||
|
dg.shape2DBufIndex = shape->bufIndex;
|
||||||
AddCommand(&dg);
|
AddCommand(&dg);
|
||||||
offset = osave;
|
offset = osave;
|
||||||
}
|
}
|
||||||
|
@ -1014,3 +1036,16 @@ void F2DDrawer::Clear()
|
||||||
}
|
}
|
||||||
screenFade = 1.f;
|
screenFade = 1.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
F2DVertexBuffer::F2DVertexBuffer()
|
||||||
|
{
|
||||||
|
mVertexBuffer = screen->CreateVertexBuffer();
|
||||||
|
mIndexBuffer = screen->CreateIndexBuffer();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef __2DDRAWER_H
|
#ifndef __2DDRAWER_H
|
||||||
#define __2DDRAWER_H
|
#define __2DDRAWER_H
|
||||||
|
|
||||||
|
#include "buffers.h"
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
#include "vectors.h"
|
#include "vectors.h"
|
||||||
#include "textures.h"
|
#include "textures.h"
|
||||||
|
@ -31,6 +32,8 @@ enum EClearWhich
|
||||||
C_Indices = 4,
|
C_Indices = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class F2DVertexBuffer;
|
||||||
|
|
||||||
class DShape2D : public DObject
|
class DShape2D : public DObject
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -45,12 +48,16 @@ public:
|
||||||
TArray<DVector2> mVertices;
|
TArray<DVector2> mVertices;
|
||||||
TArray<DVector2> mCoords;
|
TArray<DVector2> mCoords;
|
||||||
|
|
||||||
|
double minx = 0.0;
|
||||||
|
double maxx = 0.0;
|
||||||
|
double miny = 0.0;
|
||||||
|
double maxy = 0.0;
|
||||||
|
|
||||||
DMatrix3x3 transform;
|
DMatrix3x3 transform;
|
||||||
|
|
||||||
// dirty stores whether we need to re-apply the transformation
|
TArray<F2DVertexBuffer> buffers;
|
||||||
// otherwise it uses the cached values
|
bool needsVertexUpload = true;
|
||||||
bool dirty = true;
|
int bufIndex = -1;
|
||||||
TArray<DVector2> mTransformedVertices;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct F2DPolygons
|
struct F2DPolygons
|
||||||
|
@ -67,6 +74,7 @@ struct F2DPolygons
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class F2DDrawer
|
class F2DDrawer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -136,6 +144,13 @@ public:
|
||||||
uint8_t mLightLevel;
|
uint8_t mLightLevel;
|
||||||
uint8_t mFlags;
|
uint8_t mFlags;
|
||||||
|
|
||||||
|
bool useTransform;
|
||||||
|
DMatrix3x3 transform;
|
||||||
|
|
||||||
|
DShape2D* shape2D;
|
||||||
|
int shape2DBufIndex;
|
||||||
|
int shape2DIndexCount;
|
||||||
|
|
||||||
RenderCommand()
|
RenderCommand()
|
||||||
{
|
{
|
||||||
memset(this, 0, sizeof(*this));
|
memset(this, 0, sizeof(*this));
|
||||||
|
@ -144,6 +159,7 @@ public:
|
||||||
// If these fields match, two draw commands can be batched.
|
// If these fields match, two draw commands can be batched.
|
||||||
bool isCompatible(const RenderCommand &other) const
|
bool isCompatible(const RenderCommand &other) const
|
||||||
{
|
{
|
||||||
|
if (shape2D != nullptr || other.shape2D != nullptr) return false;
|
||||||
return mTexture == other.mTexture &&
|
return mTexture == other.mTexture &&
|
||||||
mType == other.mType &&
|
mType == other.mType &&
|
||||||
mTranslationId == other.mTranslationId &&
|
mTranslationId == other.mTranslationId &&
|
||||||
|
@ -155,8 +171,16 @@ public:
|
||||||
mDrawMode == other.mDrawMode &&
|
mDrawMode == other.mDrawMode &&
|
||||||
mFlags == other.mFlags &&
|
mFlags == other.mFlags &&
|
||||||
mLightLevel == other.mLightLevel &&
|
mLightLevel == other.mLightLevel &&
|
||||||
mColor1.d == other.mColor1.d;
|
mColor1.d == other.mColor1.d &&
|
||||||
|
useTransform == other.useTransform &&
|
||||||
|
(
|
||||||
|
!useTransform ||
|
||||||
|
(
|
||||||
|
transform[0] == other.transform[0] &&
|
||||||
|
transform[1] == other.transform[1] &&
|
||||||
|
transform[2] == other.transform[2]
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -238,5 +262,39 @@ public:
|
||||||
bool mIsFirstPass = true;
|
bool mIsFirstPass = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// Vertex buffer for 2D drawer
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
class F2DVertexBuffer
|
||||||
|
{
|
||||||
|
IVertexBuffer *mVertexBuffer;
|
||||||
|
IIndexBuffer *mIndexBuffer;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
F2DVertexBuffer();
|
||||||
|
|
||||||
|
~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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1304,7 +1304,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
||||||
if(AL.EXT_source_distance_model)
|
if(AL.EXT_source_distance_model)
|
||||||
alSourcei(source, AL_DISTANCE_MODEL, AL_INVERSE_DISTANCE);
|
alSourcei(source, AL_DISTANCE_MODEL, AL_INVERSE_DISTANCE);
|
||||||
alSourcef(source, AL_REFERENCE_DISTANCE, rolloff->MinDistance/distscale);
|
alSourcef(source, AL_REFERENCE_DISTANCE, rolloff->MinDistance/distscale);
|
||||||
alSourcef(source, AL_MAX_DISTANCE, (1000.f+rolloff->MinDistance)/distscale);
|
alSourcef(source, AL_MAX_DISTANCE, std::numeric_limits<float>::max());
|
||||||
alSourcef(source, AL_ROLLOFF_FACTOR, rolloff->RolloffFactor);
|
alSourcef(source, AL_ROLLOFF_FACTOR, rolloff->RolloffFactor);
|
||||||
manualRolloff = false;
|
manualRolloff = false;
|
||||||
}
|
}
|
||||||
|
@ -1324,77 +1324,49 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
||||||
// when AL_EXT_source_distance_model is not supported, we have to play
|
// when AL_EXT_source_distance_model is not supported, we have to play
|
||||||
// around a bit to get appropriate distance attenation. What we do is
|
// around a bit to get appropriate distance attenation. What we do is
|
||||||
// calculate the attenuation that should be applied, then given an
|
// calculate the attenuation that should be applied, then given an
|
||||||
// Inverse Distance rolloff model with OpenAL, reverse the calculation
|
// Inverse Distance rolloff model with OpenAL, calculate the reference
|
||||||
// to get the distance needed for that much attenuation. The Inverse
|
// distance that will achieve that much attenuation with the current
|
||||||
// Distance calculation is:
|
// distance. The Inverse Distance calculation is:
|
||||||
//
|
//
|
||||||
// Gain = MinDist / (MinDist + RolloffFactor*(Distance - MinDist))
|
// Gain = MinDist / (MinDist + RolloffFactor*(Distance - MinDist))
|
||||||
//
|
//
|
||||||
// Thus, the reverse is:
|
// Simplifying for RolloffFactor=1, it can be broken down by:
|
||||||
//
|
//
|
||||||
// Distance = (MinDist/Gain - MinDist)/RolloffFactor + MinDist
|
// Gain = MinDist / (MinDist + (Distance - MinDist))
|
||||||
|
// Gain = MinDist / Distance
|
||||||
|
// Gain * Distance = MinDist
|
||||||
//
|
//
|
||||||
// This can be simplified by using a MinDist and RolloffFactor of 1,
|
// The source's reference distance is then set according to the desired
|
||||||
// which makes it:
|
// gain and effective distance from the listener, and OpenAL takes care
|
||||||
//
|
// of the rest.
|
||||||
// Distance = 1.0f/Gain;
|
|
||||||
//
|
|
||||||
// The source position is then set that many units away from the
|
|
||||||
// listener position, and OpenAL takes care of the rest.
|
|
||||||
if(AL.EXT_source_distance_model)
|
if(AL.EXT_source_distance_model)
|
||||||
alSourcei(source, AL_DISTANCE_MODEL, AL_INVERSE_DISTANCE);
|
alSourcei(source, AL_DISTANCE_MODEL, AL_INVERSE_DISTANCE);
|
||||||
alSourcef(source, AL_REFERENCE_DISTANCE, 1.f);
|
|
||||||
alSourcef(source, AL_MAX_DISTANCE, 100000.f);
|
float dist = sqrtf(dist_sqr);
|
||||||
|
float gain = GetRolloff(rolloff, dist * distscale);
|
||||||
|
// Don't let the ref distance go to 0, or else distance attenuation is
|
||||||
|
// lost with the inverse distance model.
|
||||||
|
alSourcef(source, AL_REFERENCE_DISTANCE, std::max<float>(gain*dist, 0.0004f));
|
||||||
|
alSourcef(source, AL_MAX_DISTANCE, std::numeric_limits<float>::max());
|
||||||
alSourcef(source, AL_ROLLOFF_FACTOR, 1.f);
|
alSourcef(source, AL_ROLLOFF_FACTOR, 1.f);
|
||||||
|
}
|
||||||
|
|
||||||
if(AL.EXT_SOURCE_RADIUS)
|
if(dist_sqr < (0.0004f*0.0004f))
|
||||||
{
|
{
|
||||||
/* Since the OpenAL distance is decoupled from the sound's distance, get the OpenAL
|
// Head relative
|
||||||
* distance that corresponds to the area radius. */
|
alSourcei(source, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||||
float gain = GetRolloff(rolloff, AREA_SOUND_RADIUS);
|
alSource3f(source, AL_POSITION, 0.f, 0.f, 0.f);
|
||||||
alSourcef(source, AL_SOURCE_RADIUS, (chanflags&SNDF_AREA) ?
|
|
||||||
// Clamp in case the max distance is <= the area radius
|
|
||||||
((gain > 0.00001f) ? 1.f/gain : 100000.f) : 0.f
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dist_sqr < (0.0004f*0.0004f))
|
|
||||||
{
|
|
||||||
// Head relative
|
|
||||||
alSourcei(source, AL_SOURCE_RELATIVE, AL_TRUE);
|
|
||||||
alSource3f(source, AL_POSITION, 0.f, 0.f, 0.f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float gain = GetRolloff(rolloff, sqrtf(dist_sqr) * distscale);
|
|
||||||
FVector3 dir = pos - listener->position;
|
|
||||||
dir.MakeResize((gain > 0.00001f) ? 1.f/gain : 100000.f);
|
|
||||||
dir += listener->position;
|
|
||||||
|
|
||||||
alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE);
|
|
||||||
alSource3f(source, AL_POSITION, dir[0], dir[1], -dir[2]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(AL.EXT_SOURCE_RADIUS)
|
alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||||
alSourcef(source, AL_SOURCE_RADIUS, (chanflags&SNDF_AREA) ? AREA_SOUND_RADIUS : 0.f);
|
alSource3f(source, AL_POSITION, pos[0], pos[1], -pos[2]);
|
||||||
|
|
||||||
if(dist_sqr < (0.0004f*0.0004f))
|
|
||||||
{
|
|
||||||
// Head relative
|
|
||||||
alSourcei(source, AL_SOURCE_RELATIVE, AL_TRUE);
|
|
||||||
alSource3f(source, AL_POSITION, 0.f, 0.f, 0.f);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE);
|
|
||||||
alSource3f(source, AL_POSITION, pos[0], pos[1], -pos[2]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
alSource3f(source, AL_VELOCITY, vel[0], vel[1], -vel[2]);
|
alSource3f(source, AL_VELOCITY, vel[0], vel[1], -vel[2]);
|
||||||
alSource3f(source, AL_DIRECTION, 0.f, 0.f, 0.f);
|
alSource3f(source, AL_DIRECTION, 0.f, 0.f, 0.f);
|
||||||
alSourcef(source, AL_DOPPLER_FACTOR, 0.f);
|
alSourcef(source, AL_DOPPLER_FACTOR, 0.f);
|
||||||
|
if(AL.EXT_SOURCE_RADIUS)
|
||||||
|
alSourcef(source, AL_SOURCE_RADIUS, (chanflags&SNDF_AREA) ? AREA_SOUND_RADIUS : 0.f);
|
||||||
|
|
||||||
alSourcei(source, AL_LOOPING, (chanflags&SNDF_LOOP) ? AL_TRUE : AL_FALSE);
|
alSourcei(source, AL_LOOPING, (chanflags&SNDF_LOOP) ? AL_TRUE : AL_FALSE);
|
||||||
|
|
||||||
|
@ -1633,8 +1605,7 @@ void OpenALSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FISoundCh
|
||||||
if(chan == NULL || chan->SysChannel == NULL)
|
if(chan == NULL || chan->SysChannel == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
FVector3 dir = pos - listener->position;
|
float dist_sqr = (float)(pos - listener->position).LengthSquared();
|
||||||
float dist_sqr = (float)dir.LengthSquared();
|
|
||||||
chan->DistanceSqr = dist_sqr;
|
chan->DistanceSqr = dist_sqr;
|
||||||
|
|
||||||
alDeferUpdatesSOFT();
|
alDeferUpdatesSOFT();
|
||||||
|
@ -1649,13 +1620,13 @@ void OpenALSoundRenderer::UpdateSoundParams3D(SoundListener *listener, FISoundCh
|
||||||
{
|
{
|
||||||
if(chan->ManualRolloff)
|
if(chan->ManualRolloff)
|
||||||
{
|
{
|
||||||
float gain = GetRolloff(&chan->Rolloff, sqrtf(dist_sqr)*chan->DistanceScale);
|
float dist = sqrtf(dist_sqr);
|
||||||
dir.MakeResize((gain > 0.00001f) ? 1.f/gain : 100000.f);
|
float gain = GetRolloff(&chan->Rolloff, dist * chan->DistanceScale);
|
||||||
|
alSourcef(source, AL_REFERENCE_DISTANCE, std::max<float>(gain*dist, 0.0004f));
|
||||||
}
|
}
|
||||||
dir += listener->position;
|
|
||||||
|
|
||||||
alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE);
|
alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||||
alSource3f(source, AL_POSITION, dir[0], dir[1], -dir[2]);
|
alSource3f(source, AL_POSITION, pos[0], pos[1], -pos[2]);
|
||||||
}
|
}
|
||||||
alSource3f(source, AL_VELOCITY, vel[0], vel[1], -vel[2]);
|
alSource3f(source, AL_VELOCITY, vel[0], vel[1], -vel[2]);
|
||||||
getALError();
|
getALError();
|
||||||
|
|
|
@ -27,6 +27,10 @@ xx(Spray)
|
||||||
xx(Ghost)
|
xx(Ghost)
|
||||||
xx(Reflective)
|
xx(Reflective)
|
||||||
|
|
||||||
|
// Iron Feet types
|
||||||
|
//xx(Normal) // defined below
|
||||||
|
xx(Full)
|
||||||
|
|
||||||
// Invisibility types
|
// Invisibility types
|
||||||
xx(Additive)
|
xx(Additive)
|
||||||
xx(Cumulative)
|
xx(Cumulative)
|
||||||
|
|
|
@ -637,7 +637,8 @@ bool M_Responder (event_t *ev)
|
||||||
{
|
{
|
||||||
// We do our own key repeat handling but still want to eat the
|
// We do our own key repeat handling but still want to eat the
|
||||||
// OS's repeated keys.
|
// OS's repeated keys.
|
||||||
return true;
|
if (CurrentMenu->TranslateKeyboardEvents()) return true;
|
||||||
|
else return CurrentMenu->CallResponder(ev);
|
||||||
}
|
}
|
||||||
else if (ev->subtype == EV_GUI_BackButtonDown || ev->subtype == EV_GUI_BackButtonUp)
|
else if (ev->subtype == EV_GUI_BackButtonDown || ev->subtype == EV_GUI_BackButtonUp)
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
#include <new>
|
#include <new>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
#include "engineerrors.h"
|
#include "engineerrors.h"
|
||||||
#include "m_argv.h"
|
#include "m_argv.h"
|
||||||
|
@ -49,6 +51,7 @@
|
||||||
#include "engineerrors.h"
|
#include "engineerrors.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "i_interface.h"
|
#include "i_interface.h"
|
||||||
|
#include "printf.h"
|
||||||
|
|
||||||
// MACROS ------------------------------------------------------------------
|
// MACROS ------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -93,7 +96,50 @@ static int GetCrashInfo (char *buffer, char *end)
|
||||||
|
|
||||||
void I_DetectOS()
|
void I_DetectOS()
|
||||||
{
|
{
|
||||||
// The POSIX version never implemented this.
|
FString operatingSystem;
|
||||||
|
|
||||||
|
const char *paths[] = {"/etc/os-release", "/usr/lib/os-release"};
|
||||||
|
|
||||||
|
for (const char *path : paths)
|
||||||
|
{
|
||||||
|
struct stat dummy;
|
||||||
|
|
||||||
|
if (stat(path, &dummy) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
char cmdline[256];
|
||||||
|
snprintf(cmdline, sizeof cmdline, ". %s && echo ${PRETTY_NAME}", path);
|
||||||
|
|
||||||
|
FILE *proc = popen(cmdline, "r");
|
||||||
|
|
||||||
|
if (proc == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
char distribution[256] = {};
|
||||||
|
fread(distribution, sizeof distribution - 1, 1, proc);
|
||||||
|
|
||||||
|
const size_t length = strlen(distribution);
|
||||||
|
|
||||||
|
if (length > 1)
|
||||||
|
{
|
||||||
|
distribution[length - 1] = '\0';
|
||||||
|
operatingSystem = distribution;
|
||||||
|
}
|
||||||
|
|
||||||
|
pclose(proc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
utsname unameInfo;
|
||||||
|
|
||||||
|
if (uname(&unameInfo) == 0)
|
||||||
|
{
|
||||||
|
const char* const separator = operatingSystem.Len() > 0 ? ", " : "";
|
||||||
|
operatingSystem.AppendFormat("%s%s %s on %s", separator, unameInfo.sysname, unameInfo.release, unameInfo.machine);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operatingSystem.Len() > 0)
|
||||||
|
Printf("OS: %s\n", operatingSystem.GetChars());
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_StartupJoysticks();
|
void I_StartupJoysticks();
|
||||||
|
|
|
@ -90,7 +90,7 @@ private:
|
||||||
|
|
||||||
bool QuadStereoCheckInitialRenderContextState();
|
bool QuadStereoCheckInitialRenderContextState();
|
||||||
void PresentAnaglyph(bool r, bool g, bool b);
|
void PresentAnaglyph(bool r, bool g, bool b);
|
||||||
void PresentSideBySide();
|
void PresentSideBySide(int);
|
||||||
void PresentTopBottom();
|
void PresentTopBottom();
|
||||||
void prepareInterleavedPresent(FPresentShaderBase& shader);
|
void prepareInterleavedPresent(FPresentShaderBase& shader);
|
||||||
void PresentColumnInterleaved();
|
void PresentColumnInterleaved();
|
||||||
|
|
|
@ -76,25 +76,59 @@ void FGLRenderer::PresentAnaglyph(bool r, bool g, bool b)
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
void FGLRenderer::PresentSideBySide()
|
void FGLRenderer::PresentSideBySide(int vrmode)
|
||||||
{
|
{
|
||||||
mBuffers->BindOutputFB();
|
if (vrmode == VR_SIDEBYSIDEFULL || vrmode == VR_SIDEBYSIDESQUISHED)
|
||||||
ClearBorders();
|
{
|
||||||
|
mBuffers->BindOutputFB();
|
||||||
|
ClearBorders();
|
||||||
|
|
||||||
// Compute screen regions to use for left and right eye views
|
// Compute screen regions to use for left and right eye views
|
||||||
int leftWidth = screen->mOutputLetterbox.width / 2;
|
int leftWidth = screen->mOutputLetterbox.width / 2;
|
||||||
int rightWidth = screen->mOutputLetterbox.width - leftWidth;
|
int rightWidth = screen->mOutputLetterbox.width - leftWidth;
|
||||||
IntRect leftHalfScreen = screen->mOutputLetterbox;
|
IntRect leftHalfScreen = screen->mOutputLetterbox;
|
||||||
leftHalfScreen.width = leftWidth;
|
leftHalfScreen.width = leftWidth;
|
||||||
IntRect rightHalfScreen = screen->mOutputLetterbox;
|
IntRect rightHalfScreen = screen->mOutputLetterbox;
|
||||||
rightHalfScreen.width = rightWidth;
|
rightHalfScreen.width = rightWidth;
|
||||||
rightHalfScreen.left += leftWidth;
|
rightHalfScreen.left += leftWidth;
|
||||||
|
|
||||||
mBuffers->BindEyeTexture(0, 0);
|
mBuffers->BindEyeTexture(0, 0);
|
||||||
DrawPresentTexture(leftHalfScreen, true);
|
DrawPresentTexture(leftHalfScreen, true);
|
||||||
|
|
||||||
mBuffers->BindEyeTexture(1, 0);
|
mBuffers->BindEyeTexture(1, 0);
|
||||||
DrawPresentTexture(rightHalfScreen, true);
|
DrawPresentTexture(rightHalfScreen, true);
|
||||||
|
}
|
||||||
|
else if (vrmode == VR_SIDEBYSIDELETTERBOX)
|
||||||
|
{
|
||||||
|
mBuffers->BindOutputFB();
|
||||||
|
screen->mOutputLetterbox.top = screen->mOutputLetterbox.height;
|
||||||
|
|
||||||
|
ClearBorders();
|
||||||
|
screen->mOutputLetterbox.top = 0; //reset so screenshots can be taken
|
||||||
|
|
||||||
|
// Compute screen regions to use for left and right eye views
|
||||||
|
int leftWidth = screen->mOutputLetterbox.width / 2;
|
||||||
|
int rightWidth = screen->mOutputLetterbox.width - leftWidth;
|
||||||
|
//cut letterbox height in half
|
||||||
|
int height = screen->mOutputLetterbox.height / 2;
|
||||||
|
int top = height * .5;
|
||||||
|
IntRect leftHalfScreen = screen->mOutputLetterbox;
|
||||||
|
leftHalfScreen.width = leftWidth;
|
||||||
|
leftHalfScreen.height = height;
|
||||||
|
leftHalfScreen.top = top;
|
||||||
|
IntRect rightHalfScreen = screen->mOutputLetterbox;
|
||||||
|
rightHalfScreen.width = rightWidth;
|
||||||
|
rightHalfScreen.left += leftWidth;
|
||||||
|
//give it those cinematic black bars on top and bottom
|
||||||
|
rightHalfScreen.height = height;
|
||||||
|
rightHalfScreen.top = top;
|
||||||
|
|
||||||
|
mBuffers->BindEyeTexture(0, 0);
|
||||||
|
DrawPresentTexture(leftHalfScreen, true);
|
||||||
|
|
||||||
|
mBuffers->BindEyeTexture(1, 0);
|
||||||
|
DrawPresentTexture(rightHalfScreen, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -360,7 +394,8 @@ void FGLRenderer::PresentStereo()
|
||||||
|
|
||||||
case VR_SIDEBYSIDEFULL:
|
case VR_SIDEBYSIDEFULL:
|
||||||
case VR_SIDEBYSIDESQUISHED:
|
case VR_SIDEBYSIDESQUISHED:
|
||||||
PresentSideBySide();
|
case VR_SIDEBYSIDELETTERBOX:
|
||||||
|
PresentSideBySide(vr_mode);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VR_TOPBOTTOM:
|
case VR_TOPBOTTOM:
|
||||||
|
|
|
@ -73,6 +73,7 @@ const VRMode *VRMode::GetVRMode(bool toscreen)
|
||||||
case VR_REDCYAN:
|
case VR_REDCYAN:
|
||||||
case VR_QUADSTEREO:
|
case VR_QUADSTEREO:
|
||||||
case VR_AMBERBLUE:
|
case VR_AMBERBLUE:
|
||||||
|
case VR_SIDEBYSIDELETTERBOX:
|
||||||
return &vrmi_stereo;
|
return &vrmi_stereo;
|
||||||
|
|
||||||
case VR_SIDEBYSIDESQUISHED:
|
case VR_SIDEBYSIDESQUISHED:
|
||||||
|
|
|
@ -14,6 +14,7 @@ enum
|
||||||
VR_LEFTEYEVIEW = 5,
|
VR_LEFTEYEVIEW = 5,
|
||||||
VR_RIGHTEYEVIEW = 6,
|
VR_RIGHTEYEVIEW = 6,
|
||||||
VR_QUADSTEREO = 7,
|
VR_QUADSTEREO = 7,
|
||||||
|
VR_SIDEBYSIDELETTERBOX = 8,
|
||||||
VR_AMBERBLUE = 9,
|
VR_AMBERBLUE = 9,
|
||||||
VR_TOPBOTTOM = 11,
|
VR_TOPBOTTOM = 11,
|
||||||
VR_ROWINTERLEAVED = 12,
|
VR_ROWINTERLEAVED = 12,
|
||||||
|
|
|
@ -43,51 +43,6 @@
|
||||||
#include "r_videoscale.h"
|
#include "r_videoscale.h"
|
||||||
#include "v_draw.h"
|
#include "v_draw.h"
|
||||||
|
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// Vertex buffer for 2D drawer
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
class F2DVertexBuffer
|
|
||||||
{
|
|
||||||
IVertexBuffer *mVertexBuffer;
|
|
||||||
IIndexBuffer *mIndexBuffer;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
F2DVertexBuffer()
|
|
||||||
{
|
|
||||||
mVertexBuffer = screen->CreateVertexBuffer();
|
|
||||||
mIndexBuffer = screen->CreateIndexBuffer();
|
|
||||||
|
|
||||||
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.
|
// Draws the 2D stuff. This is the version for OpenGL 3 and later.
|
||||||
|
@ -174,6 +129,29 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state)
|
||||||
|
|
||||||
state.AlphaFunc(Alpha_GEqual, 0.f);
|
state.AlphaFunc(Alpha_GEqual, 0.f);
|
||||||
|
|
||||||
|
if (cmd.useTransform)
|
||||||
|
{
|
||||||
|
FLOATTYPE m[16] = {
|
||||||
|
0.0, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 1.0, 0.0,
|
||||||
|
0.0, 0.0, 0.0, 1.0
|
||||||
|
};
|
||||||
|
for (size_t i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
for (size_t j = 0; j < 2; j++)
|
||||||
|
{
|
||||||
|
m[4 * j + i] = (FLOATTYPE) cmd.transform.Cells[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
m[4 * 3 + i] = (FLOATTYPE) cmd.transform.Cells[i][2];
|
||||||
|
}
|
||||||
|
state.mModelMatrix.loadMatrix(m);
|
||||||
|
state.EnableModelMatrix(true);
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd.mTexture != nullptr && cmd.mTexture->isValid())
|
if (cmd.mTexture != nullptr && cmd.mTexture->isValid())
|
||||||
{
|
{
|
||||||
auto flags = cmd.mTexture->GetUseType() >= ETextureType::Special? UF_None : cmd.mTexture->GetUseType() == ETextureType::FontChar? UF_Font : UF_Texture;
|
auto flags = cmd.mTexture->GetUseType() >= ETextureType::Special? UF_None : cmd.mTexture->GetUseType() == ETextureType::FontChar? UF_Font : UF_Texture;
|
||||||
|
@ -200,26 +178,42 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state)
|
||||||
state.EnableTexture(false);
|
state.EnableTexture(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (cmd.mType)
|
if (cmd.shape2D != nullptr)
|
||||||
{
|
{
|
||||||
default:
|
state.SetVertexBuffer(&cmd.shape2D->buffers[cmd.shape2DBufIndex]);
|
||||||
case F2DDrawer::DrawTypeTriangles:
|
state.DrawIndexed(DT_Triangles, 0, cmd.shape2DIndexCount);
|
||||||
state.DrawIndexed(DT_Triangles, cmd.mIndexIndex, cmd.mIndexCount);
|
state.SetVertexBuffer(&vb);
|
||||||
break;
|
if (cmd.shape2D->bufIndex > 0 && cmd.shape2DBufIndex == cmd.shape2D->bufIndex)
|
||||||
|
{
|
||||||
|
cmd.shape2D->needsVertexUpload = true;
|
||||||
|
cmd.shape2D->buffers.Clear();
|
||||||
|
cmd.shape2D->bufIndex = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (cmd.mType)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
case F2DDrawer::DrawTypeTriangles:
|
||||||
|
state.DrawIndexed(DT_Triangles, cmd.mIndexIndex, cmd.mIndexCount);
|
||||||
|
break;
|
||||||
|
|
||||||
case F2DDrawer::DrawTypeLines:
|
case F2DDrawer::DrawTypeLines:
|
||||||
state.Draw(DT_Lines, cmd.mVertIndex, cmd.mVertCount);
|
state.Draw(DT_Lines, cmd.mVertIndex, cmd.mVertCount);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case F2DDrawer::DrawTypePoints:
|
case F2DDrawer::DrawTypePoints:
|
||||||
state.Draw(DT_Points, cmd.mVertIndex, cmd.mVertCount);
|
state.Draw(DT_Points, cmd.mVertIndex, cmd.mVertCount);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
state.SetObjectColor(0xffffffff);
|
state.SetObjectColor(0xffffffff);
|
||||||
state.SetObjectColor2(0);
|
state.SetObjectColor2(0);
|
||||||
state.SetAddColor(0);
|
state.SetAddColor(0);
|
||||||
state.EnableTextureMatrix(false);
|
state.EnableTextureMatrix(false);
|
||||||
|
state.EnableModelMatrix(false);
|
||||||
state.SetEffect(EFF_NONE);
|
state.SetEffect(EFF_NONE);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,7 +144,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VkDescriptorSetLayoutCreateInfo layoutInfo = {};
|
VkDescriptorSetLayoutCreateInfo layoutInfo = {};
|
||||||
FixedSizeVector<VkDescriptorSetLayoutBinding, 8> bindings;
|
TArray<VkDescriptorSetLayoutBinding> bindings;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DescriptorPoolBuilder
|
class DescriptorPoolBuilder
|
||||||
|
@ -636,10 +636,10 @@ inline void DescriptorSetLayoutBuilder::addBinding(int index, VkDescriptorType t
|
||||||
binding.descriptorCount = arrayCount;
|
binding.descriptorCount = arrayCount;
|
||||||
binding.stageFlags = stageFlags;
|
binding.stageFlags = stageFlags;
|
||||||
binding.pImmutableSamplers = nullptr;
|
binding.pImmutableSamplers = nullptr;
|
||||||
bindings.push_back(binding);
|
bindings.Push(binding);
|
||||||
|
|
||||||
layoutInfo.bindingCount = (uint32_t)bindings.size();
|
layoutInfo.bindingCount = (uint32_t)bindings.Size();
|
||||||
layoutInfo.pBindings = bindings.data();
|
layoutInfo.pBindings = &bindings[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::unique_ptr<VulkanDescriptorSetLayout> DescriptorSetLayoutBuilder::create(VulkanDevice *device)
|
inline std::unique_ptr<VulkanDescriptorSetLayout> DescriptorSetLayoutBuilder::create(VulkanDevice *device)
|
||||||
|
|
|
@ -9014,7 +9014,6 @@ FxExpression *FxFlopFunctionCall::Resolve(FCompileContext& ctx)
|
||||||
|
|
||||||
ExpEmit FxFlopFunctionCall::Emit(VMFunctionBuilder *build)
|
ExpEmit FxFlopFunctionCall::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
assert(ValueType == ArgList[0]->ValueType);
|
|
||||||
ExpEmit from = ArgList[0]->Emit(build);
|
ExpEmit from = ArgList[0]->Emit(build);
|
||||||
ExpEmit to;
|
ExpEmit to;
|
||||||
assert(from.Konst == 0);
|
assert(from.Konst == 0);
|
||||||
|
|
|
@ -451,7 +451,7 @@ PInt::PInt(unsigned int size, bool unsign, bool compatible)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Symbols.AddSymbol(Create<PSymbolConstNumeric>(NAME_Min, this, 0u));
|
Symbols.AddSymbol(Create<PSymbolConstNumeric>(NAME_Min, this, 0u));
|
||||||
Symbols.AddSymbol(Create<PSymbolConstNumeric>(NAME_Max, this, (1u << ((8 * size) - 1))));
|
Symbols.AddSymbol(Create<PSymbolConstNumeric>(NAME_Max, this, (uint32_t) (((uint64_t) 1u << (size * 8)) - 1uL)));
|
||||||
}
|
}
|
||||||
SetOps();
|
SetOps();
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret)
|
static int ExecScriptFunc(VMFrameStack *stack, VMReturn *ret, int numret)
|
||||||
{
|
{
|
||||||
#if COMPGOTO
|
#if COMPGOTO
|
||||||
static const void * const ops[256] =
|
static void * const ops[256] =
|
||||||
{
|
{
|
||||||
#define xx(op,sym,mode,alt,kreg,ktype) &&op,
|
#define xx(op,sym,mode,alt,kreg,ktype) &&op,
|
||||||
#include "vmops.h"
|
#include "vmops.h"
|
||||||
|
|
|
@ -590,7 +590,7 @@ int strbin (char *str)
|
||||||
while ( (c = *p++) ) {
|
while ( (c = *p++) ) {
|
||||||
if (c != '\\') {
|
if (c != '\\') {
|
||||||
*str++ = c;
|
*str++ = c;
|
||||||
} else {
|
} else if (*p != 0) {
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case 'a':
|
case 'a':
|
||||||
*str++ = '\a';
|
*str++ = '\a';
|
||||||
|
@ -693,7 +693,7 @@ FString strbin1 (const char *start)
|
||||||
while ( (c = *p++) ) {
|
while ( (c = *p++) ) {
|
||||||
if (c != '\\') {
|
if (c != '\\') {
|
||||||
result << c;
|
result << c;
|
||||||
} else {
|
} else if (*p) {
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case 'a':
|
case 'a':
|
||||||
result << '\a';
|
result << '\a';
|
||||||
|
|
Loading…
Reference in a new issue