Implement burn.fp and second texture binding

This commit is contained in:
Magnus Norddahl 2019-12-01 21:44:44 +01:00
parent 2c751d214f
commit 1b9479ea45
6 changed files with 67 additions and 13 deletions

View file

@ -233,7 +233,17 @@ void PolyRenderState::ApplyMaterial()
if (base)
{
DCanvas *texcanvas = base->GetImage(mMaterial);
PolyTriangleDrawer::SetTexture(GetPolyFrameBuffer()->GetDrawCommands(), texcanvas->GetPixels(), texcanvas->GetHeight(), texcanvas->GetWidth());
PolyTriangleDrawer::SetTexture(GetPolyFrameBuffer()->GetDrawCommands(), 0, texcanvas->GetPixels(), texcanvas->GetHeight(), texcanvas->GetWidth());
int numLayers = mMaterial.mMaterial->GetLayers();
for (int i = 1; i < numLayers; i++)
{
FTexture* layer;
auto systex = static_cast<PolyHardwareTexture*>(mMaterial.mMaterial->GetLayer(i, 0, &layer));
texcanvas = systex->GetImage(mMaterial);
PolyTriangleDrawer::SetTexture(GetPolyFrameBuffer()->GetDrawCommands(), i, texcanvas->GetPixels(), texcanvas->GetHeight(), texcanvas->GetWidth());
}
}
mMaterial.mChanged = false;

View file

@ -59,6 +59,13 @@ void PolyDrawArgs::SetTexture(FSoftwareTexture *texture, FRenderStyle style)
mTranslation = nullptr;
}
void PolyDrawArgs::SetTexture2(const uint8_t* texels, int width, int height)
{
mTexture2Pixels = texels;
mTexture2Width = width;
mTexture2Height = height;
}
void PolyDrawArgs::SetTexture(FSoftwareTexture *texture, uint32_t translationID, FRenderStyle style)
{
// Alphatexture overrides translations.

View file

@ -71,6 +71,7 @@ public:
void SetTexture(const uint8_t *texels, int width, int height);
void SetTexture(FSoftwareTexture *texture, FRenderStyle style);
void SetTexture(FSoftwareTexture *texture, uint32_t translationID, FRenderStyle style);
void SetTexture2(const uint8_t* texels, int width, int height);
void SetLight(FSWColormap *basecolormap, uint32_t lightlevel, double globVis, bool fixed);
void SetNoColormap() { mLight = 255; mFixedLight = true; mLightRed = 256; mLightGreen = 256; mLightBlue = 256; mLightAlpha = 256; mFadeRed = 0; mFadeGreen = 0; mFadeBlue = 0; mFadeAlpha = 0; mDesaturate = 0; mSimpleShade = true; mColormaps = nullptr; }
void SetDepthTest(bool enable) { mDepthTest = enable; }
@ -95,6 +96,10 @@ public:
int TextureHeight() const { return mTextureHeight; }
const uint8_t *Translation() const { return mTranslation; }
const uint8_t* Texture2Pixels() const { return mTexture2Pixels; }
int Texture2Width() const { return mTexture2Width; }
int Texture2Height() const { return mTexture2Height; }
bool WriteStencil() const { return mWriteStencil; }
bool StencilTest() const { return mStencilTest; }
uint8_t StencilTestValue() const { return mStencilTestValue; }
@ -142,6 +147,9 @@ private:
int mTextureWidth = 0;
int mTextureHeight = 0;
const uint8_t *mTranslation = nullptr;
const uint8_t* mTexture2Pixels = nullptr;
int mTexture2Width = 0;
int mTexture2Height = 0;
uint8_t mStencilTestValue = 0;
uint8_t mStencilWriteValue = 0;
const uint8_t *mColormaps = nullptr;

View file

@ -183,9 +183,9 @@ void PolyTriangleDrawer::SetRenderStyle(const DrawerCommandQueuePtr &queue, FRen
queue->Push<PolySetRenderStyleCommand>(style);
}
void PolyTriangleDrawer::SetTexture(const DrawerCommandQueuePtr &queue, void *pixels, int width, int height)
void PolyTriangleDrawer::SetTexture(const DrawerCommandQueuePtr &queue, int unit, void *pixels, int width, int height)
{
queue->Push<PolySetTextureCommand>(pixels, width, height);
queue->Push<PolySetTextureCommand>(unit, pixels, width, height);
}
void PolyTriangleDrawer::SetShader(const DrawerCommandQueuePtr &queue, int specialEffect, int effectState, bool alphaTest)
@ -446,9 +446,12 @@ void PolyTriangleThreadData::SetShader(int specialEffect, int effectState, bool
AlphaTest = alphaTest;
}
void PolyTriangleThreadData::SetTexture(void *pixels, int width, int height)
void PolyTriangleThreadData::SetTexture(int unit, void *pixels, int width, int height)
{
drawargs.SetTexture((uint8_t*)pixels, width, height);
if (unit == 0)
drawargs.SetTexture((uint8_t*)pixels, width, height);
else if (unit == 1)
drawargs.SetTexture2((uint8_t*)pixels, width, height);
}
void PolyTriangleThreadData::DrawIndexed(int index, int vcount, PolyDrawMode drawmode)

View file

@ -57,7 +57,7 @@ public:
static void SetScissor(const DrawerCommandQueuePtr &queue, int x, int y, int w, int h);
static void EnableDepthTest(const DrawerCommandQueuePtr &queue, bool on);
static void SetRenderStyle(const DrawerCommandQueuePtr &queue, FRenderStyle style);
static void SetTexture(const DrawerCommandQueuePtr &queue, void *pixels, int width, int height);
static void SetTexture(const DrawerCommandQueuePtr &queue, int unit, void *pixels, int width, int height);
static void SetShader(const DrawerCommandQueuePtr &queue, int specialEffect, int effectState, bool alphaTest);
static void PushStreamData(const DrawerCommandQueuePtr &queue, const StreamData &data, const PolyPushConstants &constants);
static void PushMatrices(const DrawerCommandQueuePtr &queue, const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix);
@ -159,7 +159,7 @@ public:
void SetScissor(int x, int y, int w, int h);
void EnableDepthTest(bool on);
void SetRenderStyle(FRenderStyle style);
void SetTexture(void *pixels, int width, int height);
void SetTexture(int unit, void *pixels, int width, int height);
void SetShader(int specialEffect, int effectState, bool alphaTest);
void UpdateClip();
@ -423,10 +423,11 @@ private:
class PolySetTextureCommand : public PolyDrawerCommand
{
public:
PolySetTextureCommand(void *pixels, int width, int height) : pixels(pixels), width(width), height(height) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetTexture(pixels, width, height); }
PolySetTextureCommand(int unit, void *pixels, int width, int height) : unit(unit), pixels(pixels), width(width), height(height) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetTexture(unit, pixels, width, height); }
private:
int unit;
void *pixels;
int width;
int height;

View file

@ -375,10 +375,35 @@ static void RunShader(int x0, int x1, PolyTriangleThreadData* thread)
}
else if (thread->SpecialEffect == EFF_BURN) // burn.fp
{
/*vec4 frag = vColor;
vec4 t1 = texture(tex, vTexCoord.xy);
vec4 t2 = texture(texture2, vec2(vTexCoord.x, 1.0-vTexCoord.y));
FragColor = frag * vec4(t1.rgb, t2.a);*/
int texWidth = thread->drawargs.TextureWidth();
int texHeight = thread->drawargs.TextureHeight();
const uint32_t* texPixels = (const uint32_t*)thread->drawargs.TexturePixels();
int tex2Width = thread->drawargs.Texture2Width();
int tex2Height = thread->drawargs.Texture2Height();
const uint32_t* tex2Pixels = (const uint32_t*)thread->drawargs.Texture2Pixels();
uint32_t frag = thread->mainVertexShader.vColor;
uint32_t frag_r = RPART(frag);
uint32_t frag_g = GPART(frag);
uint32_t frag_b = BPART(frag);
uint32_t frag_a = APART(frag);
frag_r += frag_r >> 7; // 255 -> 256
frag_g += frag_g >> 7; // 255 -> 256
frag_b += frag_b >> 7; // 255 -> 256
frag_a += frag_a >> 7; // 255 -> 256
for (int x = x0; x < x1; x++)
{
uint32_t t1 = sampleTexture(u[x], v[x], texPixels, texWidth, texHeight);
uint32_t t2 = sampleTexture(u[x], 1.0f - v[x], tex2Pixels, tex2Width, tex2Height);
uint32_t r = (frag_r * RPART(t1)) >> 8;
uint32_t g = (frag_g * GPART(t1)) >> 8;
uint32_t b = (frag_b * BPART(t1)) >> 8;
uint32_t a = (frag_a * APART(t2)) >> 8;
fragcolor[x] = MAKEARGB(a, r, g, b);
}
return;
}
else if (thread->SpecialEffect == EFF_STENCIL) // stencil.fp