Irrlicht Bink Shader

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
caburfoot
Posts: 22
Joined: Mon Aug 08, 2011 6:15 am

Irrlicht Bink Shader

Post by caburfoot »

I have several issues moving the following code (which works) to Irrlich :

Code: Select all

 
// bikplayer.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include <windows.h>
 
 
#include "bink.h"
#include "GLee.h"
#include <gl/gl.h>
#include <gl/glu.h>
#include "glut.h"
#include <malloc.h>
//#include <Carbon/Carbon.h>
 
static GLuint s_Textures[4];
static HBINK s_Bink = 0;
static char* s_TextureMem = 0;
static char* s_TextOutMem = 0;
static S32 s_HasAlpha = 0;
static S32 s_TextureWidth = 0;
static S32 s_TextureHeight = 0;
 
 
// Shader stuff
static S32 s_UseShaders = 0;
static GLhandleARB s_Program = 0;
static GLhandleARB s_VertShader = 0;
static GLhandleARB s_FragShader = 0;
static S32 s_YTexIndex = 0;
static S32 s_cRTexIndex = 0;
static S32 s_cBTexIndex = 0;
static S32 s_ATexIndex = 0;
 
int gluCheckExtension( const U8 * pstofind, const unsigned char * pstrext )
{
        char * psub = strstr( (char*) pstrext, (const char *) pstofind);
        return (psub - (char *) pstrext);
}
 
#ifdef _DEBUG 
#define GLCHK CheckGLError()
 
char errbuff[256];
void CheckGLError()
{
        GLenum en = glGetError();
        if ( en != GL_NO_ERROR )
        {
                sprintf( errbuff, "GL Error %u", en );
                OutputDebugString( errbuff );
        }
 
}
#else
#define GLCHK
#endif
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
S32 Shader_CheckCaps()
{
        const unsigned char* extensions = glGetString(GL_EXTENSIONS);
 
        if (gluCheckExtension((const U8*)"GL_ARB_shader_objects", extensions) == 0) return 0;
        if (gluCheckExtension((const U8*)"GL_ARB_vertex_shader", extensions) == 0) return 0;
        if (gluCheckExtension((const U8*)"GL_ARB_fragment_shader", extensions) == 0) return 0;
        if (gluCheckExtension((const U8*)"GL_ARB_shading_language_100", extensions) == 0) return 0;
 
        return 1;
}
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
S32 Shader_Link(GLhandleARB i_Shader)
{
        S32 Success = 0;
 
        glLinkProgramARB(i_Shader);
        GLCHK;
        if (glGetError() != GL_NO_ERROR) return 0;
 
        glGetObjectParameterivARB(i_Shader, GL_OBJECT_LINK_STATUS_ARB, &Success);
        GLCHK;
        if (Success == 0) return 0;
 
        return 1;
}
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
S32 Shader_Compile(S32 i_Target, char* i_Source, GLhandleARB* o_Shader)
{
        if (i_Source == 0) return 0;
 
        *o_Shader = glCreateShaderObjectARB(i_Target);
        GLCHK;
        if (glGetError() != GL_NO_ERROR) 
                return 0;
 
        glShaderSourceARB(*o_Shader, 1, (const char**)&i_Source, 0);
        GLCHK;
        if (glGetError() != GL_NO_ERROR) 
                return 0;
 
        glCompileShaderARB(*o_Shader);
        GLCHK;
        if (glGetError() != GL_NO_ERROR) 
                return 0;
 
        {
                S32 Success = 0;
                glGetObjectParameterivARB(*o_Shader, GL_OBJECT_COMPILE_STATUS_ARB, &Success);
                GLCHK;
                if (Success == 0) 
                        return 0;
        }
        return 1;
}
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
S32 Shader_BuildOurShaders()
{
        char VertexShader[] =
                "void main(void)\n"
                "{\n"
                "   gl_TexCoord[0] = gl_MultiTexCoord0;\n"
                "       gl_Position = ftransform();\n"
                "}\n";
 
        char FragmentShader[] =
                "uniform sampler2D YTex;\n"
                "uniform sampler2D cRTex;\n"
                "uniform sampler2D cBTex;\n"
                "uniform sampler2D ATex;\n"
                "void main (void)\n"
                "{\n"
                "   const vec4 crc = vec4(1.595, -0.813, 0, 0);\n"
 
                "   const vec4 crb = vec4(0, -0.391, 2.017, 0);\n"
 
                "   const vec4 adj = vec4(-0.870, 0.529, -1.0816, 0);\n"
                "   float Y = texture2D(YTex, gl_TexCoord[0].st).x;\n"
                "   float cR = texture2D(cRTex, gl_TexCoord[0].st).x;\n"
                "   float cB = texture2D(cBTex, gl_TexCoord[0].st).x;\n"
                "   float A = texture2D(ATex, gl_TexCoord[0].st).x;\n"
                "   vec4 p;\n"
                "   p = vec4(Y * 1.164, Y * 1.164, Y * 1.164, 1);\n"
                "   p += crc * cR;\n"
                "   p += crb * cB;\n"
                "   p += adj;\n"
                "   p.w = A;\n"
                "   gl_FragColor = p;\n"
                "}\n";
 
 
        if (Shader_Compile(GL_VERTEX_SHADER_ARB, VertexShader, &s_VertShader) == 0)
        {
                printf("Couldn't compile vertex shader.\n");
                return 0;
        }
        if (Shader_Compile(GL_FRAGMENT_SHADER_ARB, FragmentShader, &s_FragShader) == 0)
        {
                printf("Couldn't compile fragment shader.\n");
                return 0;
        }
 
        s_Program = glCreateProgramObjectARB();
        GLCHK;
        glAttachObjectARB(s_Program, s_VertShader);
        GLCHK;
        glAttachObjectARB(s_Program, s_FragShader);
        GLCHK;
 
        if (Shader_Link(s_Program) == 0)
        {
                printf("Couldn't link shader.\n");
                return 0;
        }
 
        glUseProgramObjectARB(s_Program);
        GLCHK;
        s_YTexIndex = glGetUniformLocationARB(s_Program, "YTex");
        GLCHK;
        s_cRTexIndex = glGetUniformLocationARB(s_Program, "cRTex");
        GLCHK;
        s_cBTexIndex = glGetUniformLocationARB(s_Program, "cBTex");
        GLCHK;
        s_ATexIndex = glGetUniformLocationARB(s_Program, "ATex");
        GLCHK;
        return 1;
}
 
DWORD dwtotcalls = 0;
DWORD dwbikcopy = 0;
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void RenderBinkVid()
{
        char buffer[256];
 
        glClearColor(0, 0, 1, 1);
        GLCHK;
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        GLCHK;
        
        
        dwtotcalls++;
 
        int ic1 = 0, ic2 = 0;
        if (!BinkWait(s_Bink))
        {
                BinkDoFrame(s_Bink);
                dwbikcopy++;
 
                if (s_UseShaders)
                {
                        glActiveTextureARB(GL_TEXTURE0_ARB);
                        GLCHK;
                        glUniform1iARB(s_YTexIndex, 0);
                        GLCHK;
                        glBindTexture(GL_TEXTURE_2D, s_Textures[0]);
                        GLCHK;
                        glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth, s_TextureHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].YPlane.Buffer);
                        GLCHK;
 
                        glActiveTextureARB(GL_TEXTURE1_ARB);
                        glUniform1iARB(s_cRTexIndex, 1);
                        glBindTexture(GL_TEXTURE_2D, s_Textures[1]);
                        glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth/2, s_TextureHeight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].cRPlane.Buffer);
 
                        glActiveTextureARB(GL_TEXTURE2_ARB);
                        glUniform1iARB(s_cBTexIndex, 2);
                        glBindTexture(GL_TEXTURE_2D, s_Textures[2]);
                        glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth/2, s_TextureHeight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].cBPlane.Buffer);            
 
                        if (s_HasAlpha)
                        {
                                glActiveTextureARB(GL_TEXTURE3_ARB);
                                glUniform1iARB(s_ATexIndex, 3);
                                glBindTexture(GL_TEXTURE_2D, s_Textures[3]);
                                glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth, s_TextureHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].APlane.Buffer);
                        }
                        sprintf(buffer, "Bink Frame = %d  of %d > Totcalls = %u  Binkcalls = %u\n", s_Bink->FrameNum, s_Bink->Frames, dwtotcalls, dwbikcopy );
                        OutputDebugString( buffer );
                }
                else
                {
                        char buffer[256];
                        S32 bc = BinkCopyToBuffer(s_Bink, s_TextureMem, s_TextureWidth*4, s_Bink->Height, 0, 0, (s_HasAlpha ? BINKSURFACE32RA : BINKSURFACE32R));
                        sprintf(buffer, "Bink Frame = %d  of %d > Bink copy = %d  - Totcalls = %u  Binkcalls = %u\n", s_Bink->FrameNum, s_Bink->Frames, bc, dwtotcalls, dwbikcopy );
                        OutputDebugString( buffer );
 
                        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, s_TextureWidth, s_TextureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, s_TextureMem);
                        GLCHK;
 
 
                }
 
                BinkNextFrame(s_Bink);
        }
        else
        {
                Sleep( 10 ); // 1000
        }
 
        float verts[] = {
                -1, -1,
                1, -1,
                -1, 1,
                1, 1,
        };
 
        float v = s_Bink->Height / (float)s_TextureHeight;
        float u = s_Bink->Width / (float)s_TextureWidth;
        float uvs[] = {
                0, v,
                u, v,
                0, 0,
                u, 0
        };
 
        glVertexPointer(2, GL_FLOAT, 0, verts);
        GLCHK;
 
        if (s_UseShaders)
        {
                glClientActiveTextureARB(GL_TEXTURE0_ARB); 
                glTexCoordPointer(2, GL_FLOAT, 0, uvs);
                glClientActiveTextureARB(GL_TEXTURE1_ARB); 
                glTexCoordPointer(2, GL_FLOAT, 0, uvs);
                glClientActiveTextureARB(GL_TEXTURE2_ARB); 
                glTexCoordPointer(2, GL_FLOAT, 0, uvs);
                if (s_HasAlpha)
                {
                        glClientActiveTextureARB(GL_TEXTURE3_ARB); 
                        glTexCoordPointer(2, GL_FLOAT, 0, uvs);
                }
        }
        else
        {
                glTexCoordPointer(2, GL_FLOAT, 0, uvs);
                GLCHK;
        }
 
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        GLCHK;
 
        glFlush();
        GLCHK;
 
        glutSwapBuffers();
        GLCHK;
}
 
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int _tmain( int argc, char* argv[] )
{
        S32 ForceBlit = 1;
 
        if (argc == 1)
        {
                printf("Specify BINK video on the command line to play.\n");
                return 0;
        }
        int ilen = strlen( argv[1]);
 
        s_Bink = BinkOpen(argv[1], BINKALPHA);
        if (s_Bink == 0)
        {
                printf("Couldn't open %s\n", argv[1]);
                return 0;
        }
 
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA);
 
        glutInitWindowPosition(100, 100);
 
        glutInitWindowSize(s_Bink->Width, s_Bink->Height);
 
        glutCreateWindow("OpenGL Bink");
 
        glutDisplayFunc(RenderBinkVid);
 
        glutIdleFunc(RenderBinkVid);
 
 
        glGenTextures(4, s_Textures);
        GLCHK;
 
        s_HasAlpha = s_Bink->FrameBuffers[0].Frames[0].APlane.Allocate;
        if (s_HasAlpha)
        {
                glEnable(GL_BLEND);
                GLCHK;
                glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
                GLCHK;
        }
 
        //
        // Check for shader caps.
        //
        s_UseShaders = Shader_CheckCaps() && !ForceBlit;
        if (s_UseShaders)
        {
                if (Shader_BuildOurShaders() == 0)
                {
                        s_UseShaders = 0;
                }
                else
                {
                        // Setup the other texture units.
                        glActiveTextureARB(GL_TEXTURE0_ARB);
                        GLCHK;
                        glEnable(GL_TEXTURE_2D);
                        GLCHK;
                        glBindTexture(GL_TEXTURE_2D, s_Textures[0]);
                        GLCHK;
                        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                        GLCHK;
                        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                        GLCHK;
                        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                        GLCHK;
 
                        glActiveTextureARB(GL_TEXTURE1_ARB);
                        GLCHK;
                        glEnable(GL_TEXTURE_2D);
                        GLCHK;
                        glBindTexture(GL_TEXTURE_2D, s_Textures[1]);
                        GLCHK;
                        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                        GLCHK;
                        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                        GLCHK;
                        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                        GLCHK;
 
                        glActiveTextureARB(GL_TEXTURE2_ARB);
                        GLCHK;
                        glEnable(GL_TEXTURE_2D);
                        GLCHK;
                        glBindTexture(GL_TEXTURE_2D, s_Textures[2]);
                        GLCHK;
                        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                        GLCHK;
                        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                        GLCHK;
                        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                        GLCHK;
 
                        if (s_HasAlpha)
                        {
                                glActiveTextureARB(GL_TEXTURE3_ARB);
                                GLCHK;
                                glEnable(GL_TEXTURE_2D);
                                GLCHK;
                                glBindTexture(GL_TEXTURE_2D, s_Textures[3]);
                                GLCHK;
                                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                                GLCHK;
                                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                                GLCHK;
                                glEnableClientState(GL_TEXTURE_COORD_ARRAY);        
                                GLCHK;
                        }
                }
        }
 
        s_TextureHeight = s_Bink->Height;
        s_TextureWidth = s_Bink->Width;
 
        // Only allocate the blit space if we aren't using shaders.
        if (s_UseShaders == 0)
        {
                s_TextureMem = (char *) malloc(s_TextureWidth * s_TextureHeight * 4);
                s_TextOutMem = (char *) malloc(s_TextureWidth * s_TextureHeight * 4);
                memset(s_TextureMem, 0, s_TextureWidth * s_TextureHeight * 4);
                memset(s_TextOutMem, 0, s_TextureWidth * s_TextureHeight * 4);
 
                glEnable(GL_TEXTURE_2D);
                GLCHK;
                glBindTexture(GL_TEXTURE_2D, s_Textures[0]);
                GLCHK;
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                GLCHK;
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                GLCHK;
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                GLCHK;
        }
 
        glEnableClientState(GL_VERTEX_ARRAY);
        GLCHK;
        
        glutMainLoop();
 
        if (s_TextureMem) free(s_TextureMem);
        glDeleteTextures(4, s_Textures);
        BinkClose(s_Bink);
        s_Bink = 0;
        s_TextureMem = 0;
        char buff[256];
        sprintf(buff, "Total = %u   Bik=%u", dwtotcalls, dwbikcopy );
        OutputDebugString( buff );
 
        return 0;
}
 
I've been modifying the 10.Shaders example to determine how to do this.

I've added the following :

Code: Select all

 
s32 s_UseShaders = false;
video::IVideoDriver * driver = NULL;
 
video::ITexture * yTex = NULL;
video::ITexture * cRTex = NULL;
video::ITexture * cBTex = NULL;
video::ITexture * ATex = NULL;
video::ITexture * pblt = NULL;
 
 
void RenderBinkVid( video::IMaterialRendererServices* services )
{
        glClearColor(0, 0, 1, 1);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        GLint tids[4] = {0, 1, 2, 3 };
        S32 s_TextureWidth = s_Bink->Width;
        S32 s_TextureHeight = s_Bink->Height;
        size_t tsize = s_Bink->Width * s_Bink->Height;
 
        if (!BinkWait(s_Bink))
        {
                BinkDoFrame(s_Bink);
 
                if (s_UseShaders)
                {
                        glActiveTextureARB(GL_TEXTURE0_ARB);
                        //glUniform1iARB(s_YTexIndex, 0);
                        services->setPixelShaderConstant("YTex", (float*) tids, 1 );
                        u8* pdata = (u8*) yTex->lock();
                        //memcpy( pdata, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].YPlane.Buffer,tsize);
                        yTex->unlock();
                        //glBindTexture(GL_TEXTURE_2D, s_Textures[0]);
                        glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth, s_TextureHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].YPlane.Buffer);
 
 
                        glActiveTextureARB(GL_TEXTURE1_ARB);
                        //glUniform1iARB(s_cRTexIndex, 1);
                        services->setPixelShaderConstant("cRTex", (float*) tids + 1, 1 );
                        //glBindTexture(GL_TEXTURE_2D, s_Textures[1]);
                        //glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth/2, s_TextureHeight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].cRPlane.Buffer);
                        pdata = (u8*)cRTex->lock();
                        //memcpy( pdata, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].cRPlane.Buffer,tsize / 4);
                        cRTex->unlock();
                        glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth/2, s_TextureHeight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].cRPlane.Buffer);
                        
                        glActiveTextureARB(GL_TEXTURE2_ARB);
                        //glUniform1iARB(s_cBTexIndex, 2);
                        services->setPixelShaderConstant("cBTex", (float*) tids + 2, 1 );
                        //glBindTexture(GL_TEXTURE_2D, s_Textures[2]);
                        //glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth/2, s_TextureHeight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].cBPlane.Buffer);            
                        pdata = (u8*)cBTex->lock();
                        //memcpy( pdata, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].cRPlane.Buffer,tsize/4);
                        cBTex->unlock();
                        glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth/2, s_TextureHeight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].cBPlane.Buffer);            
 
                        if (s_HasAlpha)
                        {
                                glActiveTextureARB(GL_TEXTURE3_ARB);
                                //glUniform1iARB(s_ATexIndex, 3);
                                services->setPixelShaderConstant("ATex", (float*) tids + 2, 1 );
                                //glBindTexture(GL_TEXTURE_2D, s_Textures[3]);
                                //glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth, s_TextureHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].APlane.Buffer);
                                pdata = (u8*)ATex->lock();
                                //memcpy( pdata, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].APlane.Buffer,tsize);
                                ATex->unlock();
                                glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth, s_TextureHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].APlane.Buffer);
 
                        }
                }
                
                BinkNextFrame(s_Bink);
        }
        else
        {
                Sleep( 10 ); // 1000
        }
 
}
 
class BinkShader : public video::IShaderConstantSetCallBack
{
public:
 
        virtual void OnSetConstants(video::IMaterialRendererServices* services,
                s32 userData)
        {
 
                RenderBinkVid( services );
 
        }
};
 
I've intialized the ITextures and Material with :

Code: Select all

 
 
BinkShader * pbs = new BinkShader();
s32 bikMat =  gpu->addHighLevelShaderMaterialFromFiles( 
                                bikvsname, "vertexMain", video::EVST_VS_1_1,
                                bikpsname, "pixelMain", video::EPST_PS_1_1,
                                pbs, video::EMT_SOLID ); 
 
 
video::ITexture * prt1 = driver->addRenderTargetTexture(core::dimension2d<u32>(s_Bink->Width, s_Bink->Height), "rt1", video::ECF_A8R8G8B8);
 
pblt = driver->addTexture( core::dimension2d<u32>( s_Bink->Width, s_Bink->Height) , "blt", irr::video::ECF_A8R8G8B8); //irr::video::ECF_R8G8B8);
yTex = driver->addTexture( core::dimension2d<u32>( s_Bink->Width/4, s_Bink->Height) , "YTex", irr::video::ECF_A8R8G8B8); //irr::video::ECF_R8G8B8);
cRTex = driver->addTexture( core::dimension2d<u32>( s_Bink->Width/8, s_Bink->Height) , "cRTex", irr::video::ECF_A8R8G8B8); //irr::video::ECF_R8G8B8);
cBTex = driver->addTexture( core::dimension2d<u32>( s_Bink->Width/8, s_Bink->Height) , "cBTex", irr::video::ECF_A8R8G8B8); //irr::video::ECF_R8G8B8);
ATex = driver->addTexture( core::dimension2d<u32>( s_Bink->Width/4, s_Bink->Height) , "ATex", irr::video::ECF_A8R8G8B8); //irr::video::ECF_R8G8B8);
 
 
What I'm not sure of is :

Q1 ) Use standard texture or rendertexture or does it matter ?
Q2) Faster way to set the active texture than Lock()/unlock() ? COpenGLDriver HAS a non-vritual method to setActiveTexture() but it's NOT exposed by the base.
Q3) Use irrlicht ITextures or just leave those 4 allocated by OpenGL?
Q4) Why don't services have a getpixelshaderconstant() so we can minimize the number of loop checks - this could get expensive when there's LOTs of textures?

Your thoughts and feedback are appreciated
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Irrlicht Bink Shader

Post by hybrid »

Maybe you could first summarize what you want to do. For now we'd have to compare some pure gl code with mixed gl/Irrlicht code. This seems both not the best way to get the best result. But here are at least some hints:
1)Use RenderTargetTexture if you want to render into the texture (using some Irrlicht commands such as draw2dimage or drawAll), i.e. if you need to use this texture in the setRenderTarget call. otherwise the normal texture should do ok.
2)If you want to set a texture to be active, add it to a material and call setMaterial. Lock and unlock is very expensive and is only meant for altering the texture content manually on the CPU, or to read the texture out after it is copied from GPU to CPU.
3)You don't need gl calls at all. Just use the ITextures and SMaterial to enable textures
4)Since you set the constants, you should know what you chose as value. Read back is always expensive.
caburfoot
Posts: 22
Joined: Mon Aug 08, 2011 6:15 am

Re: Irrlicht Bink Shader

Post by caburfoot »

Thanks for the Thoughts hybrid!

1) What I 'want' todo is use the Bink (RadGameTools) codec to draw within our game!
We are primarily 2d mode, but would like to know/acquire the use of getting data into and out of textures as efficiently as possible, becasue I'd love to use the SceneManager.
So if I can get the Bink codec to put/paint into an ITexture, I can fully utilize all Irrlicht scene, cameras, perspective, project,etc.
We have two options for this : 2d direct or a pixel shader. THe OpenGL code shows both ways and works. I've modified from the example to use Quads with glOortho and ModelView to test similar to the way Irrlicht draws 2d. But still can't get a valid draw in Irrlicht!

2) Have done some tinkering with RenderToTexture to gain a better understanding of how to use it.
3) Hadn't thought to use a material, which would also allow me to try drawIndexedTriangleList(). So that's on the plate.
4) setconstants() is expensive as Irrlicht doesn't return the progam or selector for the programmer. It keeps it internal so always has to loop through on each call.
Wouldn't something like - mat = setHighLevelShaderFromFiles(); program = getlastprogram(), yval = getshaderconstant( program, "yTex"); setshaderconstant( yval, value) MORE closely model the pattern?
I believe that DX follows the same technique.

I agree that I'm going a bit bonkers bouncing back and forth between OpenGL and Irrlicht. You have helped to stretch my imagination.
Thanks

PS: I'd think there would have been more interest in having Bink renderable with Irrlicht than I've seen. I've also, typically, gotten very un-interested support from RadGameTools.
caburfoot
Posts: 22
Joined: Mon Aug 08, 2011 6:15 am

Re: Irrlicht Bink Shader

Post by caburfoot »

After reading the post and thinking about 'how to do this', I've severl questions back :

1) If a pixel shader is ONLY functional as an Irricht Material type, how to use a pixel shader in Irrlicht in 2D?
2) In the existing code how to replace the assignments for each of the pixel shaders 4 data inputs without using OpenGL ?
Because mat->setTexture(0, ptexture) won't set the anything other than the GL_TEXTURE0 (!?) (unless there's something I haven't seen/been told)

Code: Select all

 
            glActiveTextureARB(GL_TEXTURE0_ARB);
            glUniform1iARB(s_YTexIndex, 0);
            glBindTexture(GL_TEXTURE_2D, s_Textures[0]);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth, s_TextureHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].YPlane.Buffer);
 
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Irrlicht Bink Shader

Post by hybrid »

Please read the shader example again. There's the uniform management described, I think that's what you need. Pixel shaders cannot be used in 2d for now. Please use an ortho projection and render planar in 3d.
You can set up to four textures in a material, after recompiling with a changed define even up to eight (or whatever you card supports for fixed pipeline textures). So it will set all GL_TEXTURE*X* for each layer you assign a texture.
Video rendering usually uses lock and unlock to update the texture. It is sometimes faster to use a render texture in these cases, and it will usually not harm to do so anyway. Upon locking you should set the write_only flag (IIRC only possible in SVN/trunk, i.e. Irrlicht 1.8 alpha) to avoid unnecessary copies. But besides that there's not much to do. If you use an ordinary texture, you should make sure you disable mipmaps on creation. Otherwise each update will cause the mipmaps to be updated, which is pretty slow.
caburfoot
Posts: 22
Joined: Mon Aug 08, 2011 6:15 am

Re: Irrlicht Bink Shader

Post by caburfoot »

I appreciate your response and experience, however the question remains HOW TO DO IT?

Problem 1) There are 4 textures needed by the shader for the input (the pix shader main )

Code: Select all

 
char FragmentShader[] =
        uniform sampler2D YTex;
        uniform sampler2D cRTex;
        uniform sampler2D cBTex;
        uniform sampler2D ATex;
void main (void)
{
           const vec4 crc = vec4(1.595, -0.813, 0, 0);
 
           const vec4 crb = vec4(0, -0.391, 2.017, 0);
 
           const vec4 adj = vec4(-0.870, 0.529, -1.0816, 0);
           float Y = texture2D(YTex, gl_TexCoord[0].st).x;
           float cR = texture2D(cRTex, gl_TexCoord[0].st).x;
           float cB = texture2D(cBTex, gl_TexCoord[0].st).x;
           float A = texture2D(ATex, gl_TexCoord[0].st).x;
           vec4 p;
           p = vec4(Y * 1.164, Y * 1.164, Y * 1.164, 1);
           p += crc * cR;
           p += crb * cB;
           p += adj;
           p.w = A;
           gl_FragColor = p;
}
 
That shader program clearly states that there are 4 input textures. Those textures are set in the OpenGL.
IF I use driver->setMaterial() in the derived IShaderConstantSetCallBack, haven't I switched the focus from the intended texture ?
So at this point I don't KNOW or see a working solution to using Irrlicht textures.

Code: Select all

 
        glActiveTextureARB(GL_TEXTURE0_ARB);
        glUniform1iARB(s_YTexIndex, 0);
        glBindTexture(GL_TEXTURE_2D, s_Textures[0]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth, s_TextureHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].YPlane.Buffer);
 

Code: Select all

 
extern video::ITexture * YTex; // we've created the 
//?? setProject() or ortho ??? how - nothing specified in the shader 
 
int tids[4] = {0, 1, 2, 3 };
 
// so how to set ortho other than glOrtho()?
core::matrix4 mWorld = driver->getTransform(video::ETS_WORLD);
mWorld.makeIdentity();
driver->setTransform( mWorld );  // ??
 
        services->setPixelShaderConstant("YTex", (float*) tids, 1 );
                tempMaterial->setTexture(0, YTex );
                driver->setMaterial( tempMaterial ); // This is what I'm worried about taking the focus away 
                glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth, s_TextureHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].YPlane.Buffer);
 
               // set the other 3 textures 
 
               // with a final   
driver->setMaterial(); //  back to the original ???
 
 
Now the code fragment shows my novice/clumsy understanding to date to accomplish the objective. If you or someone else can help me gain HOW set/map the input textures with IRRLICH and/or set the projection, it would be VERY helpful.

THanks for the thoughts
caburfoot
Posts: 22
Joined: Mon Aug 08, 2011 6:15 am

Re: Irrlicht Bink Shader

Post by caburfoot »

Since there has been no reply I have pursued alternatives with getting the Bink to work with the shader.
However, now I have a piece of code that Hybrid and other may not 'approve'.

It's taken some time and I have one version of the code that is close to working with VERY good frame rates (1920x1080). However, colors are goofed (?) up.

The idea behind the code is try to render to a render texture using OpenGl calls. The Bink buffers come in as YUV.
As I don't see ANY mechanism for handling Y @ H * W, cR @ H/2 * W /2, cB @ H/2 x W/2, i cannot see any implementation except

Code: Select all

 
int InitGLStuff()
{
        s_HasAlpha = s_Bink->FrameBuffers[0].Frames[0].APlane.Allocate;
 
        if ( Shader_BuildOurShaders() == 0)
                return 0;
 
        glGenTextures(4, s_Textures);
 
 
        glActiveTextureARB(GL_TEXTURE0_ARB);
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, s_Textures[0]);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
        glActiveTextureARB(GL_TEXTURE1_ARB);
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, s_Textures[1]);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
        glActiveTextureARB(GL_TEXTURE2_ARB);
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, s_Textures[2]);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
        if (s_HasAlpha)
        {
                glActiveTextureARB(GL_TEXTURE3_ARB);
                glEnable(GL_TEXTURE_2D);
                glBindTexture(GL_TEXTURE_2D, s_Textures[3]);
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);        
        }
 
        glEnableClientState(GL_VERTEX_ARRAY);
 
        return 1;
}
 
The call to shadercompile just builds it and gives us the handles

Then

Code: Select all

 
void RTRenderBinkVid()
{
 
        //glClearColor(0, 0, 1, 0);
        //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
 
 
        if (!BinkWait(s_Bink))
        {
                BinkDoFrame(s_Bink);
 
                //glEnable(GL_TEXTURE_2D);
                glEnableClientState(GL_VERTEX_ARRAY);
 
                glActiveTextureARB(GL_TEXTURE0_ARB);
                GLCHK;
                glUniform1iARB(s_YTexIndex, 0);
                GLCHK;
                glBindTexture(GL_TEXTURE_2D, s_Textures[0]);
                GLCHK;
                glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth, s_TextureHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].YPlane.Buffer);
                GLCHK;
 
                glActiveTextureARB(GL_TEXTURE1_ARB);
                glUniform1iARB(s_cRTexIndex, 1);
                glBindTexture(GL_TEXTURE_2D, s_Textures[1]);
                glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth/2, s_TextureHeight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].cRPlane.Buffer);
 
                glActiveTextureARB(GL_TEXTURE2_ARB);
                glUniform1iARB(s_cBTexIndex, 2);
                glBindTexture(GL_TEXTURE_2D, s_Textures[2]);
                glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth/2, s_TextureHeight/2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].cBPlane.Buffer);            
 
                if (s_HasAlpha)
                {
                        glActiveTextureARB(GL_TEXTURE3_ARB);
                        glUniform1iARB(s_ATexIndex, 3);
                        glBindTexture(GL_TEXTURE_2D, s_Textures[3]);
                        glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, s_TextureWidth, s_TextureHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, s_Bink->FrameBuffers->Frames[s_Bink->FrameBuffers->FrameNum].APlane.Buffer);
                }
 
                BinkNextFrame(s_Bink);
        
        //else
        //{
        //Sleep( 10 ); // 1000
        //}
 
                float uvs[] = {
                        0.f, 0.f,
                        1.f, 0.f,
                        1.f, 1.f,
                        0.f, 1.f
                };
 
                float verts[] = {
                        -1.f, 1.f, 
                        1.f, 1.f,
                        1.f, -1.f,
                        -1.f, -1.f
                };
        /*float verts[] = {
                -1, -1,
                1, -1,
                -1, 1,
                1, 1,
        };
 
        float uvs[] = {
                0, 1.0f,
                1.0f, 1.0f,
                0, 0,
                1.0f, 0
        }; */
        
        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(2, GL_FLOAT, 0, verts);
 
        glClientActiveTextureARB(GL_TEXTURE0_ARB); 
        glTexCoordPointer(2, GL_FLOAT, 0, uvs);
        glClientActiveTextureARB(GL_TEXTURE1_ARB); 
        glTexCoordPointer(2, GL_FLOAT, 0, uvs);
        glClientActiveTextureARB(GL_TEXTURE2_ARB); 
        glTexCoordPointer(2, GL_FLOAT, 0, uvs);
        if (s_HasAlpha)
        {
                glClientActiveTextureARB(GL_TEXTURE3_ARB); 
                glTexCoordPointer(2, GL_FLOAT, 0, uvs);
        }
 
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        glFlush();
        }
}
 
The run loop now looks like

Code: Select all

 
while(device->run())
                //if (device->isWindowActive())
        {
                driver->beginScene(true, true, video::SColor(255,255,255,255));
 
                driver->setRenderTarget( rt, true, true );
                RTRenderBinkVid();
                driver->setRenderTarget(NULL,false, false);
                driver->draw2DImage( rt,core::vector2d<s32>(0,0) );
 
                //driver->draw2DImage( rendermat.getTexture(0), core::vector2d<s32>( 0, 0));
                //driver->drawIndexedTriangleList( Vertices, 4, primaryindices, 2 ); 
                //driver->drawVertexPrimitiveList(Vertices, 4, primaryindices, 2, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);
                //driver->draw2DVertexPrimitiveList(Vertices, 4, primaryindices, 2, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);
 
                driver->endScene();
                
                //Sleep( 1000 );
 
                if ( s_Bink->FrameNum >= s_Bink->Frames )
                        BinkGoto( s_Bink, 1, 0 );
 
                int fps = driver->getFPS();
 
                if (lastFPS != fps)
                {
                        core::stringw str = L"Irrlicht Engine - Vertex and pixel shader example [";
                        str += driver->getName();
                        str += "] FPS:";
                        str += fps;
 
                        device->setWindowCaption(str.c_str());
                        lastFPS = fps;
                }
        }
 
I sure could use some brain power on this.

If I'm overlooking something simple to deal with this, slap me, my mother did!
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Irrlicht Bink Shader

Post by hybrid »

The idea looks good. Not sure if you have proper texture dimensions, that part seems to be missing. However, the crucial point is the YUV conversion in the shader. Not sure if that shader produces a proper conversion anyway. Otherwise it should probably work.
caburfoot
Posts: 22
Joined: Mon Aug 08, 2011 6:15 am

Re: Irrlicht Bink Shader

Post by caburfoot »

The code from the first entry appears to work, I'm trying to get an Ati Radeon card to use the gDebugger (AMD) to debug the shader code. What doesn't work and I have an idea, is the rendertotexture - it's empty. I suspect that the drawIndexedTriagleList() is changing the state of the OpenGl registers after I've set them up, including a NormalPointer() that isn't used by the original OPenGL code. I fully realize That I'm tinker with Irrlicht's default behavior - but don't know how else to get the YUV done.

I have double checked the code and the lengths appear correct ( Y len = W * H, cR len = cB len = W/2 * H/2)
Any idea what would happen IF I call all the opengl drawing in OnSetConstants(), but modify the draw() to skip the code except for the renderarray() or even skip that ?

Sure would like to get this working.... (heavy breathing in the background)... and perhaps expand the capability of Irrlicht with shaders
devsh
Competition winner
Posts: 2057
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Re: Irrlicht Bink Shader

Post by devsh »

I only skimmed over your code... but, lets put it this way:

a) I did a fair bit of tinkering with gl calls in irrlicht programs, and I gotta tell you... some of them don't work!!
b) why are you rendering to texture instead of straight to frame buffer?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Re: Irrlicht Bink Shader

Post by hybrid »

The problem with using foreign texture is that Irrlicht will check the current material, and set those textures (or disable texturing if none is set). Not sure if this would work somehow, because you cannot alter the underlying opengl information in the itexture
caburfoot
Posts: 22
Joined: Mon Aug 08, 2011 6:15 am

Re: Irrlicht Bink Shader

Post by caburfoot »

devsh : Thank you for your questions and interest.
1) You and I have a similar experience with some things not working as expected!
2) We 'seem' to have redraw issue with color when NOT rendering to texture, so I think we'll gain several advantages by RTT.
a) we can render windows size @ 0,0, top-down or bottom-up
b) we then have a Irrlicht Texture we can paint wherever and however we want

hybrid :
I have Irrlicht 1.7.2 and have build from source and I'm comfortable with MOST of what's being done in drawVertexPrimitive() or drawIndexedTriangle() or draw2DImage().
I was wondering IF the shader OnSetConstants() setup the OpenGl textures after setting the Irrlicht RTT, setup the Vectors and Indicies and call glDrawElements() or glDrawArray()
Then glFlush and set RTT( null). the draw2DImage( rt, (0,0))
But so far this hasn't produced any output in the rt. Do I also need a swapbuffer() ?

Irrlicht has been SO frigging impressive so far, but REALLY need the frame rates that fragment shader can provide!
Thanks you so much (still breathing heavy!)
caburfoot
Posts: 22
Joined: Mon Aug 08, 2011 6:15 am

Re: Irrlicht Bink Shader [SOLVED]

Post by caburfoot »

Well, the Lord works in mysterious ways. He sent the right guy.

devsh and I chatted and he bid about $75 bucks to get the original OpenGL example working and fix the GL shader issue with Irrlicht.

The two primary issues were that the binks weren't power of two causing buffer shifts and that Irrlicht didn't understand the Luminence type.
Mateusz Kielan (dvsh) has delivered the glshader that works with Irrlicht and bink.

I’m impressed with this guy’s skill and that he consistently met his self imposed deadline.
Guys this is a good solution to slow full screen bink renders.

This guy figured out the Irrlicht solution and found issues with the frag shader also.
He’s delivered at a very reasonable price and consistenly on time.
Delivered the modified source and an example program.

Cannot sing his technical praises loud enough.
I had spent at least 3 weeks looking at the code and couldn't see the issue, thought I could tell it was related to Luminence.

His code is clean and the example is easy to follow. I'd even say elegant.
IF You have an Irrlicht Issue or OpenGL issue, you should contact devshhttp://irrlicht.sourceforge.net/forum/m ... le&u=16623.
He can definately swizzle the GLSL and Irrlicht!
devsh
Competition winner
Posts: 2057
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Re: Irrlicht Bink Shader

Post by devsh »

charles is a very good person to work with too. He is very generous, sympathetic and supportive in providing debug assets/data.
Post Reply