123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667 |
- Namespace mojo.graphics
- #rem monkeydoc Blend modes.
- Blend modes are used with the [[Canvas.BlendMode]] property.
- | BlendMode | Description
- |:----------|:-----------
- | Opaque | Blending disabled.
- | Alpha | Alpha blending.
- | Multiply | Multiply blending.
- | Additive | Additive blending.
- #end
- Enum BlendMode
- None=0
- Opaque=1
- Alpha=2
- Additive=3
- Multiply=4
- End
- #rem monkeydoc @hidden Color mask values.
- Color masks are used with the [[Canvas.ColorMask]] property.
- | ColorMask | Descripten
- |:----------|:----------
- | Red | Red color mask.
- | Green | Green color mask.
- | Blue | Blue color mask.
- | Alpha | Alpha color mask.
- #end
- Enum ColorMask
- None=0
- Red=1
- Green=2
- Blue=4
- Alpha=8
- All=15
- End
- Enum DepthFunc
- Never=0
- Less=1
- Equal=2
- LessEqual=3
- Greater=4
- NotEqual=5
- GreaterEqual=6
- Always=7
- End
- Enum CullMode
- None=0
- Back=1
- Front=2
- End
- #rem monkeydoc @hidden
- #end
- Class GraphicsDevice
- Method New()
- Init()
- End
- Method New( width:Int,height:Int )
- Init()
-
- _deviceSize=New Vec2i( width,height )
-
- _rtargetSize=_deviceSize
- End
-
- Method Resize( size:Vec2i )
-
- _deviceSize=size
-
- If Not _rtarget _rtargetSize=size
-
- _dirty|=Dirty.Viewport|Dirty.Scissor
- End
-
- Property RenderTargetSize:Vec2i()
-
- Return _rtargetSize
- End
-
- '***** PUBLIC *****
-
- Property RenderTarget:RenderTarget()
- Return _rtarget
-
- Setter( renderTarget:RenderTarget )
- FlushTarget()
-
- _rtarget=renderTarget
-
- _rtargetSize=_rtarget ? _rtarget.Size Else _deviceSize
-
- _dirty|=Dirty.RenderTarget|Dirty.Viewport|Dirty.Scissor
- End
-
- Property Viewport:Recti()
-
- Return _viewport
-
- Setter( viewport:Recti )
- If viewport=_viewport Return
-
- FlushTarget()
-
- _viewport=viewport
-
- _dirty|=Dirty.Viewport|Dirty.Scissor
- End
-
- Property Scissor:Recti()
-
- Return _scissor
-
- Setter( scissor:Recti )
- If scissor=_scissor Return
-
- FlushTarget()
-
- _scissor=scissor
-
- _dirty|=Dirty.Scissor
- End
-
- Property ColorMask:ColorMask()
-
- Return _colorMask
-
- Setter( colorMask:ColorMask )
- If colorMask=_colorMask Return
-
- _colorMask=colorMask
-
- _dirty|=Dirty.ColorMask
- End
-
- Property DepthMask:Bool()
-
- Return _depthMask
-
- Setter( depthMask:Bool )
- If depthMask=_depthMask Return
-
- _depthMask=depthMask
-
- _dirty|=Dirty.DepthMask
- End
-
- Property DepthFunc:DepthFunc()
-
- Return _depthFunc
-
- Setter( depthFunc:DepthFunc )
- If depthFunc=_depthFunc Return
-
- _depthFunc=depthFunc
-
- _dirty2|=Dirty.DepthFunc
- End
-
- Property BlendMode:BlendMode()
-
- Return _blendMode
-
- Setter( blendMode:BlendMode )
- If blendMode=_blendMode Return
-
- _blendMode=blendMode
-
- _dirty2|=Dirty.BlendMode
- End
-
- Property CullMode:CullMode()
-
- Return _cullMode
-
- Setter( cullMode:CullMode )
- If cullMode=_cullMode Return
-
- _cullMode=cullMode
-
- _dirty2|=Dirty.CullMode
- End
- Property RetroMode:Bool()
-
- Return _retroMode
-
- Setter( retroMode:Bool )
- If retroMode=_retroMode Return
-
- _retroMode=retroMode
-
- _dirty2|=Dirty.RetroMode
- End
-
- Property VertexBuffer:VertexBuffer()
-
- Return _vertexBuffer
-
- Setter( vbuffer:VertexBuffer )
- If vbuffer=_vertexBuffer Return
-
- _vertexBuffer=vbuffer
-
- _dirty2|=Dirty.VertexBuffer
- End
-
- Property IndexBuffer:IndexBuffer()
-
- Return _indexBuffer
-
- Setter( ibuffer:IndexBuffer )
- If ibuffer=_indexBuffer Return
-
- _indexBuffer=ibuffer
-
- _dirty2|=Dirty.IndexBuffer
- End
-
- Property RenderPass:Int()
-
- Return _rpass
-
- Setter( rpass:Int )
- If rpass=_rpass Return
-
- _rpass=rpass
-
- _dirty2|=Dirty.Shader
- End
-
- Property Shader:Shader()
-
- Return _shader
- Setter( shader:Shader )
- If shader=_shader Return
-
- _shader=shader
-
- _dirty2|=Dirty.Shader
- End
-
- Method BindUniformBlock( ublock:UniformBlock )
-
- _ublocks[ublock.BlockId]=ublock
- End
-
- Method GetUniformBlock:UniformBlock( block:Int )
-
- Return _ublocks[block]
- End
-
- Method CopyPixels( rect:Recti,pixmap:Pixmap,dstx:Int,dsty:Int )
-
- Validate()
-
- glReadPixels( rect.X,rect.Y,rect.Width,rect.Height,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.PixelPtr( dstx,dsty ) )
-
- If Not _rtarget And rect.Height>1
- If rect.min.x<>0 Or rect.min.y<>0 Or rect.Size<>_rtargetSize
- pixmap.Window( rect.X,rect.Y,rect.Width,rect.Height ).FlipY()
- Else
- pixmap.FlipY()
- End
- Endif
- End
-
- Method Clear( color:Color,depth:Float=1 )
-
- Validate()
-
- If Not _scissorTest glEnable( GL_SCISSOR_TEST )
-
- Local mask:GLbitfield
-
- If _colorMask
- glClearColor( color.r,color.g,color.b,color.a )
- mask|=GL_COLOR_BUFFER_BIT
- Endif
-
- If _depthMask
- glClearDepth( depth )
- mask|=GL_DEPTH_BUFFER_BIT
- Endif
-
- glClear( mask )
-
- If Not _scissorTest glDisable( GL_SCISSOR_TEST )
-
- _modified=True
- glCheck()
- End
-
- Method Render( order:Int,count:Int,offset:Int=0 )
-
- Validate2()
-
- If Not _shaderValid Return
-
- Local n:=order*count
-
- Select order
- Case 1 glDrawArrays( GL_POINTS,offset,n )
- Case 2 glDrawArrays( GL_LINES,offset,n )
- Case 3 glDrawArrays( GL_TRIANGLES,offset,n )
- Default
- For Local i:=0 Until count
- glDrawArrays( GL_TRIANGLE_FAN,offset+i*order,order )
- Next
- End
-
- _modified=True
- glCheck()
- End
- Method RenderIndexed( order:Int,count:Int,offset:Int=0 )
-
- Validate2()
- If Not _shaderValid Return
-
- Local n:=order*count
-
- Local gltype:GLenum,pitch:Int
-
- Select _indexBuffer.Format
- Case IndexFormat.UINT16
- gltype=GL_UNSIGNED_SHORT
- pitch=2
- Case IndexFormat.UINT32
- gltype=GL_UNSIGNED_INT
- pitch=4
- Default
- RuntimeError( "Invalid index format" )
- End
- Local p:=Cast<UByte Ptr>( offset * pitch )
-
- Select order
- Case 1 glDrawElements( GL_POINTS,n,gltype,p )
- Case 2 glDrawElements( GL_LINES,n,gltype,p )
- Case 3 glDrawElements( GL_TRIANGLES,n,gltype,p )
- Default
- For Local i:=0 Until count
- glDrawElements( GL_TRIANGLE_FAN,order,gltype,p+i*order*pitch )
- Next
- End
- _modified=True
-
- glCheck()
- End
- Method FlushTarget()
-
- 'Print "GraphicsDevice.FlushTarget _modified="+_modified
-
- If Not _modified Return
-
- _modified=False
-
- If Not _rtarget Or Not _rtarget.NumColorTextures Return
-
- ' Validate()
-
- For Local i:=0 Until _rtarget.NumColorTextures
-
- Local texture:=_rtarget.GetColorTexture( i )
-
- texture.Modified( _viewport & _scissor )
- Next
-
- End
-
- Private
-
- Enum Dirty
- '
- 'stuff that affects Clear()
- RenderTarget= $0001
- Viewport= $0002
- Scissor= $0004
- ColorMask= $0008
- DepthMask= $0010
- '
- 'stuff that affects Render()
- DepthFunc= $0100
- BlendMode= $0200
- CullMode= $0400
- RetroMode= $0800
- VertexBuffer= $1000
- IndexBuffer= $2000
- Shader= $4000
- '
- All= $7fff
- '
- End
-
- Field _dirty:Dirty
- Field _dirty2:Dirty
- Field _modified:Bool
-
- Field _rtarget:RenderTarget
- Field _rtargetSize:Vec2i
- Field _deviceSize:Vec2i
- Field _viewport:Recti
- Field _scissor:Recti
- Field _scissorTest:Bool
- Field _colorMask:ColorMask
- Field _depthMask:Bool
- Field _depthFunc:DepthFunc
- Field _blendMode:BlendMode
- Field _cullMode:CullMode
- Field _retroMode:Bool
- Field _vertexBuffer:VertexBuffer
- Field _indexBuffer:IndexBuffer
- Field _ublocks:=New UniformBlock[8]
- Field _shader:Shader
- Field _shaderValid:Bool
- Field _rpass:Int
-
- Global _glSeq:Int
- Global _current:GraphicsDevice
- Global _defaultFbo:GLint
- Global _defaultDrawBuf:GLint
- Global _defaultReadBuf:GLint
-
- Method Init()
- _depthFunc=DepthFunc.Less
- _blendMode=BlendMode.Alpha
- _cullMode=CullMode.Back
- _colorMask=ColorMask.All
- _depthMask=True
- End
-
- Function InitGL()
- glCheck()
-
- glPixelStorei( GL_PACK_ALIGNMENT,1 )
- glPixelStorei( GL_UNPACK_ALIGNMENT,1 )
-
- glGetIntegerv( GL_FRAMEBUFFER_BINDING,Varptr _defaultFbo )
-
- If BBGL_seamless_cube_map glEnable( GL_TEXTURE_CUBE_MAP_SEAMLESS )
-
- If Not BBGL_ES
- glGetIntegerv( GL_DRAW_BUFFER,Varptr _defaultDrawBuf )
- glGetIntegerv( GL_READ_BUFFER,Varptr _defaultReadBuf )
- glEnable( GL_POINT_SPRITE )
- glEnable( GL_VERTEX_PROGRAM_POINT_SIZE )
- glEnable( GL_TEXTURE_CUBE_MAP_SEAMLESS )
- Endif
-
- glCheck()
- End
-
- Method Validate()
-
- glCheck()
- If _glSeq<>glGraphicsSeq
- _glSeq=glGraphicsSeq
- _current=Null
- InitGL()
- Endif
- If _current<>Self
- If _current _current.FlushTarget()
- _current=Self
- _dirty=Dirty.All
- _dirty2=Dirty.All
- Else
- If Not _dirty Return
- Endif
-
- If _dirty & Dirty.RenderTarget
-
- If _rtarget
- _rtarget.Bind()
- Else
- glBindFramebuffer( GL_FRAMEBUFFER,_defaultFbo )
-
- If Not BBGL_ES
- glDrawBuffer( _defaultDrawBuf )
- glReadBuffer( _defaultReadBuf )
- Endif
-
- Endif
- Endif
-
- If _dirty & Dirty.Viewport
-
- If _rtarget
- glViewport( _viewport.X,_viewport.Y,Max( _viewport.Width,0 ),Max( _viewport.Height,0 ) )
- Else
- glViewport( _viewport.X,_deviceSize.y-_viewport.Bottom,Max( _viewport.Width,0 ),Max( _viewport.Height,0 ) )
- End
-
- Endif
-
- If _dirty & Dirty.Scissor
-
- Local scissor:=_scissor & _viewport
-
- _scissorTest=scissor<>_viewport
-
- If _scissorTest glEnable( GL_SCISSOR_TEST ) Else glDisable( GL_SCISSOR_TEST )
-
- If _rtarget
- glScissor( scissor.X,scissor.Y,Max( scissor.Width,0 ),Max( scissor.Height,0 ) )
- Else
- glScissor( scissor.X,_rtargetSize.y-scissor.Bottom,Max( scissor.Width,0 ),Max( scissor.Height,0 ) )
- Endif
-
- Endif
-
- If _dirty & Dirty.ColorMask
-
- Local r:=Bool( _colorMask & ColorMask.Red )
- Local g:=Bool( _colorMask & ColorMask.Green )
- Local b:=Bool( _colorMask & ColorMask.Blue )
- Local a:=Bool( _colorMask & ColorMask.Alpha )
-
- glColorMask( r,g,b,a )
-
- Endif
-
- If _dirty & Dirty.DepthMask
-
- glDepthMask( _depthMask )
-
- Endif
-
- glCheck()
-
- _dirty=Null
- End
-
- Method Validate2()
-
- Validate()
-
- glCheck()
-
- If _dirty2 & Dirty.DepthFunc
-
- If _depthFunc=DepthFunc.Always
- glDisable( GL_DEPTH_TEST )
- Else
- glEnable( GL_DEPTH_TEST )
- Select _depthFunc
- Case DepthFunc.Never
- glDepthFunc( GL_NEVER )
- Case DepthFunc.Less
- glDepthFunc( GL_LESS )
- Case DepthFunc.Equal
- glDepthFunc( GL_EQUAL )
- Case DepthFunc.LessEqual
- glDepthFunc( GL_LEQUAL )
- Case DepthFunc.Greater
- glDepthFunc( GL_GREATER )
- Case DepthFunc.NotEqual
- glDepthFunc( GL_NOTEQUAL )
- Case DepthFunc.GreaterEqual
- glDepthFunc( GL_GEQUAL )
- Default
- RuntimeError( "Invalid DepthFunc" )
- End
- Endif
-
- Endif
-
- If _dirty2 & Dirty.BlendMode
-
- If _blendMode=BlendMode.Opaque
- glDisable( GL_BLEND )
- Else
- glEnable( GL_BLEND )
- Select _blendMode
- Case BlendMode.Alpha
- glBlendFunc( GL_ONE,GL_ONE_MINUS_SRC_ALPHA )
- Case BlendMode.Additive
- glBlendFunc( GL_ONE,GL_ONE )
- Case BlendMode.Multiply
- glBlendFunc( GL_DST_COLOR,GL_ONE_MINUS_SRC_ALPHA )
- Default
- RuntimeError( "Invalid BlendMode" )
- End
- Endif
- Endif
-
- If _dirty2 & Dirty.CullMode
-
- If _cullMode=CullMode.None
- glDisable( GL_CULL_FACE )
- Else
- glEnable( GL_CULL_FACE )
- Select _cullMode
- Case CullMode.Back
- glCullFace( GL_FRONT )
- Case CullMode.Front
- glCullFace( GL_BACK )
- Default
- RuntimeError( "Invalid CullMode" )
- End
- Endif
-
- Endif
-
- If _dirty2 & Dirty.RetroMode
-
- If _retroMode<>glRetroMode
- glRetroMode=_retroMode
- glRetroSeq+=1
- Endif
-
- Endif
-
- If _dirty2 & Dirty.VertexBuffer
-
- _vertexBuffer.Bind()
- Endif
- If _dirty2 & Dirty.IndexBuffer
-
- If _indexBuffer _indexBuffer.Bind()
- Endif
-
- If _dirty2 & Dirty.Shader
-
- _ublocks[0]=_shader.Uniforms
-
- _shaderValid=_shader.RenderPassMask & 1 Shl _rpass <> 0
-
- If _shaderValid _shader.Bind( _rpass )
- Endif
-
- _vertexBuffer.Validate()
-
- If _indexBuffer _indexBuffer.Validate()
- If _shaderValid _shader.ValidateUniforms( _rpass,_ublocks )
-
- glCheck()
-
- _dirty2=Null
- End
-
- End
|