1 (edited by bruZard 2009-05-11 08:08:05)

Topic: Fullscreen Quad

i have a quad and a material with a rendertarget texture and this will work. but the quad is'nt fullscreen:

http://simpleirr.sedm.de/bmx/quad.jpg

what should i do to make the quad fullscreen and overlaying the scene? (i will try to make postfx shader)

thanks for help and excuse my bad englisch wink

[EDIT]
i think the problem is that theres no AbsoluteTransformation Matrix in the video driver :

driver->setTransform(irr::video::ETS_WORLD, AbsoluteTransformation);

[/EDIT]

[EDIT 2]
i got it, the vertexshader make it big_smile
[/EDIT 2]

2 (edited by bruZard 2009-05-11 10:03:27)

Re: Fullscreen Quad

o.k. ... next problem. How can i get a float pointer from ITexture?!?

services.setPixelShaderConstantFromName("Texture0", ??? , 0)

hmm ... Float Ptr(Byte Ptr) seems to do the job, but how can i mix the shader result with the rendered scene?

Re: Fullscreen Quad

ok, at the first time i've combined the render result with the scene per 2 layer texture, now i do this with the vertexshader ... at the moment i convert the c++ postprocessing framework by slin. it works, but atm not perfect.

SuperStrict

Framework sedm.simpleirr

Type TPostProcessing_SetShaderConstants Extends IShaderConstantSetCallBack
    Global shaderparameters:Float[8]
    
    Method OnSetConstants(services:IMaterialRendererServices, userdata:Int)
        services.setPixelShaderConstantFromName("vecValues", Self.shaderparameters, 8)
    
        If userdata = 1
            'Set Textures For openGL Shaders
            Local texture1:Float = 0.0
            Local texture2:Float = 0.0
            services.setPixelShaderConstantFromName("texture1", VarPtr(texture1), 1)
            services.setPixelShaderConstantFromName("texture2", VarPtr(texture2), 1)
        EndIf
    End Method
    
    Function setShaderParameters(paras:Float[])
        shaderparameters = paras
    End Function
    
    Function generate:IShaderConstantSetCallBack()
        Return New TPostProcessing_SetShaderConstants
    EndFunction
End Type
 
rem
    Class which manages postprocessing effects
    
    To apply the effect, run
    driver->setRenderTarget(postprocessing->getFirstMap(), true, true, video::SColor(255,150,180,255));
    
    or similar before you render anything and run
    
    driver->setRenderTarget(0);
    postprocessing->renderEffect();
    
    to actually run the shaders and render the result to the screen.
end rem
Type TPostProcessing
    Field shadercallback:TPostProcessing_SetShaderConstants
    Field scenemgr:ISceneManager
    Field Driver:IVideoDriver
    Field vertices:Array_S3DVertex
    Field indices:Array_u16
    Field material:SMaterial
    Field matid:Int
    Field shaderparameters:Float[8]
    Field prevstage:TPostProcessing
    Field nextstage:TPostProcessing
    Field firstmap:ITexture
    Field secondmap:ITexture
    Field gpu:IGPUProgrammingServices
    
    rem
        Constructor
        smgr        : Scene manager which is used for the post progressing
        filename_gl    : Path to the GLSL script
        filename_dx    : Path to the HLSL script
        type_ps        : Type of the pixel shader
        res_x        : Horizontal resolution of the used texture
        res_y        : Vertical resolution of the used texture
    end rem
    Function PostProcessing:TPostProcessing(smgr:ISceneManager, filename_gl:String, filename_dx:String, type_ps:Int, res_x:Int, res_y:Int)
        Local pp:TPostProcessing = New TPostProcessing
        
        pp.Driver            = smgr.getVideoDriver()
        pp.shadercallback    = TPostProcessing_SetShaderConstants(IShaderConstantSetCallBack.Create(TPostProcessing_SetShaderConstants.generate))
        pp.vertices            = Array_S3DVertex.createWithSize(4)
        pp.indices            = Array_u16.createWithSize(6)
        pp.material            = SMaterial.Create()
        
        If pp.Driver.getDriverType() = EDT_OPENGL Or pp.Driver.getDriverType() = EDT_DIRECT3D9
            pp.vertices.Insert(S3DVertexDefault.createFromVals(-1.0, -1.0, 0.0, 1.0, 1.0, 0.0, _SCOLOR(0,0,0,0), 0.0, 1.0), 0)
            pp.vertices.Insert(S3DVertexDefault.createFromVals(-1.0,  1.0, 0.0, 1.0, 1.0, 0.0, _SCOLOR(0,0,0,0), 0.0, 0.0), 1)
            pp.vertices.Insert(S3DVertexDefault.createFromVals( 1.0,  1.0, 0.0, 1.0, 1.0, 0.0, _SCOLOR(0,0,0,0), 1.0, 0.0), 2)
            pp.vertices.Insert(S3DVertexDefault.createFromVals( 1.0, -1.0, 0.0, 1.0, 1.0, 0.0, _SCOLOR(0,0,0,0), 1.0, 1.0), 3)
            
            pp.indices.Insert(0, 0)
            pp.indices.Insert(1, 1)
            pp.indices.Insert(2, 2)
            pp.indices.Insert(0, 3)
            pp.indices.Insert(2, 4)
            pp.indices.Insert(3, 5)
            
            pp.gpu        = pp.Driver.getGPUProgrammingServices()
            pp.scenemgr    = smgr
 
            pp.prevstage = Null
            pp.nextstage = Null
            
            Local para:Float[] = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
            pp.setShaderParameters(para)
            pp.shadercallback.setShaderParameters(pp.shaderparameters)
 
            If pp.Driver.getDriverType() = EDT_OPENGL
                pp.matid = pp.gpu.addHighLevelShaderMaterialFromFiles( ..
                    "Shaders/PP_GL_Vertex.fx", ..
                    "main", ..
                    EVST_VS_1_1, ..
                    filename_gl, ..
                    "main", ..
                    type_ps, ..
                    pp.shadercallback, ..
                    EMT_SOLID, ..
                    1)
            Else
                pp.matid = pp.gpu.addHighLevelShaderMaterialFromFiles( ..
                    "Shaders/PP_DX_Vertex.fx", ..
                    "main", ..
                    EVST_VS_1_1, ..
                    filename_dx, ..
                    "main", ..
                    type_ps, ..
                    pp.shadercallback, ..
                    EMT_SOLID, ..
                    0)
            EndIf
     
            pp.firstmap = pp.Driver.addRenderTargetTexture(_DIMENSION2DI(res_x, res_y))
            pp.secondmap = Null
            pp.material.setWireframe(False)
            pp.material.setLighting(False)
            pp.material.setTexture(0,pp.firstmap);
            'material.TextureLayer[0].TextureWrap = video::ETC_CLAMP;
            pp.material.setMaterialType(pp.matid)
        EndIf
        
        Return pp
    End Function
 
    rem
        Destructor
    endrem
    Method Delete()
        Self.free()
    End Method
    
    Method free()
        Self.shadercallback = Null
        Self.scenemgr.Deconstructor()
        Self.Driver.Deconstructor()
        Self.vertices.Deconstructor()
        Self.material.Deconstructor()
        Self.shaderparameters = Null
        Self.firstmap.Deconstructor()
        Self.secondmap.Deconstructor()
        Self.gpu.Deconstructor()
        If Self.prevstage <> Null
            Self.prevstage.free()
            Self.prevstage = Null
        End If
        If Self.nextstage <> Null
            Self.nextstage.free()
            Self.nextstage = Null
        EndIf
    End Method
 
    rem
        Adds another stage and inserts it after this stage
        filename_gl Path to the GLSL script
        filename_dx Path to the HLSL script
        type_ps Type of the pixel shader
        res_x Horizontal resolution of the used texture
        res_y Vertical resolution of the used texture
    end rem
    Method addMaterial:TPostProcessing(filename_gl:String, filename_dx:String, type_ps:Int, res_x:Int, res_y:Int)
        Self.nextstage = TPostProcessing.PostProcessing(Self.scenemgr, filename_gl, filename_dx, type_ps, res_x, res_y)
        Return nextstage
    End Method
 
    rem
        Renders this postprocessing chain
    end rem
    Method renderEffect()
        Self.Driver.setMaterial(Self.material)

        If Self.nextstage <> Null
            Self.Driver.setRenderTarget(Self.nextstage.getFirstMap(), True, True, _SCOLOR(255,150,180,255))
            Self.Driver.drawIndexedTriangleList(Self.vertices, Self.indices)
            Self.Driver.setRenderTarget()
            Self.nextstage.renderEffect()
        Else
            Self.Driver.setMaterial(Self.material)
            Self.Driver.drawIndexedTriangleList(Self.vertices, Self.indices)
        EndIf
    End Method
 
    rem
        Sets the second texture
    end rem
    Method setSecondMap(tex:ITexture, mode:Int = ETC_CLAMP)
        Self.secondmap = tex
        Self.material.setTexture(1, Self.secondmap)
        'self.material.TextureLayer[1].TextureWrap = mode
    End Method
 
    rem
        Sets the parameters of the shader
    endrem
    Method setShaderParameters(para:Float[])
        Self.shaderparameters = para
    End Method
 
    rem
        Returns a pointer to the material
    end rem
    Method getMaterial:SMaterial()
        Return Self.material
    End Method
 
    rem
        Returns a pointer to the first texture
    end rem
    Method getFirstMap:ITexture()
        Return Self.firstmap
    End Method
    
    rem
        Returns a pointer to the second texture
    end rem
    Method getSecondMap:ITexture()
        Return Self.secondmap
    End Method
End Type

Local irr:TIrrlicht = TIrrlicht.Init()
irr.Graphics3D(1024, 768)

Local para:Float[8]
Local PP_Test:TPostProcessing = TPostProcessing.PostProcessing(irr.irr_scene, "Shaders/PP_GL_Bloom1.fx","Shaders/PP_DX_Bloom1.fx", EPST_PS_1_4, 512,256)
para[0] = 0.5; PP_Test.setShaderParameters(para)

Local Test2:TPostProcessing = PP_test.addMaterial("Shaders/PP_GL_Bloom2.fx", "Shaders/PP_DX_Bloom2.fx", EPST_PS_2_0, 128, 128)
para[0] = 0.01; Test2.setShaderParameters(para)

Test2 = Test2.addMaterial("Shaders/PP_GL_Bloom3.fx", "Shaders/PP_DX_Bloom3.fx", EPST_PS_2_0, 128, 128)
Test2.setShaderParameters(para)

Test2 = Test2.addMaterial("Shaders/PP_GL_Bloom4.fx", "Shaders/PP_DX_Bloom4.fx", EPST_PS_2_0, 512, 256)
para[0] = 0.7; Test2.setShaderParameters(para)

Test2.setSecondMap(PP_Test.getFirstMap(), ETC_CLAMP)

irr.AddZip("data/data.zip")

Local scene:TScene = TScene.Load("scene.irr")

Local sky:ISceneNode = irr.irr_scene.addSkyBoxSceneNode(irr.irr_video.getTexture("sky/morning_up.jpg"), ..
                                                        irr.irr_video.getTexture("sky/morning_down.jpg"), ..
                                                        irr.irr_video.getTexture("sky/morning_west.jpg"), ..
                                                        irr.irr_video.getTexture("sky/morning_east.jpg"), ..
                                                        irr.irr_video.getTexture("sky/morning_north.jpg"), ..
                                                        irr.irr_video.getTexture("sky/morning_south.jpg"))
                                                        
' die Würfel aus der Scene holen
Local cb:ISceneNode = TScene.FindByName("Cube")
Local ce:TEntity = New TEntity
ce.node=cb
cb.getMaterial(0).setShininess(200.0)

Local cam:ISceneNode = ICameraSceneNode(TScene.FindByName("Camera"))
If Not cam Then RuntimeError "no camera found"
cam.remove()

Local cam2:ICameraSceneNode = irr.irr_scene.addCameraSceneNodeFPS(Null, 100.0, 0.05)
irr.irr_scene.setActiveCamera(cam2)
cam2.setPosition(_VECTOR3DF(0.0, 3.0, -10.0))

'the main loop
Repeat
    If irr.irr_device.run()
        irr.irr_video.BeginScene(True, True, _SCOLOR(255,150,180,255))
                
        'render the scene into the postprocessing texture
        irr.irr_video.setRenderTarget(PP_Test.getFirstMap(), True, True, _SCOLOR(255,150,180,255))
        irr.irr_scene.drawAll()
        irr.irr_video.setRenderTarget()
            
        'render the effect chain
        PP_Test.renderEffect()

        irr.irr_video.EndScene()
    EndIf
Until irr.IsKeyDown(KEY_ESCAPE)
End

the result shows like that:
http://simpleirr.sedm.de/images/stories/samplepics/pp_failed_t.jpg
it is'nt combined with the scene, i'am working on it.



... excuse my poor bad fu***ng english wink wink

Re: Fullscreen Quad

The problem: your wrapper doesnt do the shader job like the original Irrlicht Engine. Postprocess is'nt possible with BlitzMax and Irrlicht. This means that i must take a look on other engines, or go to to c++.

Re: Fullscreen Quad

greetings bruZard.  what code is different?  i simply provide an interface to the compiled library.  its possible that my conversion is not quite right and that i can remedy the situation if i can understand what is not working for you.

Re: Fullscreen Quad

greetings gman.

I try to make a simple Bloom-Effekt. I have 4 shaderpasses (remove dark colors, blur h, blur v, combine), these are successively processed. The Problem: the last shader (combine the shaderbuffer with the scenebuffer) doesnt work because I cannot change the buffer for the fullscreenquad. Normally the passes are processed in a List:

For EachIn myList
  SetShaderConstant
  SetRenderTarget
  drawAll
  SetMaterial
  drawIndexedTriangleList
  SetRenderTarget Null
Next

I can check if the current entry the last in the list and try to set the current texture to scene (video.setTexture(0, myBackbuffer)) but this will not work.

Re: Fullscreen Quad

i think i've found the problem:

[ Pass 1 ] -> texture2
[ Pass 2 ] -> texture2

pass2 should take the texture with the manipulations from pass1, but this will not happen. Pass2 has again the original.

Framework sedm.simpleirr

SuperStrict
Type TPostProcessParameter
    Global _list:TList
    
    Field p_name:String
    Field p_value:Float[]
    
    Function add:TPostProcessParameter(p_name:String, p_value:Float[])
        Local par:TPostProcessParameter = New TPostProcessParameter
        If par._list = Null Then par._list = New TList
        par.p_name    = p_name
        par.p_value = p_value
        
        Return par
    End Function
End Type


Type TPostProcessCallback Extends IShaderConstantSetCallBack
    Field shaderbuffer:Byte ptr
    Field originalbuffer:Byte ptr
    Field parameter:TPostProcessParameter
    
    Method OnSetConstants(services:IMaterialRendererServices,userData:Int)
        If userData = 1
            If Self.parameter <> Null
                For Local par:TPostProcessParameter = EachIn Self.parameter._list
                    services.setPixelShaderConstantFromName(par.p_name, par.p_value, par.p_value.length)
                Next
            End If
            
            services.setPixelShaderConstantFromName("texture1", Float ptr(Self.originalbuffer), 1)
            services.setPixelShaderConstantFromName("texture2", Float ptr(Self.shaderbuffer), 1)
        Else
            services.setPixelShaderConstant(Float ptr(VarPtr(Self.originalbuffer)), 0, 1)
            services.setPixelShaderConstant(Float ptr(VarPtr(Self.shaderbuffer)), 1, 1)
        EndIf
    End Method
    
    Function generate:TPostProcessCallback()
        Return New TPostProcessCallback
    End Function
End Type

Type TPostProcessPass
    Global _list:TList
    Field irr:TIrrlicht
    Field material:SMaterial
    Field matid:Int
    Field callback:TPostProcessCallback
            
    Function add:TPostProcessPass(    irr:TIrrlicht, ..                ' simpleIrr Object
                                    vs:String, ..                    ' Vertexshaderfile
                                    ps:String, ..                    ' Pixelshaderfile
                                    backbuffertexture:ITexture, ..    ' original rendered Scene
                                    shaderbuffertexture:ITexture, ..' Texture for Manipulation
                                    vs_entry:String = "main", ..    ' Vertexshader Entry
                                    ps_entry:String = "main", ..    ' Pixelshader Entry
                                    vs_model:Int = EVST_VS_1_1, ..    ' Vertexshadermodel
                                    ps_model:Int = EPST_PS_2_0)        ' Pixelshadermodel
        
        Local pass:TPostProcessPass = New TPostProcessPass
        If pass._list = Null Then pass._list = New TList
        pass._list.AddLast(pass)
        
        pass.irr                        = irr
        pass.callback                    = TPostProcessCallback.generate()
        pass.callback.originalbuffer    = VarPtr(backbuffertexture)
        pass.callback.shaderbuffer        = VarPtr(shaderbuffertexture)
        pass.material                    = SMaterial.Create()
        
        Local ud:Int = 0
        If irr.irr_video.getDriverType() = EDT_OPENGL Then ud = 1
        pass.matid = irr.irr_gpu.addHighLevelShaderMaterialFromFiles(    vs, ..
                                                                        vs_entry, ..
                                                                        vs_model, ..
                                                                        ps, ..
                                                                        ps_entry, ..
                                                                        ps_model, ..
                                                                        pass.callback, ..
                                                                        EMT_SOLID, ..
                                                                        ud)
        pass.material.setTexture(1, shaderbuffertexture)
        pass.material.setLighting(False)
        pass.material.setWireframe(False)
        pass.material.setMaterialType(pass.matid)
        
        Return pass
    End Function
End Type

Type TPostProcess
    Field irr:TIrrlicht
    Field passes:TPostProcessPass
    Field backbuffertexture:ITexture
    Field shaderbuffertexture:ITexture
        
    Function Create:TPostProcess(irr:TIrrlicht, buffer_width:Int = 256, buffer_height:Int = 256)
        Local pp:TPostProcess = New TPostProcess
        pp.irr                    = irr
        pp.backbuffertexture    = irr.irr_video.addRenderTargetTexture(irr.screensize)
        pp.shaderbuffertexture    = irr.irr_video.addRenderTargetTexture(_DIMENSION2DI(buffer_width, buffer_height))
                
        Return pp
    End Function
    
    Method AddPass:TPostProcessPass(vs:String, ps:String, vs_entry:String = "main", ps_entry:String = "main", vs_model:Int = EVST_VS_1_1, ps_model:Int = EPST_PS_2_0)
        Self.passes = TPostProcessPass.add(Self.irr, vs, ps, Self.backbuffertexture, Self.shaderbuffertexture, vs_entry, ps_entry, vs_model, ps_model)
        
        Return Self.passes
    End Method
    
    Method RenderPostFx()
        irr.irr_video.setRenderTarget(Self.backbuffertexture, True, True, _SCOLOR(255,150,180,255))
        irr.irr_scene.drawAll()
        irr.irr_video.setRenderTarget()
        
        If Self.passes <> Null
            Local c:Int = Self.passes._list.Count()
            Local i:Int = 0
            For Local pass:TPostProcessPass = EachIn Self.passes._list    
                If i < c - 1                                
                    Self.irr.irr_video.setRenderTarget(Self.shaderbuffertexture, True, True, _SCOLOR(255,150,180,255))
                    Self.irr.irr_scene.drawAll()
                    
                    'pass.material.setTexture(0, Self.shaderbuffertexture)
                                    
                    Self.irr.irr_video.setMaterial(pass.material)
                    Self.irr.irr_video.setRenderTarget()
                    Self.irr.irr_video.drawIndexedTriangleList(Self.irr.vertices, Self.irr.indices)
                Else
                    Self.irr.irr_video.setRenderTarget(Self.backbuffertexture, True, True, _SCOLOR(255,150,180,255))
                    Self.irr.irr_scene.drawAll()
                    
                    pass.material.setTexture(0, Self.backbuffertexture)
                                    
                    Self.irr.irr_video.setMaterial(pass.material)
                    Self.irr.irr_video.setRenderTarget()
                    Self.irr.irr_video.drawIndexedTriangleList(Self.irr.vertices, Self.irr.indices)
                EndIf
                
                i:+ 1
            Next
        EndIf
        
    End Method
End Type



Local irr:TIrrlicht = TIrrlicht.Init()
irr.Graphics3D(800, 600, 32)

irr.AddZip("data/data.zip")

Local scene:TScene = TScene.Load("scene.irr")

Local sky:ISceneNode = irr.irr_scene.addSkyBoxSceneNode(irr.irr_video.getTexture("sky/morning_up.jpg"), ..
                                                        irr.irr_video.getTexture("sky/morning_down.jpg"), ..
                                                        irr.irr_video.getTexture("sky/morning_west.jpg"), ..
                                                        irr.irr_video.getTexture("sky/morning_east.jpg"), ..
                                                        irr.irr_video.getTexture("sky/morning_north.jpg"), ..
                                                        irr.irr_video.getTexture("sky/morning_south.jpg"))
                                                        
' die Würfel aus der Scene holen
Local cb:ISceneNode = TScene.FindByName("Cube")
Local ce:TEntity = New TEntity
ce.node=cb
cb.getMaterial(0).setShininess(200.0)

Local cam:ISceneNode = ICameraSceneNode(TScene.FindByName("Camera"))
If Not cam Then RuntimeError "no camera found"
cam.remove()

Local cam2:ICameraSceneNode = irr.irr_scene.addCameraSceneNodeFPS(Null, 100.0, 0.05)
irr.irr_scene.setActiveCamera(cam2)
cam2.setPosition(_VECTOR3DF(0.0, 3.0, -10.0))

ce.node.setPosition(_VECTOR3DF(0.0, 2.0, 0.0))


Local pp:TPostProcess = TPostProcess.Create(irr)
pp.AddPass("data/shader/vertex.glsl", "data/shader/blur_h.glsl")
pp.AddPass("data/shader/vertex.glsl", "data/shader/blur_v.glsl")
pp.AddPass("data/shader/vertex.glsl", "data/shader/combine.glsl")

Local lastFPS:Int = -1
Repeat
    If irr.irr_device.run()
        ce.Turn(0.05, 0.05, 0.05)
        irr.irr_video.BeginScene(True, True)
        
        pp.RenderPostFx()
                        
        irr.irr_video.EndScene()
        
        Local FPS:Int = irr.irr_video.getFPS()
        If FPS <> lastFPS
            lastFPS = FPS
            irr.irr_device.setWindowCaption(String(FPS))
        End If
    EndIf
Until irr.IsKeyDown(KEY_ESCAPE)
End

Re: Fullscreen Quad

The Pass-System works now, but the last pass will not combine the shader result with the backbuffer ... i am working on it.

http://simpleirr.sedm.de/bmx/passes.jpg