mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-12-13 13:50:59 +00:00
- hook up main.vp and the data it uses for input
This commit is contained in:
parent
fbaeb11fba
commit
3a3de13abd
10 changed files with 411 additions and 230 deletions
|
@ -83,29 +83,14 @@ void PolyVertexBuffer::SetFormat(int numBindingPoints, int numAttributes, size_t
|
||||||
mStride = stride;
|
mStride = stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShadedTriVertex PolyVertexBuffer::Shade(PolyTriangleThreadData *thread, const PolyDrawArgs &drawargs, const void *vertices, int index)
|
void PolyVertexBuffer::Load(PolyTriangleThreadData *thread, const void *vertices, int index)
|
||||||
{
|
{
|
||||||
const uint8_t *vertex = static_cast<const uint8_t*>(vertices) + mStride * index;
|
const uint8_t *vertex = static_cast<const uint8_t*>(vertices) + mStride * index;
|
||||||
const float *attrVertex = reinterpret_cast<const float*>(vertex + mOffsets[VATTR_VERTEX]);
|
const float *attrVertex = reinterpret_cast<const float*>(vertex + mOffsets[VATTR_VERTEX]);
|
||||||
const float *attrTexcoord = reinterpret_cast<const float*>(vertex + mOffsets[VATTR_TEXCOORD]);
|
const float *attrTexcoord = reinterpret_cast<const float*>(vertex + mOffsets[VATTR_TEXCOORD]);
|
||||||
|
|
||||||
Vec4f objpos = Vec4f(attrVertex[0], attrVertex[1], attrVertex[2], 1.0f);
|
thread->mainVertexShader.aPosition = { attrVertex[0], attrVertex[1], attrVertex[2], 1.0f };
|
||||||
Vec4f clippos = (*thread->objectToClip) * objpos;
|
thread->mainVertexShader.aTexCoord = { attrTexcoord[0], attrTexcoord[1] };
|
||||||
|
|
||||||
ShadedTriVertex sv;
|
|
||||||
sv.u = attrTexcoord[1];
|
|
||||||
sv.v = attrTexcoord[0];
|
|
||||||
sv.x = clippos.X;
|
|
||||||
sv.y = clippos.Y;
|
|
||||||
sv.z = clippos.Z;
|
|
||||||
sv.w = clippos.W;
|
|
||||||
sv.worldX = objpos.X;
|
|
||||||
sv.worldY = objpos.Y;
|
|
||||||
sv.worldZ = objpos.Z;
|
|
||||||
sv.clipDistance[0] = 1.0f;
|
|
||||||
sv.clipDistance[1] = 1.0f;
|
|
||||||
sv.clipDistance[2] = 1.0f;
|
|
||||||
return sv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -39,13 +39,13 @@ private:
|
||||||
std::vector<uint32_t> mData;
|
std::vector<uint32_t> mData;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PolyVertexBuffer : public IVertexBuffer, public PolyBuffer, public PolyVertexShader
|
class PolyVertexBuffer : public IVertexBuffer, public PolyBuffer, public PolyInputAssembly
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PolyVertexBuffer() { }
|
PolyVertexBuffer() { }
|
||||||
void SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) override;
|
void SetFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs) override;
|
||||||
|
|
||||||
ShadedTriVertex Shade(PolyTriangleThreadData *thread, const PolyDrawArgs &drawargs, const void *vertices, int index) override;
|
void Load(PolyTriangleThreadData *thread, const void *vertices, int index) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t mOffsets[VATTR_MAX] = {};
|
size_t mOffsets[VATTR_MAX] = {};
|
||||||
|
|
|
@ -26,6 +26,7 @@ static PolyDrawMode dtToDrawMode[] =
|
||||||
|
|
||||||
PolyRenderState::PolyRenderState()
|
PolyRenderState::PolyRenderState()
|
||||||
{
|
{
|
||||||
|
mIdentityMatrix.loadIdentity();
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,23 +176,71 @@ void PolyRenderState::Apply()
|
||||||
auto fb = GetPolyFrameBuffer();
|
auto fb = GetPolyFrameBuffer();
|
||||||
if (mVertexBuffer) PolyTriangleDrawer::SetVertexBuffer(fb->GetDrawCommands(), mVertexBuffer->Memory());
|
if (mVertexBuffer) PolyTriangleDrawer::SetVertexBuffer(fb->GetDrawCommands(), mVertexBuffer->Memory());
|
||||||
if (mIndexBuffer) PolyTriangleDrawer::SetIndexBuffer(fb->GetDrawCommands(), mIndexBuffer->Memory());
|
if (mIndexBuffer) PolyTriangleDrawer::SetIndexBuffer(fb->GetDrawCommands(), mIndexBuffer->Memory());
|
||||||
PolyTriangleDrawer::SetVertexShader(fb->GetDrawCommands(), static_cast<PolyVertexBuffer*>(mVertexBuffer));
|
PolyTriangleDrawer::SetInputAssembly(fb->GetDrawCommands(), static_cast<PolyVertexBuffer*>(mVertexBuffer));
|
||||||
|
|
||||||
|
ApplyMatrices();
|
||||||
|
|
||||||
|
PolyTriangleDrawer::PushStreamData(fb->GetDrawCommands(), mStreamData, { mClipSplit[0], mClipSplit[1] });
|
||||||
|
|
||||||
PolyTriangleDrawer::SetTwoSided(fb->GetDrawCommands(), true);
|
PolyTriangleDrawer::SetTwoSided(fb->GetDrawCommands(), true);
|
||||||
PolyTriangleDrawer::PushConstants(fb->GetDrawCommands(), args);
|
PolyTriangleDrawer::PushConstants(fb->GetDrawCommands(), args);
|
||||||
|
|
||||||
drawcalls.Unclock();
|
drawcalls.Unclock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static void BufferedSet(bool &modified, T &dst, const T &src)
|
||||||
|
{
|
||||||
|
if (dst == src)
|
||||||
|
return;
|
||||||
|
dst = src;
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BufferedSet(bool &modified, VSMatrix &dst, const VSMatrix &src)
|
||||||
|
{
|
||||||
|
if (memcmp(dst.get(), src.get(), sizeof(FLOATTYPE) * 16) == 0)
|
||||||
|
return;
|
||||||
|
dst = src;
|
||||||
|
modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolyRenderState::ApplyMatrices()
|
||||||
|
{
|
||||||
|
bool modified = mFirstMatrixApply;
|
||||||
|
if (mTextureMatrixEnabled)
|
||||||
|
{
|
||||||
|
BufferedSet(modified, mMatrices.TextureMatrix, mTextureMatrix);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BufferedSet(modified, mMatrices.TextureMatrix, mIdentityMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mModelMatrixEnabled)
|
||||||
|
{
|
||||||
|
BufferedSet(modified, mMatrices.ModelMatrix, mModelMatrix);
|
||||||
|
if (modified)
|
||||||
|
mMatrices.NormalModelMatrix.computeNormalMatrix(mModelMatrix);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BufferedSet(modified, mMatrices.ModelMatrix, mIdentityMatrix);
|
||||||
|
BufferedSet(modified, mMatrices.NormalModelMatrix, mIdentityMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modified)
|
||||||
|
{
|
||||||
|
mFirstMatrixApply = false;
|
||||||
|
PolyTriangleDrawer::PushMatrices(GetPolyFrameBuffer()->GetDrawCommands(), mMatrices.ModelMatrix, mMatrices.NormalModelMatrix, mMatrices.TextureMatrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PolyRenderState::Bind(PolyDataBuffer *buffer, uint32_t offset, uint32_t length)
|
void PolyRenderState::Bind(PolyDataBuffer *buffer, uint32_t offset, uint32_t length)
|
||||||
{
|
{
|
||||||
if (buffer->bindingpoint == VIEWPOINT_BINDINGPOINT)
|
if (buffer->bindingpoint == VIEWPOINT_BINDINGPOINT)
|
||||||
{
|
{
|
||||||
mViewpointUniforms = reinterpret_cast<HWViewpointUniforms*>(static_cast<uint8_t*>(buffer->Memory()) + offset);
|
mViewpointUniforms = reinterpret_cast<HWViewpointUniforms*>(static_cast<uint8_t*>(buffer->Memory()) + offset);
|
||||||
|
PolyTriangleDrawer::SetViewpointUniforms(GetPolyFrameBuffer()->GetDrawCommands(), mViewpointUniforms);
|
||||||
Mat4f viewToProj = Mat4f::FromValues(mViewpointUniforms->mProjectionMatrix.get());
|
|
||||||
Mat4f worldToView = Mat4f::FromValues(mViewpointUniforms->mViewMatrix.get());
|
|
||||||
|
|
||||||
auto fb = GetPolyFrameBuffer();
|
|
||||||
PolyTriangleDrawer::SetTransform(fb->GetDrawCommands(), fb->GetFrameMemory()->NewObject<Mat4f>(viewToProj * worldToView), nullptr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,16 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Apply();
|
void Apply();
|
||||||
|
void ApplyMatrices();
|
||||||
|
|
||||||
|
struct Matrices
|
||||||
|
{
|
||||||
|
VSMatrix ModelMatrix;
|
||||||
|
VSMatrix NormalModelMatrix;
|
||||||
|
VSMatrix TextureMatrix;
|
||||||
|
} mMatrices;
|
||||||
|
VSMatrix mIdentityMatrix;
|
||||||
|
bool mFirstMatrixApply = true;
|
||||||
|
|
||||||
HWViewpointUniforms *mViewpointUniforms = nullptr;
|
HWViewpointUniforms *mViewpointUniforms = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -86,9 +86,9 @@ void PolyTriangleDrawer::SetViewport(const DrawerCommandQueuePtr &queue, int x,
|
||||||
queue->Push<PolySetViewportCommand>(viewport_x, viewport_y, viewport_width, viewport_height, dest, dest_width, dest_height, dest_pitch, dest_bgra);
|
queue->Push<PolySetViewportCommand>(viewport_x, viewport_y, viewport_width, viewport_height, dest, dest_width, dest_height, dest_pitch, dest_bgra);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolyTriangleDrawer::SetVertexShader(const DrawerCommandQueuePtr &queue, PolyVertexShader *shader)
|
void PolyTriangleDrawer::SetInputAssembly(const DrawerCommandQueuePtr &queue, PolyInputAssembly *input)
|
||||||
{
|
{
|
||||||
queue->Push<PolySetVertexShaderCommand>(shader);
|
queue->Push<PolySetInputAssemblyCommand>(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolyTriangleDrawer::SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip, const Mat4f *objectToWorld)
|
void PolyTriangleDrawer::SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip, const Mat4f *objectToWorld)
|
||||||
|
@ -131,6 +131,21 @@ void PolyTriangleDrawer::PushConstants(const DrawerCommandQueuePtr &queue, const
|
||||||
queue->Push<PolyPushConstantsCommand>(args);
|
queue->Push<PolyPushConstantsCommand>(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PolyTriangleDrawer::PushStreamData(const DrawerCommandQueuePtr &queue, const StreamData &data, const Vec2f &uClipSplit)
|
||||||
|
{
|
||||||
|
queue->Push<PolyPushStreamDataCommand>(data, uClipSplit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolyTriangleDrawer::PushMatrices(const DrawerCommandQueuePtr &queue, const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix)
|
||||||
|
{
|
||||||
|
queue->Push<PolyPushMatricesCommand>(modelMatrix, normalModelMatrix, textureMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolyTriangleDrawer::SetViewpointUniforms(const DrawerCommandQueuePtr &queue, const HWViewpointUniforms *uniforms)
|
||||||
|
{
|
||||||
|
queue->Push<PolySetViewpointUniformsCommand>(uniforms);
|
||||||
|
}
|
||||||
|
|
||||||
void PolyTriangleDrawer::Draw(const DrawerCommandQueuePtr &queue, int index, int vcount, PolyDrawMode mode)
|
void PolyTriangleDrawer::Draw(const DrawerCommandQueuePtr &queue, int index, int vcount, PolyDrawMode mode)
|
||||||
{
|
{
|
||||||
queue->Push<PolyDrawCommand>(index, vcount, mode);
|
queue->Push<PolyDrawCommand>(index, vcount, mode);
|
||||||
|
@ -197,8 +212,8 @@ void PolyTriangleThreadData::SetViewport(int x, int y, int width, int height, ui
|
||||||
|
|
||||||
void PolyTriangleThreadData::SetTransform(const Mat4f *newObjectToClip, const Mat4f *newObjectToWorld)
|
void PolyTriangleThreadData::SetTransform(const Mat4f *newObjectToClip, const Mat4f *newObjectToWorld)
|
||||||
{
|
{
|
||||||
objectToClip = newObjectToClip;
|
swVertexShader.objectToClip = newObjectToClip;
|
||||||
objectToWorld = newObjectToWorld;
|
swVertexShader.objectToWorld = newObjectToWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolyTriangleThreadData::PushConstants(const PolyDrawArgs &args)
|
void PolyTriangleThreadData::PushConstants(const PolyDrawArgs &args)
|
||||||
|
@ -206,6 +221,24 @@ void PolyTriangleThreadData::PushConstants(const PolyDrawArgs &args)
|
||||||
drawargs = args;
|
drawargs = args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PolyTriangleThreadData::PushStreamData(const StreamData &data, const Vec2f &uClipSplit)
|
||||||
|
{
|
||||||
|
mainVertexShader.Data = data;
|
||||||
|
mainVertexShader.uClipSplit = uClipSplit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolyTriangleThreadData::PushMatrices(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix)
|
||||||
|
{
|
||||||
|
mainVertexShader.ModelMatrix = modelMatrix;
|
||||||
|
mainVertexShader.NormalModelMatrix = normalModelMatrix;
|
||||||
|
mainVertexShader.TextureMatrix = textureMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolyTriangleThreadData::SetViewpointUniforms(const HWViewpointUniforms *uniforms)
|
||||||
|
{
|
||||||
|
mainVertexShader.Viewpoint = uniforms;
|
||||||
|
}
|
||||||
|
|
||||||
void PolyTriangleThreadData::DrawIndexed(int index, int vcount, PolyDrawMode drawmode)
|
void PolyTriangleThreadData::DrawIndexed(int index, int vcount, PolyDrawMode drawmode)
|
||||||
{
|
{
|
||||||
if (vcount < 3)
|
if (vcount < 3)
|
||||||
|
@ -216,38 +249,41 @@ void PolyTriangleThreadData::DrawIndexed(int index, int vcount, PolyDrawMode dra
|
||||||
TriDrawTriangleArgs args;
|
TriDrawTriangleArgs args;
|
||||||
args.uniforms = &drawargs;
|
args.uniforms = &drawargs;
|
||||||
|
|
||||||
ShadedTriVertex vert[3];
|
ShadedTriVertex vertbuffer[3];
|
||||||
|
ShadedTriVertex *vert[3] = { &vertbuffer[0], &vertbuffer[1], &vertbuffer[2] };
|
||||||
if (drawmode == PolyDrawMode::Triangles)
|
if (drawmode == PolyDrawMode::Triangles)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < vcount / 3; i++)
|
for (int i = 0; i < vcount / 3; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 3; j++)
|
||||||
vert[j] = vertexShader->Shade(this, drawargs, vertices, *(elements++));
|
*vert[j] = ShadeVertex(*(elements++));
|
||||||
DrawShadedTriangle(vert, ccw, &args);
|
DrawShadedTriangle(vert, ccw, &args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (drawmode == PolyDrawMode::TriangleFan)
|
else if (drawmode == PolyDrawMode::TriangleFan)
|
||||||
{
|
{
|
||||||
vert[0] = vertexShader->Shade(this, drawargs, vertices, *(elements++));
|
*vert[0] = ShadeVertex(*(elements++));
|
||||||
vert[1] = vertexShader->Shade(this, drawargs, vertices, *(elements++));
|
*vert[1] = ShadeVertex(*(elements++));
|
||||||
for (int i = 2; i < vcount; i++)
|
for (int i = 2; i < vcount; i++)
|
||||||
{
|
{
|
||||||
vert[2] = vertexShader->Shade(this, drawargs, vertices, *(elements++));
|
*vert[2] = ShadeVertex(*(elements++));
|
||||||
DrawShadedTriangle(vert, ccw, &args);
|
DrawShadedTriangle(vert, ccw, &args);
|
||||||
vert[1] = vert[2];
|
std::swap(vert[1], vert[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // TriangleDrawMode::TriangleStrip
|
else // TriangleDrawMode::TriangleStrip
|
||||||
{
|
{
|
||||||
bool toggleccw = ccw;
|
bool toggleccw = ccw;
|
||||||
vert[0] = vertexShader->Shade(this, drawargs, vertices, *(elements++));
|
*vert[0] = ShadeVertex(*(elements++));
|
||||||
vert[1] = vertexShader->Shade(this, drawargs, vertices, *(elements++));
|
*vert[1] = ShadeVertex(*(elements++));
|
||||||
for (int i = 2; i < vcount; i++)
|
for (int i = 2; i < vcount; i++)
|
||||||
{
|
{
|
||||||
vert[2] = vertexShader->Shade(this, drawargs, vertices, *(elements++));
|
*vert[2] = ShadeVertex(*(elements++));
|
||||||
DrawShadedTriangle(vert, toggleccw, &args);
|
DrawShadedTriangle(vert, toggleccw, &args);
|
||||||
|
ShadedTriVertex *vtmp = vert[0];
|
||||||
vert[0] = vert[1];
|
vert[0] = vert[1];
|
||||||
vert[1] = vert[2];
|
vert[1] = vert[2];
|
||||||
|
vert[2] = vtmp;
|
||||||
toggleccw = !toggleccw;
|
toggleccw = !toggleccw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,116 +299,89 @@ void PolyTriangleThreadData::Draw(int index, int vcount, PolyDrawMode drawmode)
|
||||||
|
|
||||||
int vinput = index;
|
int vinput = index;
|
||||||
|
|
||||||
ShadedTriVertex vert[3];
|
ShadedTriVertex vertbuffer[3];
|
||||||
|
ShadedTriVertex *vert[3] = { &vertbuffer[0], &vertbuffer[1], &vertbuffer[2] };
|
||||||
if (drawmode == PolyDrawMode::Triangles)
|
if (drawmode == PolyDrawMode::Triangles)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < vcount / 3; i++)
|
for (int i = 0; i < vcount / 3; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < 3; j++)
|
for (int j = 0; j < 3; j++)
|
||||||
vert[j] = vertexShader->Shade(this, drawargs, vertices, vinput++);
|
*vert[j] = ShadeVertex(vinput++);
|
||||||
DrawShadedTriangle(vert, ccw, &args);
|
DrawShadedTriangle(vert, ccw, &args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (drawmode == PolyDrawMode::TriangleFan)
|
else if (drawmode == PolyDrawMode::TriangleFan)
|
||||||
{
|
{
|
||||||
vert[0] = vertexShader->Shade(this, drawargs, vertices, vinput++);
|
*vert[0] = ShadeVertex(vinput++);
|
||||||
vert[1] = vertexShader->Shade(this, drawargs, vertices, vinput++);
|
*vert[1] = ShadeVertex(vinput++);
|
||||||
for (int i = 2; i < vcount; i++)
|
for (int i = 2; i < vcount; i++)
|
||||||
{
|
{
|
||||||
vert[2] = vertexShader->Shade(this, drawargs, vertices, vinput++);
|
*vert[2] = ShadeVertex(vinput++);
|
||||||
DrawShadedTriangle(vert, ccw, &args);
|
DrawShadedTriangle(vert, ccw, &args);
|
||||||
vert[1] = vert[2];
|
std::swap(vert[1], vert[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // TriangleDrawMode::TriangleStrip
|
else // TriangleDrawMode::TriangleStrip
|
||||||
{
|
{
|
||||||
bool toggleccw = ccw;
|
bool toggleccw = ccw;
|
||||||
vert[0] = vertexShader->Shade(this, drawargs, vertices, vinput++);
|
*vert[0] = ShadeVertex(vinput++);
|
||||||
vert[1] = vertexShader->Shade(this, drawargs, vertices, vinput++);
|
*vert[1] = ShadeVertex(vinput++);
|
||||||
for (int i = 2; i < vcount; i++)
|
for (int i = 2; i < vcount; i++)
|
||||||
{
|
{
|
||||||
vert[2] = vertexShader->Shade(this, drawargs, vertices, vinput++);
|
*vert[2] = ShadeVertex(vinput++);
|
||||||
DrawShadedTriangle(vert, toggleccw, &args);
|
DrawShadedTriangle(vert, toggleccw, &args);
|
||||||
|
ShadedTriVertex *vtmp = vert[0];
|
||||||
vert[0] = vert[1];
|
vert[0] = vert[1];
|
||||||
vert[1] = vert[2];
|
vert[1] = vert[2];
|
||||||
|
vert[2] = vtmp;
|
||||||
toggleccw = !toggleccw;
|
toggleccw = !toggleccw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ShadedTriVertex PolyTriVertexShader::Shade(PolyTriangleThreadData *thread, const PolyDrawArgs &drawargs, const void *vertices, int index)
|
ShadedTriVertex PolyTriangleThreadData::ShadeVertex(int index)
|
||||||
{
|
{
|
||||||
ShadedTriVertex sv;
|
inputAssembly->Load(this, vertices, index);
|
||||||
Vec4f objpos;
|
mainVertexShader.main();
|
||||||
|
return mainVertexShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolySWInputAssembly::Load(PolyTriangleThreadData *thread, const void *vertices, int index)
|
||||||
|
{
|
||||||
if (thread->modelFrame1 == -1)
|
if (thread->modelFrame1 == -1)
|
||||||
{
|
{
|
||||||
const TriVertex &v = static_cast<const TriVertex*>(vertices)[index];
|
thread->swVertexShader.v1 = static_cast<const TriVertex*>(vertices)[index];
|
||||||
objpos = Vec4f(v.x, v.y, v.z, v.w);
|
|
||||||
sv.u = v.u;
|
|
||||||
sv.v = v.v;
|
|
||||||
}
|
|
||||||
else if (thread->modelFrame1 == thread->modelFrame2 || thread->modelInterpolationFactor == 0.f)
|
|
||||||
{
|
|
||||||
const FModelVertex &v = static_cast<const FModelVertex*>(vertices)[thread->modelFrame1 + index];
|
|
||||||
objpos = Vec4f(v.x, v.y, v.z, 1.0f);
|
|
||||||
sv.u = v.u;
|
|
||||||
sv.v = v.v;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const FModelVertex &v1 = static_cast<const FModelVertex*>(vertices)[thread->modelFrame1 + index];
|
const FModelVertex &v1 = static_cast<const FModelVertex*>(vertices)[thread->modelFrame1 + index];
|
||||||
const FModelVertex &v2 = static_cast<const FModelVertex*>(vertices)[thread->modelFrame2 + index];
|
const FModelVertex &v2 = static_cast<const FModelVertex*>(vertices)[thread->modelFrame2 + index];
|
||||||
|
|
||||||
float frac = thread->modelInterpolationFactor;
|
thread->swVertexShader.v1.x = v1.x;
|
||||||
float inv_frac = 1.0f - frac;
|
thread->swVertexShader.v1.y = v1.y;
|
||||||
|
thread->swVertexShader.v1.z = v1.z;
|
||||||
|
thread->swVertexShader.v1.w = 1.0f;
|
||||||
|
thread->swVertexShader.v1.u = v1.u;
|
||||||
|
thread->swVertexShader.v1.v = v1.v;
|
||||||
|
|
||||||
objpos = Vec4f(v1.x * inv_frac + v2.x * frac, v1.y * inv_frac + v2.y * frac, v1.z * inv_frac + v2.z * frac, 1.0f);
|
thread->swVertexShader.v2.x = v2.x;
|
||||||
sv.u = v1.u;
|
thread->swVertexShader.v2.y = v2.y;
|
||||||
sv.v = v1.v;
|
thread->swVertexShader.v2.z = v2.z;
|
||||||
|
thread->swVertexShader.v2.w = 1.0f;
|
||||||
|
thread->swVertexShader.v2.u = v2.u;
|
||||||
|
thread->swVertexShader.v2.v = v2.v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply transform to get clip coordinates:
|
bool PolyTriangleThreadData::IsDegenerate(const ShadedTriVertex *const* vert)
|
||||||
Vec4f clippos = (*thread->objectToClip) * objpos;
|
|
||||||
|
|
||||||
sv.x = clippos.X;
|
|
||||||
sv.y = clippos.Y;
|
|
||||||
sv.z = clippos.Z;
|
|
||||||
sv.w = clippos.W;
|
|
||||||
|
|
||||||
if (!thread->objectToWorld) // Identity matrix
|
|
||||||
{
|
|
||||||
sv.worldX = objpos.X;
|
|
||||||
sv.worldY = objpos.Y;
|
|
||||||
sv.worldZ = objpos.Z;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Vec4f worldpos = (*thread->objectToWorld) * objpos;
|
|
||||||
sv.worldX = worldpos.X;
|
|
||||||
sv.worldY = worldpos.Y;
|
|
||||||
sv.worldZ = worldpos.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate gl_ClipDistance[i]
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
const auto &clipPlane = drawargs.ClipPlane(i);
|
|
||||||
sv.clipDistance[i] = objpos.X * clipPlane.A + objpos.Y * clipPlane.B + objpos.Z * clipPlane.C + objpos.W * clipPlane.D;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sv;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PolyTriangleThreadData::IsDegenerate(const ShadedTriVertex *vert)
|
|
||||||
{
|
{
|
||||||
// A degenerate triangle has a zero cross product for two of its sides.
|
// A degenerate triangle has a zero cross product for two of its sides.
|
||||||
float ax = vert[1].x - vert[0].x;
|
float ax = vert[1]->gl_Position.X - vert[0]->gl_Position.X;
|
||||||
float ay = vert[1].y - vert[0].y;
|
float ay = vert[1]->gl_Position.Y - vert[0]->gl_Position.Y;
|
||||||
float az = vert[1].w - vert[0].w;
|
float az = vert[1]->gl_Position.W - vert[0]->gl_Position.W;
|
||||||
float bx = vert[2].x - vert[0].x;
|
float bx = vert[2]->gl_Position.X - vert[0]->gl_Position.X;
|
||||||
float by = vert[2].y - vert[0].y;
|
float by = vert[2]->gl_Position.Y - vert[0]->gl_Position.Y;
|
||||||
float bz = vert[2].w - vert[0].w;
|
float bz = vert[2]->gl_Position.W - vert[0]->gl_Position.W;
|
||||||
float crossx = ay * bz - az * by;
|
float crossx = ay * bz - az * by;
|
||||||
float crossy = az * bx - ax * bz;
|
float crossy = az * bx - ax * bz;
|
||||||
float crossz = ax * by - ay * bx;
|
float crossz = ax * by - ay * bx;
|
||||||
|
@ -389,15 +398,35 @@ bool PolyTriangleThreadData::IsFrontfacing(TriDrawTriangleArgs *args)
|
||||||
return a <= 0.0f;
|
return a <= 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *vert, bool ccw, TriDrawTriangleArgs *args)
|
void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *const* vert, bool ccw, TriDrawTriangleArgs *args)
|
||||||
{
|
{
|
||||||
// Reject triangle if degenerate
|
// Reject triangle if degenerate
|
||||||
if (IsDegenerate(vert))
|
if (IsDegenerate(vert))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Cull, clip and generate additional vertices as needed
|
// Cull, clip and generate additional vertices as needed
|
||||||
ShadedTriVertex clippedvert[max_additional_vertices];
|
ScreenTriVertex clippedvert[max_additional_vertices];
|
||||||
int numclipvert = ClipEdge(vert, clippedvert);
|
int numclipvert = ClipEdge(vert);
|
||||||
|
|
||||||
|
// Convert barycentric weights to actual vertices
|
||||||
|
for (int i = 0; i < numclipvert; i++)
|
||||||
|
{
|
||||||
|
auto &v = clippedvert[i];
|
||||||
|
memset(&v, 0, sizeof(ScreenTriVertex));
|
||||||
|
for (int w = 0; w < 3; w++)
|
||||||
|
{
|
||||||
|
float weight = weights[i * 3 + w];
|
||||||
|
v.x += vert[w]->gl_Position.X * weight;
|
||||||
|
v.y += vert[w]->gl_Position.Y * weight;
|
||||||
|
v.z += vert[w]->gl_Position.Z * weight;
|
||||||
|
v.w += vert[w]->gl_Position.W * weight;
|
||||||
|
v.u += vert[w]->vTexCoord.X * weight;
|
||||||
|
v.v += vert[w]->vTexCoord.Y * weight;
|
||||||
|
v.worldX += vert[w]->pixelpos.X * weight;
|
||||||
|
v.worldY += vert[w]->pixelpos.Y * weight;
|
||||||
|
v.worldZ += vert[w]->pixelpos.Z * weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef NO_SSE
|
#ifdef NO_SSE
|
||||||
// Map to 2D viewport:
|
// Map to 2D viewport:
|
||||||
|
@ -499,8 +528,18 @@ void PolyTriangleThreadData::DrawShadedTriangle(const ShadedTriVertex *vert, boo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int PolyTriangleThreadData::ClipEdge(const ShadedTriVertex *verts, ShadedTriVertex *clippedvert)
|
int PolyTriangleThreadData::ClipEdge(const ShadedTriVertex *const* verts)
|
||||||
{
|
{
|
||||||
|
// use barycentric weights for clipped vertices
|
||||||
|
weights = weightsbuffer;
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
weights[i * 3 + 0] = 0.0f;
|
||||||
|
weights[i * 3 + 1] = 0.0f;
|
||||||
|
weights[i * 3 + 2] = 0.0f;
|
||||||
|
weights[i * 3 + i] = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
// Clip and cull so that the following is true for all vertices:
|
// Clip and cull so that the following is true for all vertices:
|
||||||
// -v.w <= v.x <= v.w
|
// -v.w <= v.x <= v.w
|
||||||
// -v.w <= v.y <= v.w
|
// -v.w <= v.y <= v.w
|
||||||
|
@ -514,16 +553,16 @@ int PolyTriangleThreadData::ClipEdge(const ShadedTriVertex *verts, ShadedTriVert
|
||||||
float *clipd = clipdistance;
|
float *clipd = clipdistance;
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
const auto &v = verts[i];
|
const auto &v = *verts[i];
|
||||||
clipd[0] = v.x + v.w;
|
clipd[0] = v.gl_Position.X + v.gl_Position.W;
|
||||||
clipd[1] = v.w - v.x;
|
clipd[1] = v.gl_Position.W - v.gl_Position.X;
|
||||||
clipd[2] = v.y + v.w;
|
clipd[2] = v.gl_Position.Y + v.gl_Position.W;
|
||||||
clipd[3] = v.w - v.y;
|
clipd[3] = v.gl_Position.W - v.gl_Position.Y;
|
||||||
clipd[4] = v.z + v.w;
|
clipd[4] = v.gl_Position.Z + v.gl_Position.W;
|
||||||
clipd[5] = v.w - v.z;
|
clipd[5] = v.gl_Position.W - v.gl_Position.Z;
|
||||||
clipd[6] = v.clipDistance[0];
|
clipd[6] = v.gl_ClipDistance[0];
|
||||||
clipd[7] = v.clipDistance[1];
|
clipd[7] = v.gl_ClipDistance[1];
|
||||||
clipd[8] = v.clipDistance[2];
|
clipd[8] = v.gl_ClipDistance[2];
|
||||||
for (int j = 0; j < 9; j++)
|
for (int j = 0; j < 9; j++)
|
||||||
needsclipping = needsclipping || clipd[i];
|
needsclipping = needsclipping || clipd[i];
|
||||||
clipd += numclipdistances;
|
clipd += numclipdistances;
|
||||||
|
@ -532,16 +571,12 @@ int PolyTriangleThreadData::ClipEdge(const ShadedTriVertex *verts, ShadedTriVert
|
||||||
// If all halfspace clip distances are positive then the entire triangle is visible. Skip the expensive clipping step.
|
// If all halfspace clip distances are positive then the entire triangle is visible. Skip the expensive clipping step.
|
||||||
if (!needsclipping)
|
if (!needsclipping)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
memcpy(clippedvert + i, &verts[i], sizeof(ShadedTriVertex));
|
|
||||||
}
|
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
__m128 mx = _mm_loadu_ps(&verts[0].x);
|
__m128 mx = _mm_loadu_ps(&verts[0]->gl_Position.X);
|
||||||
__m128 my = _mm_loadu_ps(&verts[1].x);
|
__m128 my = _mm_loadu_ps(&verts[1]->gl_Position.X);
|
||||||
__m128 mz = _mm_loadu_ps(&verts[2].x);
|
__m128 mz = _mm_loadu_ps(&verts[2]->gl_Position.X);
|
||||||
__m128 mw = _mm_setzero_ps();
|
__m128 mw = _mm_setzero_ps();
|
||||||
_MM_TRANSPOSE4_PS(mx, my, mz, mw);
|
_MM_TRANSPOSE4_PS(mx, my, mz, mw);
|
||||||
__m128 clipd0 = _mm_add_ps(mx, mw);
|
__m128 clipd0 = _mm_add_ps(mx, mw);
|
||||||
|
@ -550,9 +585,9 @@ int PolyTriangleThreadData::ClipEdge(const ShadedTriVertex *verts, ShadedTriVert
|
||||||
__m128 clipd3 = _mm_sub_ps(mw, my);
|
__m128 clipd3 = _mm_sub_ps(mw, my);
|
||||||
__m128 clipd4 = _mm_add_ps(mz, mw);
|
__m128 clipd4 = _mm_add_ps(mz, mw);
|
||||||
__m128 clipd5 = _mm_sub_ps(mw, mz);
|
__m128 clipd5 = _mm_sub_ps(mw, mz);
|
||||||
__m128 clipd6 = _mm_setr_ps(verts[0].clipDistance[0], verts[1].clipDistance[0], verts[2].clipDistance[0], 0.0f);
|
__m128 clipd6 = _mm_setr_ps(verts[0]->gl_ClipDistance[0], verts[1]->gl_ClipDistance[0], verts[2]->gl_ClipDistance[0], 0.0f);
|
||||||
__m128 clipd7 = _mm_setr_ps(verts[0].clipDistance[1], verts[1].clipDistance[1], verts[2].clipDistance[1], 0.0f);
|
__m128 clipd7 = _mm_setr_ps(verts[0]->gl_ClipDistance[1], verts[1]->gl_ClipDistance[1], verts[2]->gl_ClipDistance[1], 0.0f);
|
||||||
__m128 clipd8 = _mm_setr_ps(verts[0].clipDistance[2], verts[1].clipDistance[2], verts[2].clipDistance[2], 0.0f);
|
__m128 clipd8 = _mm_setr_ps(verts[0]->gl_ClipDistance[2], verts[1]->gl_ClipDistance[2], verts[2]->gl_ClipDistance[2], 0.0f);
|
||||||
__m128 mneedsclipping = _mm_cmplt_ps(clipd0, _mm_setzero_ps());
|
__m128 mneedsclipping = _mm_cmplt_ps(clipd0, _mm_setzero_ps());
|
||||||
mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd1, _mm_setzero_ps()));
|
mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd1, _mm_setzero_ps()));
|
||||||
mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd2, _mm_setzero_ps()));
|
mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd2, _mm_setzero_ps()));
|
||||||
|
@ -564,10 +599,6 @@ int PolyTriangleThreadData::ClipEdge(const ShadedTriVertex *verts, ShadedTriVert
|
||||||
mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd8, _mm_setzero_ps()));
|
mneedsclipping = _mm_or_ps(mneedsclipping, _mm_cmplt_ps(clipd8, _mm_setzero_ps()));
|
||||||
if (_mm_movemask_ps(mneedsclipping) == 0)
|
if (_mm_movemask_ps(mneedsclipping) == 0)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
memcpy(clippedvert + i, &verts[i], sizeof(ShadedTriVertex));
|
|
||||||
}
|
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
float clipdistance[numclipdistances * 4];
|
float clipdistance[numclipdistances * 4];
|
||||||
|
@ -582,16 +613,6 @@ int PolyTriangleThreadData::ClipEdge(const ShadedTriVertex *verts, ShadedTriVert
|
||||||
_mm_storeu_ps(clipdistance + 32, clipd8);
|
_mm_storeu_ps(clipdistance + 32, clipd8);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// use barycentric weights while clipping vertices
|
|
||||||
float weights[max_additional_vertices * 3 * 2];
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
weights[i * 3 + 0] = 0.0f;
|
|
||||||
weights[i * 3 + 1] = 0.0f;
|
|
||||||
weights[i * 3 + 2] = 0.0f;
|
|
||||||
weights[i * 3 + i] = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clip against each halfspace
|
// Clip against each halfspace
|
||||||
float *input = weights;
|
float *input = weights;
|
||||||
float *output = weights + max_additional_vertices * 3;
|
float *output = weights + max_additional_vertices * 3;
|
||||||
|
@ -651,25 +672,7 @@ int PolyTriangleThreadData::ClipEdge(const ShadedTriVertex *verts, ShadedTriVert
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert barycentric weights to actual vertices
|
weights = input;
|
||||||
for (int i = 0; i < inputverts; i++)
|
|
||||||
{
|
|
||||||
auto &v = clippedvert[i];
|
|
||||||
memset(&v, 0, sizeof(ShadedTriVertex));
|
|
||||||
for (int w = 0; w < 3; w++)
|
|
||||||
{
|
|
||||||
float weight = input[i * 3 + w];
|
|
||||||
v.x += verts[w].x * weight;
|
|
||||||
v.y += verts[w].y * weight;
|
|
||||||
v.z += verts[w].z * weight;
|
|
||||||
v.w += verts[w].w * weight;
|
|
||||||
v.u += verts[w].u * weight;
|
|
||||||
v.v += verts[w].v * weight;
|
|
||||||
v.worldX += verts[w].worldX * weight;
|
|
||||||
v.worldY += verts[w].worldY * weight;
|
|
||||||
v.worldZ += verts[w].worldZ * weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return inputverts;
|
return inputverts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,13 +707,13 @@ void PolySetIndexBufferCommand::Execute(DrawerThread *thread)
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PolySetVertexShaderCommand::PolySetVertexShaderCommand(PolyVertexShader *shader) : shader(shader)
|
PolySetInputAssemblyCommand::PolySetInputAssemblyCommand(PolyInputAssembly *input) : input(input)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void PolySetVertexShaderCommand::Execute(DrawerThread *thread)
|
void PolySetInputAssemblyCommand::Execute(DrawerThread *thread)
|
||||||
{
|
{
|
||||||
PolyTriangleThreadData::Get(thread)->SetVertexShader(shader);
|
PolyTriangleThreadData::Get(thread)->SetInputAssembly(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -804,6 +807,40 @@ void PolySetViewportCommand::Execute(DrawerThread *thread)
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PolySetViewpointUniformsCommand::PolySetViewpointUniformsCommand(const HWViewpointUniforms *uniforms) : uniforms(uniforms)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolySetViewpointUniformsCommand::Execute(DrawerThread *thread)
|
||||||
|
{
|
||||||
|
PolyTriangleThreadData::Get(thread)->SetViewpointUniforms(uniforms);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PolyPushMatricesCommand::PolyPushMatricesCommand(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix)
|
||||||
|
: modelMatrix(modelMatrix), normalModelMatrix(normalModelMatrix), textureMatrix(textureMatrix)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolyPushMatricesCommand::Execute(DrawerThread *thread)
|
||||||
|
{
|
||||||
|
PolyTriangleThreadData::Get(thread)->PushMatrices(modelMatrix, normalModelMatrix, textureMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
PolyPushStreamDataCommand::PolyPushStreamDataCommand(const StreamData &data, const Vec2f &uClipSplit) : data(data), uClipSplit(uClipSplit)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PolyPushStreamDataCommand::Execute(DrawerThread *thread)
|
||||||
|
{
|
||||||
|
PolyTriangleThreadData::Get(thread)->PushStreamData(data, uClipSplit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PolyPushConstantsCommand::PolyPushConstantsCommand(const PolyDrawArgs &args) : args(args)
|
PolyPushConstantsCommand::PolyPushConstantsCommand(const PolyDrawArgs &args) : args(args)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
class DCanvas;
|
class DCanvas;
|
||||||
class PolyDrawerCommand;
|
class PolyDrawerCommand;
|
||||||
class PolyVertexShader;
|
class PolyInputAssembly;
|
||||||
|
|
||||||
class PolyTriangleDrawer
|
class PolyTriangleDrawer
|
||||||
{
|
{
|
||||||
|
@ -41,7 +41,7 @@ public:
|
||||||
static void ClearDepth(const DrawerCommandQueuePtr &queue, float value);
|
static void ClearDepth(const DrawerCommandQueuePtr &queue, float value);
|
||||||
static void ClearStencil(const DrawerCommandQueuePtr &queue, uint8_t value);
|
static void ClearStencil(const DrawerCommandQueuePtr &queue, uint8_t value);
|
||||||
static void SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas);
|
static void SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas);
|
||||||
static void SetVertexShader(const DrawerCommandQueuePtr &queue, PolyVertexShader *shader);
|
static void SetInputAssembly(const DrawerCommandQueuePtr &queue, PolyInputAssembly *input);
|
||||||
static void SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw);
|
static void SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw);
|
||||||
static void SetTwoSided(const DrawerCommandQueuePtr &queue, bool twosided);
|
static void SetTwoSided(const DrawerCommandQueuePtr &queue, bool twosided);
|
||||||
static void SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable);
|
static void SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable);
|
||||||
|
@ -49,42 +49,55 @@ public:
|
||||||
static void SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip, const Mat4f *objectToWorld);
|
static void SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip, const Mat4f *objectToWorld);
|
||||||
static void SetVertexBuffer(const DrawerCommandQueuePtr &queue, const void *vertices);
|
static void SetVertexBuffer(const DrawerCommandQueuePtr &queue, const void *vertices);
|
||||||
static void SetIndexBuffer(const DrawerCommandQueuePtr &queue, const void *elements);
|
static void SetIndexBuffer(const DrawerCommandQueuePtr &queue, const void *elements);
|
||||||
|
static void SetViewpointUniforms(const DrawerCommandQueuePtr &queue, const HWViewpointUniforms *uniforms);
|
||||||
static void PushConstants(const DrawerCommandQueuePtr &queue, const PolyDrawArgs &args);
|
static void PushConstants(const DrawerCommandQueuePtr &queue, const PolyDrawArgs &args);
|
||||||
|
static void PushStreamData(const DrawerCommandQueuePtr &queue, const StreamData &data, const Vec2f &uClipSplit);
|
||||||
|
static void PushMatrices(const DrawerCommandQueuePtr &queue, const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix);
|
||||||
static void Draw(const DrawerCommandQueuePtr &queue, int index, int vcount, PolyDrawMode mode = PolyDrawMode::Triangles);
|
static void Draw(const DrawerCommandQueuePtr &queue, int index, int vcount, PolyDrawMode mode = PolyDrawMode::Triangles);
|
||||||
static void DrawIndexed(const DrawerCommandQueuePtr &queue, int index, int count, PolyDrawMode mode = PolyDrawMode::Triangles);
|
static void DrawIndexed(const DrawerCommandQueuePtr &queue, int index, int count, PolyDrawMode mode = PolyDrawMode::Triangles);
|
||||||
static bool IsBgra();
|
static bool IsBgra();
|
||||||
};
|
};
|
||||||
|
|
||||||
class PolyVertexShader
|
class PolyInputAssembly
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ShadedTriVertex Shade(PolyTriangleThreadData *thread, const PolyDrawArgs &drawargs, const void *vertices, int index) = 0;
|
virtual void Load(PolyTriangleThreadData *thread, const void *vertices, int index) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PolyTriVertexShader : public PolyVertexShader
|
class PolySWInputAssembly : public PolyInputAssembly
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ShadedTriVertex Shade(PolyTriangleThreadData *thread, const PolyDrawArgs &drawargs, const void *vertices, int index) override;
|
void Load(PolyTriangleThreadData *thread, const void *vertices, int index) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PolyTriangleThreadData
|
class PolyTriangleThreadData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PolyTriangleThreadData(int32_t core, int32_t num_cores, int32_t numa_node, int32_t num_numa_nodes, int numa_start_y, int numa_end_y) : core(core), num_cores(num_cores), numa_node(numa_node), num_numa_nodes(num_numa_nodes), numa_start_y(numa_start_y), numa_end_y(numa_end_y) { }
|
PolyTriangleThreadData(int32_t core, int32_t num_cores, int32_t numa_node, int32_t num_numa_nodes, int numa_start_y, int numa_end_y)
|
||||||
|
: core(core), num_cores(num_cores), numa_node(numa_node), num_numa_nodes(num_numa_nodes), numa_start_y(numa_start_y), numa_end_y(numa_end_y)
|
||||||
|
{
|
||||||
|
swVertexShader.drawargs = &drawargs;
|
||||||
|
}
|
||||||
|
|
||||||
void ClearDepth(float value);
|
void ClearDepth(float value);
|
||||||
void ClearStencil(uint8_t value);
|
void ClearStencil(uint8_t value);
|
||||||
void SetViewport(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra);
|
void SetViewport(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra);
|
||||||
|
|
||||||
void SetTransform(const Mat4f *objectToClip, const Mat4f *objectToWorld);
|
void SetTransform(const Mat4f *objectToClip, const Mat4f *objectToWorld);
|
||||||
void SetCullCCW(bool value) { ccw = value; }
|
void SetCullCCW(bool value) { ccw = value; }
|
||||||
void SetTwoSided(bool value) { twosided = value; }
|
void SetTwoSided(bool value) { twosided = value; }
|
||||||
void SetWeaponScene(bool value) { weaponScene = value; }
|
void SetWeaponScene(bool value) { weaponScene = value; }
|
||||||
void SetModelVertexShader(int frame1, int frame2, float interpolationFactor) { modelFrame1 = frame1; modelFrame2 = frame2; modelInterpolationFactor = interpolationFactor; }
|
void SetModelVertexShader(int frame1, int frame2, float interpolationFactor) { modelFrame1 = frame1; modelFrame2 = frame2; swVertexShader.modelInterpolationFactor = interpolationFactor; }
|
||||||
void SetVertexShader(PolyVertexShader *shader) { vertexShader = shader; }
|
|
||||||
|
void SetInputAssembly(PolyInputAssembly *input) { inputAssembly = input; }
|
||||||
void SetVertexBuffer(const void *data) { vertices = data; }
|
void SetVertexBuffer(const void *data) { vertices = data; }
|
||||||
void SetIndexBuffer(const void *data) { elements = (const unsigned int *)data; }
|
void SetIndexBuffer(const void *data) { elements = (const unsigned int *)data; }
|
||||||
|
void SetViewpointUniforms(const HWViewpointUniforms *uniforms);
|
||||||
|
|
||||||
void PushConstants(const PolyDrawArgs &args);
|
void PushConstants(const PolyDrawArgs &args);
|
||||||
|
void PushStreamData(const StreamData &data, const Vec2f &uClipSplit);
|
||||||
|
void PushMatrices(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix);
|
||||||
|
|
||||||
void DrawIndexed(int index, int count, PolyDrawMode mode);
|
void DrawIndexed(int index, int count, PolyDrawMode mode);
|
||||||
void Draw(int index, int vcount, PolyDrawMode mode);
|
void Draw(int index, int vcount, PolyDrawMode mode);
|
||||||
|
|
||||||
|
@ -140,30 +153,30 @@ public:
|
||||||
const void *vertices = nullptr;
|
const void *vertices = nullptr;
|
||||||
const unsigned int *elements = nullptr;
|
const unsigned int *elements = nullptr;
|
||||||
|
|
||||||
|
PolyMainVertexShader mainVertexShader;
|
||||||
|
|
||||||
|
int modelFrame1 = -1;
|
||||||
|
int modelFrame2 = -1;
|
||||||
|
PolySWVertexShader swVertexShader;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void DrawShadedTriangle(const ShadedTriVertex *vertices, bool ccw, TriDrawTriangleArgs *args);
|
ShadedTriVertex ShadeVertex(int index);
|
||||||
static bool IsDegenerate(const ShadedTriVertex *vertices);
|
void DrawShadedTriangle(const ShadedTriVertex *const* vertices, bool ccw, TriDrawTriangleArgs *args);
|
||||||
|
static bool IsDegenerate(const ShadedTriVertex *const* vertices);
|
||||||
static bool IsFrontfacing(TriDrawTriangleArgs *args);
|
static bool IsFrontfacing(TriDrawTriangleArgs *args);
|
||||||
static int ClipEdge(const ShadedTriVertex *verts, ShadedTriVertex *clippedvert);
|
|
||||||
|
int ClipEdge(const ShadedTriVertex *const* verts);
|
||||||
|
|
||||||
int viewport_x = 0;
|
int viewport_x = 0;
|
||||||
int viewport_width = 0;
|
int viewport_width = 0;
|
||||||
int viewport_height = 0;
|
int viewport_height = 0;
|
||||||
bool ccw = true;
|
bool ccw = true;
|
||||||
bool twosided = false;
|
bool twosided = false;
|
||||||
public:
|
PolyInputAssembly *inputAssembly = nullptr;
|
||||||
const Mat4f *objectToClip = nullptr;
|
|
||||||
const Mat4f *objectToWorld = nullptr;
|
|
||||||
private:
|
|
||||||
int modelFrame1 = -1;
|
|
||||||
int modelFrame2 = -1;
|
|
||||||
float modelInterpolationFactor = 0.0f;
|
|
||||||
PolyVertexShader *vertexShader = nullptr;
|
|
||||||
PolyMainVertexShader mainVertexShader;
|
|
||||||
|
|
||||||
enum { max_additional_vertices = 16 };
|
enum { max_additional_vertices = 16 };
|
||||||
|
float weightsbuffer[max_additional_vertices * 3 * 2];
|
||||||
friend class PolyTriVertexShader;
|
float *weights = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PolyDrawerCommand : public DrawerCommand
|
class PolyDrawerCommand : public DrawerCommand
|
||||||
|
@ -191,14 +204,14 @@ private:
|
||||||
const void *indices;
|
const void *indices;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PolySetVertexShaderCommand : public PolyDrawerCommand
|
class PolySetInputAssemblyCommand : public PolyDrawerCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PolySetVertexShaderCommand(PolyVertexShader *shader);
|
PolySetInputAssemblyCommand(PolyInputAssembly *input);
|
||||||
void Execute(DrawerThread *thread) override;
|
void Execute(DrawerThread *thread) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PolyVertexShader *shader;
|
PolyInputAssembly *input;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PolySetTransformCommand : public PolyDrawerCommand
|
class PolySetTransformCommand : public PolyDrawerCommand
|
||||||
|
@ -300,6 +313,39 @@ private:
|
||||||
bool dest_bgra;
|
bool dest_bgra;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PolySetViewpointUniformsCommand : public PolyDrawerCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PolySetViewpointUniformsCommand(const HWViewpointUniforms *uniforms);
|
||||||
|
void Execute(DrawerThread *thread) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const HWViewpointUniforms *uniforms;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PolyPushMatricesCommand : public PolyDrawerCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PolyPushMatricesCommand(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix);
|
||||||
|
void Execute(DrawerThread *thread) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
VSMatrix modelMatrix;
|
||||||
|
VSMatrix normalModelMatrix;
|
||||||
|
VSMatrix textureMatrix;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PolyPushStreamDataCommand : public PolyDrawerCommand
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PolyPushStreamDataCommand(const StreamData &data, const Vec2f &uClipSplit);
|
||||||
|
void Execute(DrawerThread *thread) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StreamData data;
|
||||||
|
Vec2f uClipSplit;
|
||||||
|
};
|
||||||
|
|
||||||
class PolyPushConstantsCommand : public PolyDrawerCommand
|
class PolyPushConstantsCommand : public PolyDrawerCommand
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -9,7 +9,16 @@
|
||||||
#include <xmmintrin.h>
|
#include <xmmintrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class PolyMainVertexShader
|
class ShadedTriVertex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Vec4f gl_Position;
|
||||||
|
float gl_ClipDistance[5];
|
||||||
|
Vec4f vTexCoord;
|
||||||
|
Vec4f pixelpos;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PolyMainVertexShader : public ShadedTriVertex
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Input
|
// Input
|
||||||
|
@ -21,11 +30,7 @@ public:
|
||||||
Vec4f aNormal2;
|
Vec4f aNormal2;
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
Vec4f gl_Position;
|
|
||||||
float gl_ClipDistance[5];
|
|
||||||
Vec4f vTexCoord;
|
|
||||||
Vec4f vColor;
|
Vec4f vColor;
|
||||||
Vec4f pixelpos;
|
|
||||||
Vec3f glowdist;
|
Vec3f glowdist;
|
||||||
Vec3f gradientdist;
|
Vec3f gradientdist;
|
||||||
Vec4f vWorldNormal;
|
Vec4f vWorldNormal;
|
||||||
|
@ -41,12 +46,10 @@ public:
|
||||||
VSMatrix TextureMatrix;
|
VSMatrix TextureMatrix;
|
||||||
StreamData Data;
|
StreamData Data;
|
||||||
Vec2f uClipSplit;
|
Vec2f uClipSplit;
|
||||||
HWViewpointUniforms Viewpoint;
|
const HWViewpointUniforms *Viewpoint = nullptr;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
float ClipDistance0, ClipDistance1, ClipDistance2, ClipDistance3, ClipDistance4;
|
|
||||||
|
|
||||||
Vec2f parmTexCoord = aTexCoord;
|
Vec2f parmTexCoord = aTexCoord;
|
||||||
Vec4f parmPosition = aPosition;
|
Vec4f parmPosition = aPosition;
|
||||||
|
|
||||||
|
@ -56,7 +59,7 @@ public:
|
||||||
else
|
else
|
||||||
worldcoord = mul(ModelMatrix, parmPosition);
|
worldcoord = mul(ModelMatrix, parmPosition);
|
||||||
|
|
||||||
Vec4f eyeCoordPos = mul(Viewpoint.mViewMatrix, worldcoord);
|
Vec4f eyeCoordPos = mul(Viewpoint->mViewMatrix, worldcoord);
|
||||||
|
|
||||||
vColor = aColor;
|
vColor = aColor;
|
||||||
|
|
||||||
|
@ -87,12 +90,12 @@ public:
|
||||||
|
|
||||||
if (Data.uSplitBottomPlane.Z != 0.0f)
|
if (Data.uSplitBottomPlane.Z != 0.0f)
|
||||||
{
|
{
|
||||||
ClipDistance3 = ((Data.uSplitTopPlane.W + Data.uSplitTopPlane.X * worldcoord.X + Data.uSplitTopPlane.Y * worldcoord.Z) * Data.uSplitTopPlane.Z) - worldcoord.Y;
|
gl_ClipDistance[3] = ((Data.uSplitTopPlane.W + Data.uSplitTopPlane.X * worldcoord.X + Data.uSplitTopPlane.Y * worldcoord.Z) * Data.uSplitTopPlane.Z) - worldcoord.Y;
|
||||||
ClipDistance4 = worldcoord.Y - ((Data.uSplitBottomPlane.W + Data.uSplitBottomPlane.X * worldcoord.X + Data.uSplitBottomPlane.Y * worldcoord.Z) * Data.uSplitBottomPlane.Z);
|
gl_ClipDistance[4] = worldcoord.Y - ((Data.uSplitBottomPlane.W + Data.uSplitBottomPlane.X * worldcoord.X + Data.uSplitBottomPlane.Y * worldcoord.Z) * Data.uSplitBottomPlane.Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
vWorldNormal = mul(NormalModelMatrix, Vec4f(normalize(mix3(aNormal, aNormal2, Data.uInterpolationFactor)), 1.0f));
|
vWorldNormal = mul(NormalModelMatrix, Vec4f(normalize(mix3(aNormal, aNormal2, Data.uInterpolationFactor)), 1.0f));
|
||||||
vEyeNormal = mul(Viewpoint.mNormalViewMatrix, vWorldNormal);
|
vEyeNormal = mul(Viewpoint->mNormalViewMatrix, vWorldNormal);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SPHEREMAP)
|
if (!SPHEREMAP)
|
||||||
|
@ -102,43 +105,39 @@ public:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Vec3f u = normalize3(eyeCoordPos);
|
Vec3f u = normalize3(eyeCoordPos);
|
||||||
Vec3f n = normalize3(mul(Viewpoint.mNormalViewMatrix, Vec4f(parmTexCoord.X, 0.0f, parmTexCoord.Y, 0.0f)));
|
Vec3f n = normalize3(mul(Viewpoint->mNormalViewMatrix, Vec4f(parmTexCoord.X, 0.0f, parmTexCoord.Y, 0.0f)));
|
||||||
Vec3f r = reflect(u, n);
|
Vec3f r = reflect(u, n);
|
||||||
float m = 2.0f * sqrt(r.X*r.X + r.Y*r.Y + (r.Z + 1.0f)*(r.Z + 1.0f));
|
float m = 2.0f * sqrt(r.X*r.X + r.Y*r.Y + (r.Z + 1.0f)*(r.Z + 1.0f));
|
||||||
vTexCoord.X = r.X / m + 0.5f;
|
vTexCoord.X = r.X / m + 0.5f;
|
||||||
vTexCoord.Y = r.Y / m + 0.5f;
|
vTexCoord.Y = r.Y / m + 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_Position = mul(Viewpoint.mProjectionMatrix, eyeCoordPos);
|
gl_Position = mul(Viewpoint->mProjectionMatrix, eyeCoordPos);
|
||||||
|
|
||||||
if (Viewpoint.mClipHeightDirection != 0.0f) // clip planes used for reflective flats
|
if (Viewpoint->mClipHeightDirection != 0.0f) // clip planes used for reflective flats
|
||||||
{
|
{
|
||||||
ClipDistance0 = (worldcoord.Y - Viewpoint.mClipHeight) * Viewpoint.mClipHeightDirection;
|
gl_ClipDistance[0] = (worldcoord.Y - Viewpoint->mClipHeight) * Viewpoint->mClipHeightDirection;
|
||||||
}
|
}
|
||||||
else if (Viewpoint.mClipLine.X > -1000000.0f) // and for line portals - this will never be active at the same time as the reflective planes clipping so it can use the same hardware clip plane.
|
else if (Viewpoint->mClipLine.X > -1000000.0f) // and for line portals - this will never be active at the same time as the reflective planes clipping so it can use the same hardware clip plane.
|
||||||
{
|
{
|
||||||
ClipDistance0 = -((worldcoord.Z - Viewpoint.mClipLine.Y) * Viewpoint.mClipLine.Z + (Viewpoint.mClipLine.X - worldcoord.X) * Viewpoint.mClipLine.W) + 1.0f / 32768.0f; // allow a tiny bit of imprecisions for colinear linedefs.
|
gl_ClipDistance[0] = -((worldcoord.Z - Viewpoint->mClipLine.Y) * Viewpoint->mClipLine.Z + (Viewpoint->mClipLine.X - worldcoord.X) * Viewpoint->mClipLine.W) + 1.0f / 32768.0f; // allow a tiny bit of imprecisions for colinear linedefs.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ClipDistance0 = 1.0f;
|
gl_ClipDistance[0] = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clip planes used for translucency splitting
|
// clip planes used for translucency splitting
|
||||||
ClipDistance1 = worldcoord.Y - uClipSplit.X;
|
gl_ClipDistance[1] = worldcoord.Y - uClipSplit.X;
|
||||||
ClipDistance2 = uClipSplit.Y - worldcoord.Y;
|
gl_ClipDistance[2] = uClipSplit.Y - worldcoord.Y;
|
||||||
|
|
||||||
if (Data.uSplitTopPlane == FVector4(0.0f, 0.0f, 0.0f, 0.0f))
|
if (Data.uSplitTopPlane == FVector4(0.0f, 0.0f, 0.0f, 0.0f))
|
||||||
{
|
{
|
||||||
ClipDistance3 = 1.0f;
|
gl_ClipDistance[3] = 1.0f;
|
||||||
ClipDistance4 = 1.0f;
|
gl_ClipDistance[4] = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_ClipDistance[0] = ClipDistance0;
|
std::swap(vTexCoord.X, vTexCoord.Y); // textures are transposed because the software renderer did them this way
|
||||||
gl_ClipDistance[1] = ClipDistance1;
|
|
||||||
gl_ClipDistance[2] = ClipDistance2;
|
|
||||||
gl_ClipDistance[3] = ClipDistance3;
|
|
||||||
gl_ClipDistance[4] = ClipDistance4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -198,3 +197,59 @@ private:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PolySWVertexShader : public ShadedTriVertex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Input
|
||||||
|
TriVertex v1;
|
||||||
|
TriVertex v2;
|
||||||
|
|
||||||
|
// Uniforms
|
||||||
|
float modelInterpolationFactor = 0.0f;
|
||||||
|
const Mat4f *objectToClip = nullptr;
|
||||||
|
const Mat4f *objectToWorld = nullptr;
|
||||||
|
PolyDrawArgs *drawargs = nullptr;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
Vec4f objpos;
|
||||||
|
|
||||||
|
if (modelInterpolationFactor == 0.f)
|
||||||
|
{
|
||||||
|
objpos = Vec4f(v1.x, v1.y, v1.z, v1.w);
|
||||||
|
vTexCoord.X = v1.u;
|
||||||
|
vTexCoord.Y = v1.v;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float frac = modelInterpolationFactor;
|
||||||
|
float inv_frac = 1.0f - frac;
|
||||||
|
|
||||||
|
objpos = Vec4f(v1.x * inv_frac + v2.x * frac, v1.y * inv_frac + v2.y * frac, v1.z * inv_frac + v2.z * frac, 1.0f);
|
||||||
|
vTexCoord.X = v1.u;
|
||||||
|
vTexCoord.Y = v1.v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply transform to get clip coordinates:
|
||||||
|
gl_Position = (*objectToClip) * objpos;
|
||||||
|
|
||||||
|
if (!objectToWorld) // Identity matrix
|
||||||
|
{
|
||||||
|
pixelpos = objpos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pixelpos = (*objectToWorld) * objpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate gl_ClipDistance[i]
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
const auto &clipPlane = drawargs->ClipPlane(i);
|
||||||
|
gl_ClipDistance[i] = objpos.X * clipPlane.A + objpos.Y * clipPlane.B + objpos.Z * clipPlane.C + objpos.W * clipPlane.D;
|
||||||
|
}
|
||||||
|
gl_ClipDistance[3] = 1.0f;
|
||||||
|
gl_ClipDistance[4] = 1.0f;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#include "screen_triangle.h"
|
#include "screen_triangle.h"
|
||||||
#include "x86.h"
|
#include "x86.h"
|
||||||
|
|
||||||
static void SortVertices(const TriDrawTriangleArgs *args, ShadedTriVertex **sortedVertices)
|
static void SortVertices(const TriDrawTriangleArgs *args, ScreenTriVertex **sortedVertices)
|
||||||
{
|
{
|
||||||
sortedVertices[0] = args->v1;
|
sortedVertices[0] = args->v1;
|
||||||
sortedVertices[1] = args->v2;
|
sortedVertices[1] = args->v2;
|
||||||
|
@ -57,7 +57,7 @@ void ScreenTriangle::Draw(const TriDrawTriangleArgs *args, PolyTriangleThreadDat
|
||||||
using namespace TriScreenDrawerModes;
|
using namespace TriScreenDrawerModes;
|
||||||
|
|
||||||
// Sort vertices by Y position
|
// Sort vertices by Y position
|
||||||
ShadedTriVertex *sortedVertices[3];
|
ScreenTriVertex *sortedVertices[3];
|
||||||
SortVertices(args, sortedVertices);
|
SortVertices(args, sortedVertices);
|
||||||
|
|
||||||
int clipleft = 0;
|
int clipleft = 0;
|
||||||
|
|
|
@ -31,11 +31,10 @@ class FString;
|
||||||
class PolyDrawArgs;
|
class PolyDrawArgs;
|
||||||
class PolyTriangleThreadData;
|
class PolyTriangleThreadData;
|
||||||
|
|
||||||
struct ShadedTriVertex
|
struct ScreenTriVertex
|
||||||
{
|
{
|
||||||
float x, y, z, w;
|
float x, y, z, w;
|
||||||
float u, v;
|
float u, v;
|
||||||
float clipDistance[3];
|
|
||||||
float worldX, worldY, worldZ;
|
float worldX, worldY, worldZ;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -47,9 +46,9 @@ struct ScreenTriangleStepVariables
|
||||||
|
|
||||||
struct TriDrawTriangleArgs
|
struct TriDrawTriangleArgs
|
||||||
{
|
{
|
||||||
ShadedTriVertex *v1;
|
ScreenTriVertex *v1;
|
||||||
ShadedTriVertex *v2;
|
ScreenTriVertex *v2;
|
||||||
ShadedTriVertex *v3;
|
ScreenTriVertex *v3;
|
||||||
const PolyDrawArgs *uniforms;
|
const PolyDrawArgs *uniforms;
|
||||||
ScreenTriangleStepVariables gradientX;
|
ScreenTriangleStepVariables gradientX;
|
||||||
ScreenTriangleStepVariables gradientY;
|
ScreenTriangleStepVariables gradientY;
|
||||||
|
|
|
@ -148,8 +148,8 @@ namespace swrenderer
|
||||||
SWModelRenderer::SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor, Mat4f *worldToClip, bool mirrorWorldToClip)
|
SWModelRenderer::SWModelRenderer(RenderThread *thread, Fake3DTranslucent clip3DFloor, Mat4f *worldToClip, bool mirrorWorldToClip)
|
||||||
: Thread(thread), Clip3DFloor(clip3DFloor), WorldToClip(worldToClip), MirrorWorldToClip(mirrorWorldToClip)
|
: Thread(thread), Clip3DFloor(clip3DFloor), WorldToClip(worldToClip), MirrorWorldToClip(mirrorWorldToClip)
|
||||||
{
|
{
|
||||||
static PolyTriVertexShader shader;
|
static PolySWInputAssembly input;
|
||||||
PolyTriangleDrawer::SetVertexShader(thread->DrawQueue, &shader);
|
PolyTriangleDrawer::SetInputAssembly(thread->DrawQueue, &input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SWModelRenderer::AddLights(AActor *actor)
|
void SWModelRenderer::AddLights(AActor *actor)
|
||||||
|
|
Loading…
Reference in a new issue