#Region "Color Combiner"
Private Sub SETCOMBINE(ByVal w0 As UInteger, ByVal w1 As UInteger)
If GLExtensions.GLFragProg Then
EnableCombiner = True
Dim ShaderCachePos As Integer = -1
For i As Integer = 0 To FragShaderCache.Length - 1
If (w0 = FragShaderCache(i).MUXS0) And (w1 = FragShaderCache(i).MUXS1) Then
ShaderCachePos = i
Exit For
End If
Next
If ShaderCachePos > -1 Then
Gl.glBindProgramARB(Gl.GL_FRAGMENT_PROGRAM_ARB, FragShaderCache(ShaderCachePos).FragShader)
Else
DecodeMUX(w0, w1, FragShaderCache, FragShaderCache.Length)
End If
Else
EnableCombiner = False
End If
End Sub
Private Sub SETFOGCOLOR(ByVal CMDDword() As Byte)
FogColor(0) = CMDDword(4) / 255
FogColor(1) = CMDDword(5) / 255
FogColor(2) = CMDDword(6) / 255
FogColor(3) = CMDDword(7) / 255
End Sub
Private Sub SETBLENDCOLOR(ByVal CMDDword() As Byte)
BlendColor(0) = CMDDword(4) / 255
BlendColor(1) = CMDDword(5) / 255
BlendColor(2) = CMDDword(6) / 255
BlendColor(3) = CMDDword(7) / 255
End Sub
Private Sub SETENVCOLOR(ByVal CMDDword() As Byte)
EnvironmentColor(0) = CMDDword(4) / 255
EnvironmentColor(1) = CMDDword(5) / 255
EnvironmentColor(2) = CMDDword(6) / 255
EnvironmentColor(3) = CMDDword(7) / 255
End Sub
Private Sub SETPRIMCOLOR(ByVal CMDDword() As Byte)
PrimColor(0) = CMDDword(4) / 255
PrimColor(1) = CMDDword(5) / 255
PrimColor(2) = CMDDword(6) / 255
PrimColor(3) = CMDDword(7) / 255
End Sub
Public Sub PrecompileMUXS(ByVal MUXLIST1() As UInteger, ByVal MUXLIST2() As UInteger)
If MUXLIST1.Length = MUXLIST2.Length Then
For i As Integer = 0 To MUXLIST1.Length - 1
DecodeMUX(MUXLIST1(i), MUXLIST2(i), FragShaderCache, i)
Next
End If
PrecompiledCombiner = True
End Sub
Public Sub DecodeMUX(ByVal MUXS0 As UInteger, ByVal MUXS1 As UInteger, ByRef Cache() As ShaderCache, ByVal CacheEntry As Integer)
ColorA(0) = (MUXS0 >> 20) And &HF
ColorB(0) = (MUXS1 >> 28) And &HF
ColorC(0) = (MUXS0 >> 15) And &H1F
ColorD(0) = (MUXS1 >> 15) And &H7
AlphaA(0) = (MUXS0 >> 12) And &H7
AlphaB(0) = (MUXS1 >> 12) And &H7
AlphaC(0) = (MUXS0 >> 9) And &H7
AlphaD(0) = (MUXS1 >> 9) And &H7
ColorA(1) = (MUXS0 >> 5) And &HF
ColorB(1) = (MUXS1 >> 24) And &HF
ColorC(1) = (MUXS0 >> 0) And &H1F
ColorD(1) = (MUXS1 >> 6) And &H7
AlphaA(1) = (MUXS1 >> 21) And &H7
AlphaB(1) = (MUXS1 >> 3) And &H7
AlphaC(1) = (MUXS1 >> 18) And &H7
AlphaD(1) = (MUXS1 >> 0) And &H7
If GLExtensions.GLFragProg Then
ReDim Preserve Cache(CacheEntry)
Cache(CacheEntry).MUXS0 = MUXS0
Cache(CacheEntry).MUXS1 = MUXS1
CreateShader(2, Cache(CacheEntry).FragShader)
Else
'TODO - At least limited color combiner emulation without using pixel shaders *shrug*
End If
End Sub
Private Sub CreateShader(ByVal Cycles As Integer, ByRef prog As Int32)
Dim ShaderLines As String = "!!ARBfp1.0" & Environment.NewLine & Environment.NewLine & _
"TEMP CCReg;" & Environment.NewLine & _
"TEMP ACReg;" & Environment.NewLine & Environment.NewLine & _
"TEMP CCRegister_0;" & Environment.NewLine & _
"TEMP CCRegister_1;" & Environment.NewLine & _
"TEMP ACRegister_0;" & Environment.NewLine & _
"TEMP ACRegister_1;" & Environment.NewLine & _
"TEMP Texel0;" & Environment.NewLine & _
"TEMP Texel1;" & Environment.NewLine & _
"PARAM EnvColor = program.env[0];" & Environment.NewLine & _
"PARAM PrimColor = program.env[1];" & Environment.NewLine & _
"ATTRIB Shade = fragment.color.primary;" & Environment.NewLine & Environment.NewLine & _
"OUTPUT FinalColor = result.color;" & Environment.NewLine & Environment.NewLine & _
"TEX Texel0, fragment.texcoord[0], texture[0], 2D;" & Environment.NewLine & _
"TEX Texel1, fragment.texcoord[1], texture[1], 2D;" & Environment.NewLine & Environment.NewLine
For i As Integer = 0 To Cycles - 1
Select Case ColorA(i)
Case RDP.G_CCMUX_COMBINED
ShaderLines += "MOV CCRegister_0.rgb, CCReg;" & Environment.NewLine
Case RDP.G_CCMUX_TEXEL0
ShaderLines += "MOV CCRegister_0.rgb, Texel0;" & Environment.NewLine
Case RDP.G_CCMUX_TEXEL1
ShaderLines += "MOV CCRegister_0.rgb, Texel1;" & Environment.NewLine
Case RDP.G_CCMUX_PRIMITIVE
ShaderLines += "MOV CCRegister_0.rgb, PrimColor;" & Environment.NewLine
Case RDP.G_CCMUX_SHADE
ShaderLines += "MOV CCRegister_0.rgb, Shade;" & Environment.NewLine
Case RDP.G_CCMUX_ENVIRONMENT
ShaderLines += "MOV CCRegister_0.rgb, EnvColor;" & Environment.NewLine
Case RDP.G_CCMUX_1
ShaderLines += "MOV CCRegister_0.rgb, {1.0,1.0,1.0,1.0};" & Environment.NewLine
Case RDP.G_CCMUX_COMBINED_ALPHA
ShaderLines += "MOV CCRegister_0.rgb, CCReg.a;" & Environment.NewLine
Case RDP.G_CCMUX_TEXEL0_ALPHA
ShaderLines += "MOV CCRegister_0.rgb, Texel0.a;" & Environment.NewLine
Case RDP.G_CCMUX_TEXEL1_ALPHA
ShaderLines += "MOV CCRegister_0.rgb, Texel1.a;" & Environment.NewLine
Case RDP.G_CCMUX_PRIMITIVE_ALPHA
ShaderLines += "MOV CCRegister_0.rgb, PrimColor.a;" & Environment.NewLine
Case RDP.G_CCMUX_SHADE_ALPHA
ShaderLines += "MOV CCRegister_0.rgb, Shade.a;" & Environment.NewLine
Case RDP.G_CCMUX_ENV_ALPHA
ShaderLines += "MOV CCRegister_0.rgb, EnvColor.a;" & Environment.NewLine
Case RDP.G_CCMUX_LOD_FRACTION
ShaderLines += "MOV CCRegister_0.rgb, {0.0,0.0,0.0,0.0};" & Environment.NewLine
Case RDP.G_CCMUX_PRIM_LOD_FRAC
ShaderLines += "MOV CCRegister_0.rgb, {0.0,0.0,0.0,0.0};" & Environment.NewLine
Case 15
ShaderLines += "MOV CCRegister_0.rgb, {0.0,0.0,0.0,0.0};" & Environment.NewLine
Case Else
ShaderLines += "MOV CCRegister_0.rgb, {0.0,0.0,0.0,0.0};" & Environment.NewLine
End Select
Select Case ColorB(i)
Case RDP.G_CCMUX_COMBINED
ShaderLines += "MOV CCRegister_1.rgb, CCReg;" & Environment.NewLine
Case RDP.G_CCMUX_TEXEL0
ShaderLines += "MOV CCRegister_1.rgb, Texel0;" & Environment.NewLine
Case RDP.G_CCMUX_TEXEL1
ShaderLines += "MOV CCRegister_1.rgb, Texel1;" & Environment.NewLine
Case RDP.G_CCMUX_PRIMITIVE
ShaderLines += "MOV CCRegister_1.rgb, PrimColor;" & Environment.NewLine
Case RDP.G_CCMUX_SHADE
ShaderLines += "MOV CCRegister_1.rgb, Shade;" & Environment.NewLine
Case RDP.G_CCMUX_ENVIRONMENT
ShaderLines += "MOV CCRegister_1.rgb, EnvColor;" & Environment.NewLine
Case RDP.G_CCMUX_1
ShaderLines += "MOV CCRegister_1.rgb, {1.0,1.0,1.0,1.0};" & Environment.NewLine
Case RDP.G_CCMUX_COMBINED_ALPHA
ShaderLines += "MOV CCRegister_1.rgb, CCReg.a;" & Environment.NewLine
Case RDP.G_CCMUX_TEXEL0_ALPHA
ShaderLines += "MOV CCRegister_1.rgb, Texel0.a;" & Environment.NewLine
Case RDP.G_CCMUX_TEXEL1_ALPHA
ShaderLines += "MOV CCRegister_1.rgb, Texel1.a;" & Environment.NewLine
Case RDP.G_CCMUX_PRIMITIVE_ALPHA
ShaderLines += "MOV CCRegister_1.rgb, PrimColor.a;" & Environment.NewLine
Case RDP.G_CCMUX_SHADE_ALPHA
ShaderLines += "MOV CCRegister_1.rgb, Shade.a;" & Environment.NewLine
Case RDP.G_CCMUX_ENV_ALPHA
ShaderLines += "MOV CCRegister_1.rgb, EnvColor.a;" & Environment.NewLine
Case Else
ShaderLines += "MOV CCRegister_1.rgb, {0.0,0.0,0.0,0.0};" & Environment.NewLine
End Select
ShaderLines += "SUB CCRegister_0, CCRegister_0, CCRegister_1;" & Environment.NewLine & Environment.NewLine
Select Case ColorC(i)
Case RDP.G_CCMUX_COMBINED
ShaderLines += "MOV CCRegister_1.rgb, CCReg;" & Environment.NewLine
Case RDP.G_CCMUX_TEXEL0
ShaderLines += "MOV CCRegister_1.rgb, Texel0;" & Environment.NewLine
Case RDP.G_CCMUX_TEXEL1
ShaderLines += "MOV CCRegister_1.rgb, Texel1;" & Environment.NewLine
Case RDP.G_CCMUX_PRIMITIVE
ShaderLines += "MOV CCRegister_1.rgb, PrimColor;" & Environment.NewLine
Case RDP.G_CCMUX_SHADE
ShaderLines += "MOV CCRegister_1.rgb, Shade;" & Environment.NewLine
Case RDP.G_CCMUX_ENVIRONMENT
ShaderLines += "MOV CCRegister_1.rgb, EnvColor;" & Environment.NewLine
Case RDP.G_CCMUX_1
ShaderLines += "MOV CCRegister_1.rgb, {1.0,1.0,1.0,1.0};" & Environment.NewLine
Case RDP.G_CCMUX_COMBINED_ALPHA
ShaderLines += "MOV CCRegister_1.rgb, CCReg.a;" & Environment.NewLine
Case RDP.G_CCMUX_TEXEL0_ALPHA
ShaderLines += "MOV CCRegister_1.rgb, Texel0.a;" & Environment.NewLine
Case RDP.G_CCMUX_TEXEL1_ALPHA
ShaderLines += "MOV CCRegister_1.rgb, Texel1.a;" & Environment.NewLine
Case RDP.G_CCMUX_PRIMITIVE_ALPHA
ShaderLines += "MOV CCRegister_1.rgb, PrimColor.a;" & Environment.NewLine
Case RDP.G_CCMUX_SHADE_ALPHA
ShaderLines += "MOV CCRegister_1.rgb, Shade.a;" & Environment.NewLine
Case RDP.G_CCMUX_ENV_ALPHA
ShaderLines += "MOV CCRegister_1.rgb, EnvColor.a;" & Environment.NewLine
Case RDP.G_CCMUX_K5
ShaderLines += "MOV CCRegister_1.rgb, {1.0,1.0,1.0,1.0};" & Environment.NewLine
Case RDP.G_CCMUX_0
ShaderLines += "MOV CCRegister_1.rgb, {0.0,0.0,0.0,0.0};" & Environment.NewLine
Case Else
ShaderLines += "MOV CCRegister_1.rgb, {0.0,0.0,0.0,0.0};" & Environment.NewLine
End Select
ShaderLines += "MUL CCRegister_0, CCRegister_0, CCRegister_1;" & Environment.NewLine & Environment.NewLine
Select Case ColorD(i)
Case RDP.G_CCMUX_COMBINED
ShaderLines += "MOV CCRegister_1.rgb, CCReg;" & Environment.NewLine
Case RDP.G_CCMUX_TEXEL0
ShaderLines += "MOV CCRegister_1.rgb, Texel0;" & Environment.NewLine
Case RDP.G_CCMUX_TEXEL1
ShaderLines += "MOV CCRegister_1.rgb, Texel1;" & Environment.NewLine
Case RDP.G_CCMUX_PRIMITIVE
ShaderLines += "MOV CCRegister_1.rgb, PrimColor;" & Environment.NewLine
Case RDP.G_CCMUX_SHADE
ShaderLines += "MOV CCRegister_1.rgb, Shade;" & Environment.NewLine
Case RDP.G_CCMUX_ENVIRONMENT
ShaderLines += "MOV CCRegister_1.rgb, EnvColor;" & Environment.NewLine
Case RDP.G_CCMUX_1
ShaderLines += "MOV CCRegister_1.rgb, {1.0,1.0,1.0,1.0};" & Environment.NewLine
Case Else
ShaderLines += "MOV CCRegister_1.rgb, {0.0,0.0,0.0,0.0};" & Environment.NewLine
End Select
ShaderLines += "ADD CCRegister_0, CCRegister_0, CCRegister_1;" & Environment.NewLine & Environment.NewLine
Select Case AlphaA(i)
Case RDP.G_ACMUX_COMBINED
ShaderLines += "MOV ACRegister_0.a, ACReg;" & Environment.NewLine
Case RDP.G_ACMUX_TEXEL0
ShaderLines += "MOV ACRegister_0.a, Texel0;" & Environment.NewLine
Case RDP.G_ACMUX_TEXEL1
ShaderLines += "MOV ACRegister_0.a, Texel1;" & Environment.NewLine
Case RDP.G_ACMUX_PRIMITIVE
ShaderLines += "MOV ACRegister_0.a, PrimColor;" & Environment.NewLine
Case RDP.G_ACMUX_SHADE
ShaderLines += "MOV ACRegister_0.a, Shade;" & Environment.NewLine
Case RDP.G_ACMUX_ENVIRONMENT
ShaderLines += "MOV ACRegister_0.a, EnvColor;" & Environment.NewLine
Case RDP.G_ACMUX_1
ShaderLines += "MOV ACRegister_0.a, {1.0,1.0,1.0,1.0};" & Environment.NewLine
Case RDP.G_ACMUX_0
ShaderLines += "MOV ACRegister_0.a, {0.0,0.0,0.0,0.0};" & Environment.NewLine
Case Else
ShaderLines += "MOV ACRegister_0.a, {0.0,0.0,0.0,0.0};" & Environment.NewLine
End Select
Select Case AlphaB(i)
Case RDP.G_ACMUX_COMBINED
ShaderLines += "MOV ACRegister_1.a, ACReg.a;" & Environment.NewLine
Case RDP.G_ACMUX_TEXEL0
ShaderLines += "MOV ACRegister_1.a, Texel0.a;" & Environment.NewLine
Case RDP.G_ACMUX_TEXEL1
ShaderLines += "MOV ACRegister_1.a, Texel1.a;" & Environment.NewLine
Case RDP.G_ACMUX_PRIMITIVE
ShaderLines += "MOV ACRegister_1.a, PrimColor.a;" & Environment.NewLine
Case RDP.G_ACMUX_SHADE
ShaderLines += "MOV ACRegister_1.a, Shade.a;" & Environment.NewLine
Case RDP.G_ACMUX_ENVIRONMENT
ShaderLines += "MOV ACRegister_1.a, EnvColor.a;" & Environment.NewLine
Case RDP.G_ACMUX_1
ShaderLines += "MOV ACRegister_1.a, {1.0,1.0,1.0,1.0};" & Environment.NewLine
Case RDP.G_ACMUX_0
ShaderLines += "MOV ACRegister_1.a, {0.0,0.0,0.0,0.0};" & Environment.NewLine
Case Else
ShaderLines += "MOV ACRegister_1.a, {0.0,0.0,0.0,0.0};" & Environment.NewLine
End Select
ShaderLines += "SUB ACRegister_0.a, ACRegister_0.a, ACRegister_1.a;" & Environment.NewLine
Select Case AlphaC(i)
Case RDP.G_ACMUX_COMBINED
ShaderLines += "MOV ACRegister_1.a, ACReg.a;" & Environment.NewLine
Case RDP.G_ACMUX_TEXEL0
ShaderLines += "MOV ACRegister_1.a, Texel0.a;" & Environment.NewLine
Case RDP.G_ACMUX_TEXEL1
ShaderLines += "MOV ACRegister_1.a, Texel1.a;" & Environment.NewLine
Case RDP.G_ACMUX_PRIMITIVE
ShaderLines += "MOV ACRegister_1.a, PrimColor.a;" & Environment.NewLine
Case RDP.G_ACMUX_SHADE
ShaderLines += "MOV ACRegister_1.a, Shade.a;" & Environment.NewLine
Case RDP.G_ACMUX_ENVIRONMENT
ShaderLines += "MOV ACRegister_1.a, EnvColor.a;" & Environment.NewLine
Case RDP.G_ACMUX_1
ShaderLines += "MOV ACRegister_1.a, {1.0,1.0,1.0,1.0};" & Environment.NewLine
Case RDP.G_ACMUX_0
ShaderLines += "MOV ACRegister_1.a, {0.0,0.0,0.0,0.0};" & Environment.NewLine
Case Else
ShaderLines += "MOV ACRegister_1.a, {0.0,0.0,0.0,0.0};" & Environment.NewLine
End Select
ShaderLines += "MUL ACRegister_0.a, ACRegister_0.a, ACRegister_1.a;" & Environment.NewLine
Select Case AlphaD(i)
Case RDP.G_ACMUX_COMBINED
ShaderLines += "MOV ACRegister_1.a, ACReg.a;" & Environment.NewLine
Case RDP.G_ACMUX_TEXEL0
ShaderLines += "MOV ACRegister_1.a, Texel0.a;" & Environment.NewLine
Case RDP.G_ACMUX_TEXEL1
ShaderLines += "MOV ACRegister_1.a, Texel1.a;" & Environment.NewLine
Case RDP.G_ACMUX_PRIMITIVE
ShaderLines += "MOV ACRegister_1.a, PrimColor.a;" & Environment.NewLine
Case RDP.G_ACMUX_SHADE
ShaderLines += "MOV ACRegister_1.a, Shade.a;" & Environment.NewLine
Case RDP.G_ACMUX_ENVIRONMENT
ShaderLines += "MOV ACRegister_1.a, EnvColor.a;" & Environment.NewLine
Case RDP.G_ACMUX_1
ShaderLines += "MOV ACRegister_1.a, {1.0,1.0,1.0,1.0};" & Environment.NewLine
Case RDP.G_ACMUX_0
ShaderLines += "MOV ACRegister_1.a, {0.0,0.0,0.0,0.0};" & Environment.NewLine
Case Else
ShaderLines += "MOV ACRegister_1.a, {0.0,0.0,0.0,0.0};" & Environment.NewLine
End Select
ShaderLines += "ADD ACRegister_0.a, ACRegister_0.a, ACRegister_1.a;" & Environment.NewLine & Environment.NewLine
ShaderLines += "MOV CCReg.rgb, CCRegister_0;" & Environment.NewLine
ShaderLines += "MOV ACReg.a, ACRegister_0.a;" & Environment.NewLine
Next
ShaderLines += "MOV CCReg.a, ACReg.a;" & Environment.NewLine
ShaderLines += "MOV FinalColor, CCReg;" & Environment.NewLine
ShaderLines += "END" & Environment.NewLine
Dim program() As Byte = System.Text.Encoding.ASCII.GetBytes(ShaderLines)
Gl.glGenProgramsARB(1, prog)
Gl.glBindProgramARB(Gl.GL_FRAGMENT_PROGRAM_ARB, prog)
Gl.glProgramStringARB(Gl.GL_FRAGMENT_PROGRAM_ARB, Gl.GL_PROGRAM_FORMAT_ASCII_ARB, program.Length, program)
End Sub
#End Region