mirror of
https://github.com/ZDoom/raze-gles.git
synced 2025-01-12 11:10:39 +00:00
- fixed VP8 video player.
Also do the color space conversion on the CPU to avoid the shader hassle, performance wise it is utterly irrelevant here.
This commit is contained in:
parent
2e06ccfec6
commit
8cd9775513
8 changed files with 90 additions and 133 deletions
|
@ -10,6 +10,9 @@
|
||||||
|
|
||||||
#include "matrix.h"
|
#include "matrix.h"
|
||||||
#include "../../glbackend/glbackend.h"
|
#include "../../glbackend/glbackend.h"
|
||||||
|
#include "textures.h"
|
||||||
|
#include "bitmap.h"
|
||||||
|
#include "v_draw.h"
|
||||||
|
|
||||||
#undef UNUSED
|
#undef UNUSED
|
||||||
#define VPX_CODEC_DISABLE_COMPAT 1
|
#define VPX_CODEC_DISABLE_COMPAT 1
|
||||||
|
@ -17,6 +20,74 @@
|
||||||
#include <vpx/vp8dx.h>
|
#include <vpx/vp8dx.h>
|
||||||
#include "animvpx.h"
|
#include "animvpx.h"
|
||||||
|
|
||||||
|
|
||||||
|
class VPXTexture : public FTexture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VPXTexture();
|
||||||
|
void SetFrame(const void* data, int width, int height);
|
||||||
|
virtual FBitmap GetBgraBitmap(const PalEntry* remap, int* trans) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
const void* data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
VPXTexture::VPXTexture() {}
|
||||||
|
|
||||||
|
void VPXTexture::SetFrame(const void *data_, int width, int height)
|
||||||
|
{
|
||||||
|
Size.x = width;
|
||||||
|
Size.y = height;
|
||||||
|
data = data_;
|
||||||
|
DeleteHardwareTextures();
|
||||||
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
//
|
||||||
|
// FPNGTexture::CopyPixels
|
||||||
|
//
|
||||||
|
//===========================================================================
|
||||||
|
|
||||||
|
FBitmap VPXTexture::GetBgraBitmap(const PalEntry* remap, int* trans)
|
||||||
|
{
|
||||||
|
FBitmap bmp;
|
||||||
|
|
||||||
|
bmp.Create(Size.x, Size.y);
|
||||||
|
|
||||||
|
auto spix = (uint8_t*)data;
|
||||||
|
auto dpix = bmp.GetPixels();
|
||||||
|
for (int i = 0; i < Size.x * Size.y; i++)
|
||||||
|
{
|
||||||
|
int p = i * 4;
|
||||||
|
float y = spix[p] * (1/255.f);
|
||||||
|
float u = spix[p+1] * (1 / 255.f) - 0.5f;
|
||||||
|
float v = spix[p+2] * (1 / 255.f) - 0.5f;
|
||||||
|
|
||||||
|
y = 1.1643f * (y - 0.0625f);
|
||||||
|
|
||||||
|
float r = y + 1.5958f * v;
|
||||||
|
float g = y - 0.39173f * u - 0.81290f * v;
|
||||||
|
float b = y + 2.017f * u;
|
||||||
|
|
||||||
|
dpix[p + 0] = (uint8_t)(clamp(b, 0, 1.f) * 255);
|
||||||
|
dpix[p + 1] = (uint8_t)(clamp(g, 0, 1.f) * 255);
|
||||||
|
dpix[p + 2] = (uint8_t)(clamp(r, 0, 1.f) * 255);
|
||||||
|
dpix[p + 3] = 255;
|
||||||
|
}
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const char *animvpx_read_ivf_header_errmsg[] = {
|
const char *animvpx_read_ivf_header_errmsg[] = {
|
||||||
"All OK",
|
"All OK",
|
||||||
"couldn't read 32-byte IVF header",
|
"couldn't read 32-byte IVF header",
|
||||||
|
@ -339,28 +410,13 @@ read_ivf_frame:
|
||||||
|
|
||||||
|
|
||||||
/////////////// DRAWING! ///////////////
|
/////////////// DRAWING! ///////////////
|
||||||
static FHardwareTexture* texture;
|
|
||||||
static int sampler;
|
static int sampler;
|
||||||
static int32_t texuploaded;
|
static VPXTexture* vpxtex;
|
||||||
|
|
||||||
void animvpx_setup_glstate(int32_t animvpx_flags)
|
void animvpx_setup_glstate(int32_t animvpx_flags)
|
||||||
{
|
{
|
||||||
static char logbuf[512];
|
|
||||||
|
|
||||||
GLInterface.SetVPXShader();
|
|
||||||
|
|
||||||
|
|
||||||
////////// GL STATE //////////
|
////////// GL STATE //////////
|
||||||
|
vpxtex = new VPXTexture;
|
||||||
//Force fullscreen (glox1=-1 forces it to restore afterwards)
|
|
||||||
GLInterface.SetViewport(0,0,xdim,ydim); glox1 = -1;
|
|
||||||
|
|
||||||
GLInterface.EnableAlphaTest(false);
|
|
||||||
GLInterface.EnableDepthTest(false);
|
|
||||||
GLInterface.EnableBlend(false);
|
|
||||||
GLInterface.SetCull(Cull_None);
|
|
||||||
|
|
||||||
texture = GLInterface.NewTexture();
|
|
||||||
|
|
||||||
if ((animvpx_flags & CUTSCENE_TEXTUREFILTER && hw_texfilter == TEXFILTER_ON) || animvpx_flags & CUTSCENE_FORCEFILTER ||
|
if ((animvpx_flags & CUTSCENE_TEXTUREFILTER && hw_texfilter == TEXFILTER_ON) || animvpx_flags & CUTSCENE_FORCEFILTER ||
|
||||||
(!(animvpx_flags & CUTSCENE_TEXTUREFILTER) && !(animvpx_flags & CUTSCENE_FORCENOFILTER))) // if no flags, then use filter for IVFs
|
(!(animvpx_flags & CUTSCENE_TEXTUREFILTER) && !(animvpx_flags & CUTSCENE_FORCENOFILTER))) // if no flags, then use filter for IVFs
|
||||||
|
@ -372,18 +428,14 @@ void animvpx_setup_glstate(int32_t animvpx_flags)
|
||||||
sampler = SamplerNoFilterClampXY;
|
sampler = SamplerNoFilterClampXY;
|
||||||
}
|
}
|
||||||
|
|
||||||
texuploaded = 0;
|
|
||||||
////////////////////
|
|
||||||
|
|
||||||
GLInterface.ClearScreen(0, true);
|
GLInterface.ClearScreen(0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void animvpx_restore_glstate(void)
|
void animvpx_restore_glstate(void)
|
||||||
{
|
{
|
||||||
GLInterface.SetPolymostShader();
|
delete vpxtex;
|
||||||
delete texture;
|
vpxtex = nullptr;
|
||||||
texture = nullptr;
|
|
||||||
texuploaded = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t animvpx_render_frame(animvpx_codec_ctx *codec, double animvpx_aspect)
|
int32_t animvpx_render_frame(animvpx_codec_ctx *codec, double animvpx_aspect)
|
||||||
|
@ -396,13 +448,7 @@ int32_t animvpx_render_frame(animvpx_codec_ctx *codec, double animvpx_aspect)
|
||||||
if (codec->pic == NULL)
|
if (codec->pic == NULL)
|
||||||
return 2; // shouldn't happen
|
return 2; // shouldn't happen
|
||||||
|
|
||||||
if (!texuploaded)
|
vpxtex->SetFrame(codec->pic, codec->width, codec->height);
|
||||||
{
|
|
||||||
texture->CreateTexture(codec->width, codec->height, FHardwareTexture::TrueColor, false);
|
|
||||||
texuploaded = 1;
|
|
||||||
}
|
|
||||||
texture->LoadTexture(codec->pic);
|
|
||||||
GLInterface.BindTexture(0, texture, sampler);
|
|
||||||
|
|
||||||
float vid_wbyh = ((float)codec->width)/codec->height;
|
float vid_wbyh = ((float)codec->width)/codec->height;
|
||||||
if (animvpx_aspect > 0)
|
if (animvpx_aspect > 0)
|
||||||
|
@ -422,22 +468,9 @@ int32_t animvpx_render_frame(animvpx_codec_ctx *codec, double animvpx_aspect)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto data = GLInterface.AllocVertices(4);
|
x *= screen->GetWidth() / 2;
|
||||||
auto vt = data.second;
|
y *= screen->GetHeight() / 2;
|
||||||
|
DrawTexture(twod, vpxtex, screen->GetWidth() / 2 - int(x), screen->GetHeight()/2 - int(y), DTA_DestWidth, 2*int(x), DTA_DestHeight, 2*int(y), DTA_Masked, false, DTA_KeepRatio, true, TAG_DONE);
|
||||||
vt[0].SetTexCoord(0.0,1.0);
|
|
||||||
vt[0].SetVertex(-x, -y, 0.0);
|
|
||||||
|
|
||||||
vt[1].SetTexCoord(0.0,0.0);
|
|
||||||
vt[1].SetVertex(-x, y, 0.0);
|
|
||||||
|
|
||||||
vt[2].SetTexCoord(1.0,0.0);
|
|
||||||
vt[2].SetVertex(x, y, 0.0);
|
|
||||||
|
|
||||||
vt[3].SetTexCoord(1.0,1.0);
|
|
||||||
vt[3].SetVertex(x, -y, 0.0);
|
|
||||||
|
|
||||||
GLInterface.DrawIm(DT_TRIANGLE_FAN, data.first, 4);
|
|
||||||
|
|
||||||
t = timerGetTicks()-t;
|
t = timerGetTicks()-t;
|
||||||
codec->sumtimes[2] += t;
|
codec->sumtimes[2] += t;
|
||||||
|
|
|
@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "build.h"
|
#include "build.h"
|
||||||
|
#include "v_2ddrawer.h"
|
||||||
#include "../glbackend/glbackend.h"
|
#include "../glbackend/glbackend.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -303,6 +304,10 @@ int32_t Anim_Play(const char *fn)
|
||||||
// OSD_Printf("msecs per frame: %d\n", msecsperframe);
|
// OSD_Printf("msecs per frame: %d\n", msecsperframe);
|
||||||
|
|
||||||
GLInterface.EnableNonTransparent255(true);
|
GLInterface.EnableNonTransparent255(true);
|
||||||
|
|
||||||
|
// Dummy rotatesprite call. Without this the movie won't render. Apparently some state isn't initialized properly and gets reset by this.
|
||||||
|
// Needs to be investigated. Leave this in as a workaround for now...
|
||||||
|
rotatesprite_fs(int(160 * 65536), int(100 * 65536) + ((28) << 16), 65536L, 0, 2499, 0, 0, 10);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
nextframetime += msecsperframe;
|
nextframetime += msecsperframe;
|
||||||
|
@ -325,7 +330,7 @@ int32_t Anim_Play(const char *fn)
|
||||||
|
|
||||||
VM_OnEventWithReturn(EVENT_PRECUTSCENE, g_player[screenpeek].ps->i, screenpeek, framenum);
|
VM_OnEventWithReturn(EVENT_PRECUTSCENE, g_player[screenpeek].ps->i, screenpeek, framenum);
|
||||||
|
|
||||||
videoClearScreen(0);
|
twod->ClearScreen();
|
||||||
|
|
||||||
ototalclock = totalclock + 1; // pause game like ANMs
|
ototalclock = totalclock + 1; // pause game like ANMs
|
||||||
|
|
||||||
|
@ -376,12 +381,7 @@ int32_t Anim_Play(const char *fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this and showframe() instead of nextpage() are so that
|
videoNextPage();
|
||||||
// nobody tramples on our carefully set up GL state!
|
|
||||||
palfadedelta = 0;
|
|
||||||
videoShowFrame(0);
|
|
||||||
|
|
||||||
// inputState.ClearAllInput();
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|
|
@ -92,7 +92,6 @@ void GLInstance::Init(int ydim)
|
||||||
|
|
||||||
new(&renderState) PolymostRenderState; // reset to defaults.
|
new(&renderState) PolymostRenderState; // reset to defaults.
|
||||||
LoadSurfaceShader();
|
LoadSurfaceShader();
|
||||||
LoadVPXShader();
|
|
||||||
LoadPolymostShader();
|
LoadPolymostShader();
|
||||||
#if 0
|
#if 0
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
|
@ -128,19 +127,6 @@ void GLInstance::LoadPolymostShader()
|
||||||
SetPolymostShader();
|
SetPolymostShader();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLInstance::LoadVPXShader()
|
|
||||||
{
|
|
||||||
auto fr1 = GetResource("engine/shaders/glsl/animvpx.vp");
|
|
||||||
TArray<uint8_t> Vert = fr1.Read();
|
|
||||||
fr1 = GetResource("engine/shaders/glsl/animvpx.fp");
|
|
||||||
TArray<uint8_t> Frag = fr1.Read();
|
|
||||||
// Zero-terminate both strings.
|
|
||||||
Vert.Push(0);
|
|
||||||
Frag.Push(0);
|
|
||||||
vpxShader = new FShader();
|
|
||||||
vpxShader->Load("VPXShader", (const char*)Vert.Data(), (const char*)Frag.Data());
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLInstance::LoadSurfaceShader()
|
void GLInstance::LoadSurfaceShader()
|
||||||
{
|
{
|
||||||
auto fr1 = GetResource("engine/shaders/glsl/glsurface.vp");
|
auto fr1 = GetResource("engine/shaders/glsl/glsurface.vp");
|
||||||
|
@ -194,8 +180,6 @@ void GLInstance::Deinit()
|
||||||
polymostShader = nullptr;
|
polymostShader = nullptr;
|
||||||
if (surfaceShader) delete surfaceShader;
|
if (surfaceShader) delete surfaceShader;
|
||||||
surfaceShader = nullptr;
|
surfaceShader = nullptr;
|
||||||
if (vpxShader) delete vpxShader;
|
|
||||||
vpxShader = nullptr;
|
|
||||||
activeShader = nullptr;
|
activeShader = nullptr;
|
||||||
palmanager.DeleteAllTextures();
|
palmanager.DeleteAllTextures();
|
||||||
lastPalswapIndex = -1;
|
lastPalswapIndex = -1;
|
||||||
|
@ -349,15 +333,6 @@ void GLInstance::SetSurfaceShader()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLInstance::SetVPXShader()
|
|
||||||
{
|
|
||||||
if (activeShader != vpxShader)
|
|
||||||
{
|
|
||||||
vpxShader->Bind();
|
|
||||||
activeShader = vpxShader;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLInstance::SetPalette(int index)
|
void GLInstance::SetPalette(int index)
|
||||||
{
|
{
|
||||||
palmanager.BindPalette(index);
|
palmanager.BindPalette(index);
|
||||||
|
|
|
@ -202,7 +202,6 @@ class GLInstance
|
||||||
FShader* activeShader;
|
FShader* activeShader;
|
||||||
PolymostShader* polymostShader;
|
PolymostShader* polymostShader;
|
||||||
SurfaceShader* surfaceShader;
|
SurfaceShader* surfaceShader;
|
||||||
FShader* vpxShader;
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -213,7 +212,6 @@ public:
|
||||||
void InitGLState(int fogmode, int multisample);
|
void InitGLState(int fogmode, int multisample);
|
||||||
void LoadPolymostShader();
|
void LoadPolymostShader();
|
||||||
void LoadSurfaceShader();
|
void LoadSurfaceShader();
|
||||||
void LoadVPXShader();
|
|
||||||
void Draw2D(F2DDrawer* drawer);
|
void Draw2D(F2DDrawer* drawer);
|
||||||
void DrawImGui(ImDrawData*);
|
void DrawImGui(ImDrawData*);
|
||||||
void ResetFrame();
|
void ResetFrame();
|
||||||
|
@ -262,7 +260,6 @@ public:
|
||||||
|
|
||||||
void SetPolymostShader();
|
void SetPolymostShader();
|
||||||
void SetSurfaceShader();
|
void SetSurfaceShader();
|
||||||
void SetVPXShader();
|
|
||||||
void SetPalette(int palette);
|
void SetPalette(int palette);
|
||||||
|
|
||||||
void ReadPixels(int w, int h, uint8_t* buffer);
|
void ReadPixels(int w, int h, uint8_t* buffer);
|
||||||
|
|
|
@ -172,15 +172,14 @@ void GLInstance::Draw2D(F2DDrawer *drawer)
|
||||||
SetShade(cmd.mRemapIndex >> 16, numshades);
|
SetShade(cmd.mRemapIndex >> 16, numshades);
|
||||||
SetFadeDisable(false);
|
SetFadeDisable(false);
|
||||||
SetTexture(0, tex, cmd.mRemapIndex & 0xffff, 4/*DAMETH_CLAMPED*/, cmd.mFlags & F2DDrawer::DTF_Wrap ? SamplerRepeat : SamplerClampXY);
|
SetTexture(0, tex, cmd.mRemapIndex & 0xffff, 4/*DAMETH_CLAMPED*/, cmd.mFlags & F2DDrawer::DTF_Wrap ? SamplerRepeat : SamplerClampXY);
|
||||||
EnableBlend(!(cmd.mRenderStyle.Flags & STYLEF_Alpha1));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SetFadeDisable(true);
|
SetFadeDisable(true);
|
||||||
SetShade(0, numshades);
|
SetShade(0, numshades);
|
||||||
SetNamedTexture(cmd.mTexture, cmd.mRemapIndex, cmd.mFlags & F2DDrawer::DTF_Wrap ? SamplerRepeat : SamplerClampXY);
|
SetNamedTexture(cmd.mTexture, cmd.mRemapIndex, cmd.mFlags & F2DDrawer::DTF_Wrap ? SamplerRepeat : SamplerClampXY);
|
||||||
EnableBlend(true);
|
|
||||||
}
|
}
|
||||||
|
EnableBlend(!(cmd.mRenderStyle.Flags & STYLEF_Alpha1));
|
||||||
UseColorOnly(false);
|
UseColorOnly(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "animlib.h"
|
#include "animlib.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "cmdlib.h"
|
#include "cmdlib.h"
|
||||||
|
#include "v_2ddrawer.h"
|
||||||
#include "../glbackend/glbackend.h"
|
#include "../glbackend/glbackend.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -359,7 +360,7 @@ int32_t Anim_Play(const char *fn)
|
||||||
if (!pic)
|
if (!pic)
|
||||||
break; // no more pics!
|
break; // no more pics!
|
||||||
|
|
||||||
videoClearScreen(0);
|
twod->ClearScreen();
|
||||||
|
|
||||||
ototalclock = totalclock + 1; // pause game like ANMs
|
ototalclock = totalclock + 1; // pause game like ANMs
|
||||||
|
|
||||||
|
@ -408,13 +409,7 @@ int32_t Anim_Play(const char *fn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this and showframe() instead of nextpage() are so that
|
videoNextPage();
|
||||||
// nobody tramples on our carefully set up GL state!
|
|
||||||
palfadedelta = 0;
|
|
||||||
videoShowFrame(0);
|
|
||||||
|
|
||||||
// inputState.ClearAllInput();
|
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
G_HandleAsync();
|
G_HandleAsync();
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
// YUV->RGB conversion fragment shader adapted from
|
|
||||||
// http://www.fourcc.org/fccyvrgb.php: Want some sample code?
|
|
||||||
// direct link: http://www.fourcc.org/source/YUV420P-OpenGL-GLSLang.c
|
|
||||||
#version 330
|
|
||||||
|
|
||||||
uniform sampler2D tex;
|
|
||||||
in vec2 v_texCoord;
|
|
||||||
out vec4 FragColor;
|
|
||||||
|
|
||||||
void main(void) {
|
|
||||||
|
|
||||||
float r,g,b,y,u,v;
|
|
||||||
vec3 yuv;
|
|
||||||
|
|
||||||
yuv = texture2D(tex, v_texCoord.st).rgb;
|
|
||||||
y = yuv.r;
|
|
||||||
u = yuv.g;
|
|
||||||
v = yuv.b;
|
|
||||||
|
|
||||||
y = 1.1643*(y-0.0625);
|
|
||||||
u = u-0.5;
|
|
||||||
v = v-0.5;
|
|
||||||
|
|
||||||
r = y + 1.5958*v;
|
|
||||||
g = y - 0.39173*u - 0.81290*v;
|
|
||||||
b = y + 2.017*u;
|
|
||||||
|
|
||||||
FragColor = vec4(r,g,b,1.0);
|
|
||||||
};
|
|
|
@ -1,13 +0,0 @@
|
||||||
#version 330
|
|
||||||
|
|
||||||
in vec4 i_vertPos;
|
|
||||||
in vec4 i_texCoord;
|
|
||||||
|
|
||||||
out vec2 v_texCoord;
|
|
||||||
|
|
||||||
void main()
|
|
||||||
{
|
|
||||||
gl_Position = i_vertPos;
|
|
||||||
v_texCoord = i_texCoord.st;
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue