Hi,
Ok, found the problem with multitexuring.
- Fixed Multitexturing error (it was in TSurface.Render)
- Fixed DDD_TEXTURE_BLEND error in TTexture.Render()
- Added TTexture.SetCoordset() and TTexture.GetCoordset()
TTexture.SetCoordset allows you to set which uv set a texture uses. Same as Blitz3D TextureCoords. Only uvset 0 (default) and 1 is available (just like in Blitz3D)
Below is the code update:
Texture.bmx:
Strict
Import Pub.Glew
?Linux
Import "-lX11"
Import "-lXxf86vm"
?
Import Brl.BlitzGL
Import Brl.LinkedList
Import Brl.Pixmap
Import "Error.bmx"
Import "HardwareInfo.bmx"
' Cube-Faces
Const DDD_TEXTURE_POSX = 1 ' Positive X = Right
Const DDD_TEXTURE_NEGX = 2 ' Negative X = Left
Const DDD_TEXTURE_POSY = 3 ' Positive Y = Top
Const DDD_TEXTURE_NEGY = 4 ' Negative Y = Bottom
Const DDD_TEXTURE_POSZ = 5 ' Positive Z = Back
Const DDD_TEXTURE_NEGZ = 6 ' Negative Z = Front
' Rendering-Modes
Const DDD_TEXTURE_TRANSFORM = %00000001
Const DDD_TEXTURE_MIPMAP = %00000010
Const DDD_TEXTURE_SPHEREMAP = %00000100
Const DDD_TEXTURE_CUBEMAP = %00001000
' Cube-Modes
Const DDD_TEXTURE_REFLECTION = 1
Const DDD_TEXTURE_NORMAL = 2
' Filter
Const DDD_TEXTURE_SHARP = 1
Const DDD_TEXTURE_BLURRED = 2
' Clamp-Modes
Const DDD_TEXTURE_CLAMP = 1
Const DDD_TEXTURE_REPEAT = 2
' Blending-Modes
Const DDD_TEXTURE_REPLACE = 1
Const DDD_TEXTURE_MODULATE = 2
Const DDD_TEXTURE_MODULATE2X = 3
Const DDD_TEXTURE_DECAL = 4
Const DDD_TEXTURE_BLEND = 5
Const DDD_TEXTURE_ADD = 6
Const DDD_TEXTURE_SUBTRACT = 7
Const DDD_TEXTURE_INTERPOLATE = 8
Const DDD_TEXTURE_DOT3 = 9
Type TTexture
Global List : TList
Field Name : String
Field Filename : String
Field TextureID : Int
Field CubeFace : Int
Field RenderMode : Int
Field BlendMode : Int
Field CubeMode : Int
Field Coordset : Int
Field Position : Float[2]
Field Rotation : Float
Field Scale : Float[2]
Method SetName(Name:String)
Self.Name = Name
End Method
Method GetName:String()
Return Self.Name
End Method
Method SetFilename(Name:String)
Self.Filename = Filename
End Method
Method GetFilename:String()
Return Self.Filename
End Method
Method SetPixmap(Pixmap:TPixmap)
Local Target:Int, Width:Int, Height:Int
If Pixmap = Null Then TDreiDeError.DisplayError("Pixmap does not exist!")
If Self.RenderMode & DDD_TEXTURE_CUBEMAP Then
Target = GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT+Self.CubeFace-1
Else
Target = GL_TEXTURE_2D
EndIf
glBindTexture(Target, Self.TextureID)
' Has Pixmap the Pixelformat RGBA8888?
If Pixmap.Format <> PF_RGBA8888 Then Pixmap = Pixmap.Convert(PF_RGBA8888)
' Get supported TextureSize
Width = Pixmap.Width
Height = Pixmap.Height
bglAdjustTexSize width,height
If (Width <> Pixmap.Width) Or (Height <> Pixmap.Height) Then
Pixmap = ResizePixmap(Pixmap, Width, Height)
EndIf
If Self.RenderMode & DDD_TEXTURE_MIPMAP Then
gluBuild2DMipmaps(Target, 4, Width, Height, GL_RGBA, GL_UNSIGNED_BYTE, ..
Pixmap.Pixels)
Else
glTexImage2D(Target, 0, 4, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, ..
Pixmap.Pixels)
EndIf
End Method
Method SetCubeFace(Face:Int)
If (Face > 0) Or (Face < 6) Then
Self.CubeFace = Face
Else
TDreiDeError.DisplayError("Cubeface is not supported!")
EndIf
End Method
Method GetCubeFace:Int()
Return Self.CubeFace
End Method
Method SetRenderMode(Mode:Int)
If (Mode & DDD_TEXTURE_CUBEMAP) And (THardwareInfo.CubemapSupport = False) Then
TDreiDeError.DisplayError("Cubemapping is not supported!")
EndIf
Self.RenderMode = Mode
End Method
Method AddRenderMode(Mode:Int)
If (Mode & DDD_TEXTURE_CUBEMAP) And (THardwareInfo.CubemapSupport = False) Then
TDreiDeError.DisplayError("Cubemapping is not supported!")
EndIf
Self.RenderMode :| Mode
End Method
Method RemoveRenderMode(Mode:Int)
Self.RenderMode :& (~Mode)
End Method
Method GetRenderMode:Int()
Return Self.RenderMode
End Method
Method SetBlendMode(Mode:Int)
If (Mode => DDD_TEXTURE_REPLACE ) And (Mode <= DDD_TEXTURE_DOT3) Then
Self.BlendMode = Mode
Else
TDreiDeError.DisplayError("Blendmode is not supported!")
EndIf
End Method
Method GetBlendMode:Int()
Return Self.BlendMode
End Method
Method SetCubeMode(Mode:Int)
If (Mode > 0) And (Mode < 3) Then
Self.CubeMode = Mode
Else
TDreiDeError.DisplayError("Cubemode is not supported!")
EndIf
End Method
Method GetCubeMode:Int()
Return Self.CubeMode
End Method
Method SetFilter(MinFilter:Int, MagFilter:Int)
Local Filter:Int
If Self.RenderMode & DDD_TEXTURE_CUBEMAP Then
glBindTexture(GL_TEXTURE_2D, 0)
Else
glBindTexture(GL_TEXTURE_2D, Self.TextureID)
EndIf
' Setting Minificant Filter
If Self.RenderMode & DDD_TEXTURE_MIPMAP Then
If MinFilter = DDD_TEXTURE_SHARP Then
Filter = GL_NEAREST_MIPMAP_NEAREST
Else
Filter = GL_LINEAR_MIPMAP_LINEAR
EndIf
Else
If MinFilter = DDD_TEXTURE_SHARP Then
Filter = GL_NEAREST
Else
Filter = GL_LINEAR
EndIf
EndIf
If Self.RenderMode & DDD_TEXTURE_CUBEMAP Then
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, Filter)
Else
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter)
EndIf
' Setting Magnificant Filter
If MagFilter = DDD_TEXTURE_SHARP Then
Filter = GL_NEAREST
Else
Filter = GL_LINEAR
EndIf
If Self.RenderMode & DDD_TEXTURE_CUBEMAP Then
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, Filter)
Else
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter)
EndIf
End Method
Method SetClamp(UClamp:Int, VClamp:Int)
Local Target:Int
If Self.RenderMode & DDD_TEXTURE_CUBEMAP Then
glBindTexture(GL_TEXTURE_2D, 0)
Target = GL_TEXTURE_CUBE_MAP
Else
glBindTexture(GL_TEXTURE_2D, Self.TextureID)
Target = GL_TEXTURE_2D
EndIf
If UClamp = DDD_TEXTURE_CLAMP Then
glTexParameteri(Target, GL_TEXTURE_WRAP_S, GL_CLAMP)
Else
glTexParameteri(Target, GL_TEXTURE_WRAP_S, GL_REPEAT)
EndIf
If VClamp = DDD_TEXTURE_CLAMP Then
glTexParameteri(Target, GL_TEXTURE_WRAP_T, GL_CLAMP)
Else
glTexParameteri(Target, GL_TEXTURE_WRAP_T, GL_REPEAT)
EndIf
End Method
Method SetPosition(U:Float, V:Float)
Self.Position[0] = U
Self.Position[1] = V
End Method
Method Translate(U:Float, V:Float)
Self.Position[0] :+ U
Self.Position[1] :+ V
End Method
Method GetPosition(U:Float Var, V:Float Var)
U = Self.Position[0]
V = Self.Position[1]
End Method
Method GetU:Float()
Return Self.Position[0]
End Method
Method GetV:Float()
Return Self.Position[0]
End Method
Method SetRotation(Roll:Float)
Self.Rotation = Roll
End Method
Method Turn(Roll:Float)
Self.Rotation :+ Roll
End Method
Method GetRotation:Float()
Return Self.Rotation
End Method
Method SetScale(U:Float, V:Float)
Self.Scale[0] = U
Self.Scale[1] = V
End Method
Method GetScale(U:Float Var, V:Float Var)
U = Self.Scale[0]
V = Self.Scale[1]
End Method
Method GetScaleU:Float()
Return Self.Scale[0]
End Method
Method GetScaleV:Float()
Return Self.Scale[1]
End Method
Method SetCoordset(uvset:Int)
If uvset=>0 And uvset<=1
self.Coordset = uvset
Else
TDreiDeError.DisplayError("Coordset not supported!")
EndIf
EndMethod
Method GetCoordset()
Return self.Coordset
EndMethod
Method Render()
Local Matrix:Int
If Self.RenderMode & DDD_TEXTURE_TRANSFORM Then
glGetIntegerv(GL_MATRIX_MODE, Varptr(Matrix))
glMatrixMode(GL_TEXTURE)
glLoadIdentity()
glTranslatef(Self.Position[0], Self.Position[1], 0.0)
glRotatef(Self.Rotation, 0.0, 0.0, 1.0)
glScalef(Self.Scale[0], Self.Scale[1], -1.0)
glMatrixMode(Matrix)
EndIf
If Self.RenderMode & DDD_TEXTURE_SPHEREMAP Then
glEnable(GL_TEXTURE_2D)
glDisable(GL_TEXTURE_CUBE_MAP)
glEnable(GL_TEXTURE_GEN_S)
glEnable(GL_TEXTURE_GEN_T)
glDisable(GL_TEXTURE_GEN_R)
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP)
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP)
ElseIf Self.RenderMode & DDD_TEXTURE_CUBEMAP Then
glEnable(GL_TEXTURE_CUBE_MAP)
' Bind all Sides of the CubeMap
glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_X, Self.TextureID)
glBindTexture(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, Self.TextureID)
glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, Self.TextureID)
glBindTexture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, Self.TextureID)
glBindTexture(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, Self.TextureID)
glBindTexture(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, Self.TextureID)
glEnable(GL_TEXTURE_GEN_S)
glEnable(GL_TEXTURE_GEN_T)
glEnable(GL_TEXTURE_GEN_R)
If Self.CubeMode = DDD_TEXTURE_REFLECTION Then
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB)
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB)
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB)
Else
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB)
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB)
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_ARB)
EndIf
Else
glDisable(GL_TEXTURE_CUBE_MAP)
glDisable(GL_TEXTURE_GEN_S)
glDisable(GL_TEXTURE_GEN_T)
glDisable(GL_TEXTURE_GEN_R)
glEnable(GL_TEXTURE_2D)
glBindTexture(GL_TEXTURE_2D, Self.TextureID)
EndIf
If THardwareInfo.TexBlendSupport Then
Select Self.BlendMode
Case DDD_TEXTURE_REPLACE
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE)
Case DDD_TEXTURE_MODULATE
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
Case DDD_TEXTURE_DECAL
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
Case DDD_TEXTURE_BLEND
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND)
Case DDD_TEXTURE_MODULATE2X
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE)
glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE, 2.0)
Case DDD_TEXTURE_ADD
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD)
Case DDD_TEXTURE_SUBTRACT
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_SUBTRACT_ARB)
Case DDD_TEXTURE_INTERPOLATE
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_INTERPOLATE_ARB)
Case DDD_TEXTURE_DOT3
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE)
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_DOT3_RGB)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PREVIOUS)
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE)
End Select
EndIf
End Method
Method New()
glGenTextures(1, Varptr(Self.TextureID))
Self.Name = "Unnamed Texture"
Self.Filename = ""
Self.CubeFace = DDD_TEXTURE_POSX
Self.RenderMode = DDD_TEXTURE_TRANSFORM
Self.BlendMode = DDD_TEXTURE_MODULATE
Self.CubeMode = DDD_TEXTURE_REFLECTION
Self.Position = [0.0, 0.0]
Self.Rotation = 0.0
Self.Scale = [1.0, 1.0]
Self.SetFilter(DDD_TEXTURE_BLURRED, DDD_TEXTURE_BLURRED)
TTexture.List.AddLast(Self)
End Method
Method Delete()
glDeleteTextures(1, Varptr(Self.TextureID))
End Method
End Type
Surface.bmx:
Strict
Import Pub.Glew
Import Brl.LinkedList
Import Brl.Bank
Import "Error.bmx"
Import "HardwareInfo.bmx"
Import "Material.bmx"
Import "Camera.bmx"
Type TSurface
Global List : TList
Field Material : TMaterial
Field Dynamic : Int
Field VertexCount : Int
Field Vertices : TBank[5]
Field VertexBuffer : Int[5]
Field TriangleCount : Int
Field Triangles : TBank
Field TriangleBuffer : Int
Method SetMaterial(Material:TMaterial)
Self.Material = Material
End Method
Method GetMaterial:TMaterial()
Return Self.Material
End Method
Method SetDynamic(Enable:Int)
If Enable Then
Self.Dynamic = True
Else
Self.Dynamic = False
EndIf
End Method
Method GetDynamic:Int()
Return Self.Dynamic
End Method
Method CountVertices:Int()
Return Self.VertexCount
End Method
Method CreateVertex:Int(X:Float, Y:Float, Z:Float, U:Float=0.0, V:Float=0.0)
' Resize Vertex-, Noramal-, UV0-, UV1- and ColorBuffer
Self.Vertices[0].Resize((Self.VertexCount+1)*12)
Self.Vertices[1].Resize((Self.VertexCount+1)*12)
Self.Vertices[2].Resize((Self.VertexCount+1)*8)
Self.Vertices[3].Resize((Self.VertexCount+1)*8)
Self.Vertices[4].Resize((Self.VertexCount+1)*16)
Self.VertexCount :+ 1
' Set Vertex-Defaults
Self.SetVertexPosition(Self.VertexCount-1, X, Y, Z)
Self.SetVertexNormal(Self.VertexCount-1, 0.0, 0.0, 0.0)
Self.SetVertexTexCoords(Self.VertexCount-1, U, V)
Self.SetVertexTexCoords(Self.VertexCount-1, U, V, 1)
Self.SetVertexColor(Self.VertexCount-1, 1.0, 1.0, 1.0)
Return Self.VertexCount-1
End Method
Method SetVertexPosition(Vertex:Int, X:Float, Y:Float, Z:Float)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
Self.Vertices[0].PokeFloat(Vertex*12, X)
Self.Vertices[0].PokeFloat(Vertex*12+4, Y)
Self.Vertices[0].PokeFloat(Vertex*12+8, Z)
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method GetVertexPosition(Vertex:Int, X:Float Var, Y:Float Var, Z:Float Var)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
X = Self.Vertices[0].PeekFloat(Vertex*12)
Y = Self.Vertices[0].PeekFloat(Vertex*12+4)
Z = Self.Vertices[0].PeekFloat(Vertex*12+8)
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method GetVertexX:Float(Vertex:Int)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
Return Self.Vertices[0].PeekFloat(Vertex*12)
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method GetVertexY:Float(Vertex:Int)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
Return Self.Vertices[0].PeekFloat(Vertex*12+4)
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method GetVertexZ:Float(Vertex:Int)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
Return Self.Vertices[0].PeekFloat(Vertex*12+8)
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method SetVertexNormal(Vertex:Int, X:Float, Y:Float, Z:Float)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
Self.Vertices[1].PokeFloat(Vertex*12, X)
Self.Vertices[1].PokeFloat(Vertex*12+4, Y)
Self.Vertices[1].PokeFloat(Vertex*12+8, Z)
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method GetVertexNormal(Vertex:Int, X:Float Var, Y:Float Var, Z:Float Var)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
X = Self.Vertices[1].PeekFloat(Vertex*12)
Y = Self.Vertices[1].PeekFloat(Vertex*12+4)
Z = Self.Vertices[1].PeekFloat(Vertex*12+8)
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method GetVertexNX:Float(Vertex:Int)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
Return Self.Vertices[1].PeekFloat(Vertex*12)
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method GetVertexNY:Float(Vertex:Int)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
Return Self.Vertices[1].PeekFloat(Vertex*12+4)
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method GetVertexNZ:Float(Vertex:Int)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
Return Self.Vertices[1].PeekFloat(Vertex*12+8)
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method SetVertexTexCoords(Vertex:Int, U:Float, V:Float, UVSet:Int=0)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
If UVSet = 0 Then
Self.Vertices[2].PokeFloat(Vertex*8, U)
Self.Vertices[2].PokeFloat(Vertex*8+4, V)
ElseIf UVSet = 1
Self.Vertices[3].PokeFloat(Vertex*8, U)
Self.Vertices[3].PokeFloat(Vertex*8+4, V)
Else
Notify("UV-Set not avariable!", True)
EndIf
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method GetVertexTexCoords(Vertex:Int, U:Float Var, V:Float Var, UVSet:Int=0)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
If UVSet = 0 Then
U = Self.Vertices[2].PeekFloat(Vertex*8)
V = Self.Vertices[2].PeekFloat(Vertex*8+4)
ElseIf UVSet = 1
U = Self.Vertices[3].PeekFloat(Vertex*8)
V = Self.Vertices[3].PeekFloat(Vertex*8+4)
Else
TDreiDeError.DisplayError("UV-Set is not avariable!")
EndIf
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method GetVertexU:Float(Vertex:Int, UVSet:Int=0)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
If UVSet = 0 Then
Return Self.Vertices[2].PeekFloat(Vertex*8)
ElseIf UVSet = 1
Return Self.Vertices[3].PeekFloat(Vertex*8)
Else
TDreiDeError.DisplayError("UV-Set is not avariable!")
EndIf
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method GetVertexV:Float(Vertex:Int, UVSet:Int=0)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
If UVSet = 0 Then
Return Self.Vertices[2].PeekFloat(Vertex*8+4)
ElseIf UVSet = 1
Return Self.Vertices[3].PeekFloat(Vertex*8+4)
Else
TDreiDeError.DisplayError("UV-Set is not avariable!")
EndIf
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method SetVertexColor(Vertex:Int, Red:Float, Green:Float, Blue:Float, Alpha:Float=1.0)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
Self.Vertices[4].PokeFloat(Vertex*16, Red)
Self.Vertices[4].PokeFloat(Vertex*16+4, Green)
Self.Vertices[4].PokeFloat(Vertex*16+8, Blue)
Self.Vertices[4].PokeFloat(Vertex*16+12, Alpha)
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method GetVertexColor(Vertex:Int, Red:Float Var, Green:Float Var, Blue:Float Var, Alpha:Float Var)
Red = Self.Vertices[4].PeekFloat(Vertex*16)
Green = Self.Vertices[4].PeekFloat(Vertex*16+4)
Blue = Self.Vertices[4].PeekFloat(Vertex*16+8)
Alpha = Self.Vertices[4].PeekFloat(Vertex*16+12)
End Method
Method GetVertexRed:Float(Vertex:Int)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
Return Self.Vertices[4].PeekFloat(Vertex*16)
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method GetVertexGreen:Float(Vertex:Int)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
Return Self.Vertices[4].PeekFloat(Vertex*16+4)
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method GetVertexBlue:Float(Vertex:Int)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
Return Self.Vertices[4].PeekFloat(Vertex*16+8)
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method GetVertexAlpha:Float(Vertex:Int)
If (Vertex => 0) And (Vertex < Self.VertexCount) Then
Return Self.Vertices[4].PeekFloat(Vertex*16+12)
Else
TDreiDeError.DisplayError("Vertex does not exist!")
EndIf
End Method
Method UpdateVertices(Position:Int=True, Normal:Int=True, UV0:Int=True, UV1:Int=True, ..
Color:Int=True)
Local Flag:Int
' Check, if there VertexBufferObject-Support
If Not THardwareInfo.VBOSupport Then Return
If Self.Dynamic Then
Flag = GL_DYNAMIC_DRAW
Else
Flag = GL_STATIC_DRAW
EndIf
' Transfer Buffer(s) from WorkRAM into VideoRAM
If Position Then
glBindBufferARB(GL_ARRAY_BUFFER, Self.VertexBuffer[0])
glBufferDataARB(GL_ARRAY_BUFFER, Self.VertexCount*12, Self.Vertices[0].Buf(), Flag)
EndIf
If Normal Then
glBindBufferARB(GL_ARRAY_BUFFER, Self.VertexBuffer[1])
glBufferDataARB(GL_ARRAY_BUFFER, Self.VertexCount*12, Self.Vertices[1].Buf(), Flag)
EndIf
If UV0 Then
glBindBufferARB(GL_ARRAY_BUFFER, Self.VertexBuffer[2])
glBufferDataARB(GL_ARRAY_BUFFER, Self.VertexCount*8, Self.Vertices[2].Buf(), Flag)
EndIf
If UV1 Then
glBindBufferARB(GL_ARRAY_BUFFER, Self.VertexBuffer[3])
glBufferDataARB(GL_ARRAY_BUFFER, Self.VertexCount*8, Self.Vertices[3].Buf(), Flag)
EndIf
If Color Then
glBindBufferARB(GL_ARRAY_BUFFER, Self.VertexBuffer[4])
glBufferDataARB(GL_ARRAY_BUFFER, Self.VertexCount*16, Self.Vertices[4].Buf(), Flag)
EndIf
End Method
Method CreateTriangle:Int(V0:Int, V1:Int, V2:Int)
' Check, if vertices exists
If (V0 < 0) Or (V0 => Self.VertexCount) Then ..
TDreiDeError.DisplayError("Vertex V0 does not exist!")
If (V1 < 0) Or (V1 => Self.VertexCount) Then ..
TDreiDeError.DisplayError("Vertex V1 does not exist!")
If (V2 < 0) Or (V2 => Self.VertexCount) Then ..
TDreiDeError.DisplayError("Vertex V2 does not exist!")
' Resize TriangleBuffer
Self.Triangles.Resize((Self.TriangleCount+1)*12)
Self.TriangleCount :+1
' Set Vertex-Indices
Self.SetTriangle(Self.TriangleCount-1, V0, V1, V2)
Return Self.TriangleCount-1
End Method
Method SetTriangle(Triangle:Int, V0:Int, V1:Int, V2:Int)
If (Triangle < 0) Or (Triangle => Self.TriangleCount) Then ..
TDreiDeError.DisplayError("Triangle does not exist!")
If (V0 < 0) Or (V0 => Self.VertexCount) Then ..
TDreiDeError.DisplayError("Vertex V0 does not exist!")
If (V1 < 0) Or (V1 => Self.VertexCount) Then ..
TDreiDeError.DisplayError("Vertex V1 does not exist!")
If (V2 < 0) Or (V2 => Self.VertexCount) Then ..
TDreiDeError.DisplayError("Vertex V2 does not exist!")
Self.Triangles.PokeInt(Triangle*12, V0)
Self.Triangles.PokeInt(Triangle*12+4, V1)
Self.Triangles.PokeInt(Triangle*12+8, V2)
End Method
Method GetTriangle(Triangle:Int, V0:Int Var, V1:Int Var, V2:Int Var)
If (Triangle < 0) Or (Triangle => Self.TriangleCount) Then ..
TDreiDeError.DisplayError("Triangle does not exist!")
V0 = Self.Triangles.PeekInt(Triangle*12)
V1 = Self.Triangles.PeekInt(Triangle*12+4)
V2 = Self.Triangles.PeekInt(Triangle*12+8)
End Method
Method UpdateTriangles()
Local Flag:Int
' Check, if there VertexBufferObject-Support
If Not THardwareInfo.VBOSupport Then Return
If Self.Dynamic Then
Flag = GL_DYNAMIC_DRAW
Else
Flag = GL_STATIC_DRAW
EndIf
' Transfer TriangleBuffer from WorkRAM into VideoRAM
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Self.TriangleBuffer)
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER, Self.TriangleCount*12, Self.Triangles.Buf(), ..
Flag)
End Method
Method GetWidth:Float()
Local Vertex:Int, X:Float, MinX:Float, MaxX:Float
' Find the lowest and highest X-Coordinate
For Vertex = 0 To Self.VertexCount-1
X = Self.Vertices[0].PeekFloat(Vertex*12)
If X < MinX Then MinX = X
If X > MaxX Then MaxX = X
Next
Return MaxX-MinX
End Method
Method GetHeight:Float()
Local Vertex:Int, Y:Float, MinY:Float, MaxY:Float
' Find the lowest and highest Y-Coordinate
For Vertex = 0 To Self.VertexCount-1
Y = Self.Vertices[0].PeekFloat(Vertex*12+4)
If Y < MinY Then MinY = Y
If Y > MaxY Then MaxY = Y
Next
Return MaxY-MinY
End Method
Method GetDepth:Float()
Local Vertex:Int, Z:Float, MinZ:Float, MaxZ:Float
' Find the lowest and highest Z-Coordinate
For Vertex = 0 To Self.VertexCount-1
Z = Self.Vertices[0].PeekFloat(Vertex*12+8)
If Z < MinZ Then MinZ = Z
If Z > MaxZ Then MaxZ = Z
Next
Return MaxZ-MinZ
End Method
Method Invert(Normals:Int=True, Update:Int=True)
Local Index:Int, V0:Int, V2:Int
For Index = 0 To Self.TriangleCount-1
V0 = Self.Triangles.PeekInt(Index*12)
V2 = Self.Triangles.PeekInt(Index*12+8)
Self.Triangles.PokeInt(Index*12, V2)
Self.Triangles.PokeInt(Index*12+8, V0)
Next
If Update Then Self.UpdateTriangles()
If Normals Then
For Index = 0 To Self.VertexCount-1
Self.Vertices[1].PokeFloat(Index*12, -Self.Vertices[1].PeekFloat(Index*12))
Self.Vertices[1].PokeFloat(Index*12+4, -Self.Vertices[1].PeekFloat(Index*12+4))
Self.Vertices[1].PokeFloat(Index*12+8, -Self.Vertices[1].PeekFloat(Index*12+8))
Next
If Update Then Self.UpdateVertices(False, True, False, False, False)
EndIf
End Method
Method SmoothNormals(Update:Int=True)
Local FaceNormals:Float[,], Index:Int, Index2:Float, Indices:Int[,]
Local Vertices:Float[3, 3], Edges:Float[2, 3], Length:Float
Local Normal:Float[3], Count:Int
FaceNormals = New Float[Self.TriangleCount, 3]
Indices = New Int[Self.TriangleCount, 3]
' Calculate alle FaceNormals
For Index = 0 To Self.TriangleCount-1
' Get VertexIndices
Indices[Index, 0] = Self.Triangles.PeekInt(Index*12)
Indices[Index, 1] = Self.Triangles.PeekInt(Index*12+4)
Indices[Index, 2] = Self.Triangles.PeekInt(Index*12+8)
' Get VertexPositions
Vertices[0, 0] = Self.Vertices[0].PeekFloat(Indices[Index, 0]*12)
Vertices[0, 1] = Self.Vertices[0].PeekFloat(Indices[Index, 0]*12+4)
Vertices[0, 2] = Self.Vertices[0].PeekFloat(Indices[Index, 0]*12+8)
Vertices[1, 0] = Self.Vertices[0].PeekFloat(Indices[Index, 1]*12)
Vertices[1, 1] = Self.Vertices[0].PeekFloat(Indices[Index, 1]*12+4)
Vertices[1, 2] = Self.Vertices[0].PeekFloat(Indices[Index, 1]*12+8)
Vertices[2, 0] = Self.Vertices[0].PeekFloat(Indices[Index, 2]*12)
Vertices[2, 1] = Self.Vertices[0].PeekFloat(Indices[Index, 2]*12+4)
Vertices[2, 2] = Self.Vertices[0].PeekFloat(Indices[Index, 2]*12+8)
' Get EdgeVectors between Vertex1-Vertex0 and Vertex2-Vertex0
Edges[0, 0] = Vertices[1, 0]-Vertices[0, 0]
Edges[0, 1] = Vertices[1, 1]-Vertices[0, 1]
Edges[0, 2] = Vertices[1, 2]-Vertices[0, 2]
Edges[1, 0] = Vertices[2, 0]-Vertices[0, 0]
Edges[1, 1] = Vertices[2, 1]-Vertices[0, 1]
Edges[1, 2] = Vertices[2, 2]-Vertices[0, 2]
' Calculate the FaceNormal by using the CrossProduct
FaceNormals[Index, 0] = Edges[0, 1]*Edges[1, 2] - Edges[0, 2]*Edges[1, 1]
FaceNormals[Index, 1] = Edges[0, 2]*Edges[1, 0] - Edges[0, 0]*Edges[1, 2]
FaceNormals[Index, 2] = Edges[0, 0]*Edges[1, 1] - Edges[0, 1]*Edges[1, 0]
' Caluclate the Length of this Vector
Length = Sqr(FaceNormals[Index, 0]*FaceNormals[Index, 0] + ..
FaceNormals[Index, 1]*FaceNormals[Index, 1] + ..
FaceNormals[Index, 2]*FaceNormals[Index, 2])
' Normalize this Vector
FaceNormals[Index, 0] :/ Length
FaceNormals[Index, 1] :/ Length
FaceNormals[Index, 2] :/ Length
Next
' Interpolate all VertexNormals
For Index = 0 To Self.VertexCount-1
Count = 0
Normal[0] = 0.0
Normal[1] = 0.0
Normal[2] = 0.0
For Index2 = 0 To Self.TriangleCount-1
If (Indices[Index2, 0] = Index) Or ..
(Indices[Index2, 1] = Index) Or ..
(Indices[Index2, 2] = Index) Then
Normal[0] :+ FaceNormals[Index2, 0]
Normal[1] :+ FaceNormals[Index2, 1]
Normal[2] :+ FaceNormals[Index2, 2]
Count :+ 1
EndIf
Next
If Count > 0 Then
Normal[0] :/ Count
Normal[1] :/ Count
Normal[2] :/ Count
Self.SetVertexNormal(Index, Normal[0], Normal[1], Normal[2])
EndIf
Next
If Update Then Self.UpdateVertices(False, True, False, False, False)
End Method
Method SetColor(Red:Float, Green:Float, Blue:Float, Alpha:Float=1.0, Update:Int=True)
Local Index:Int
For Index = 0 To Self.VertexCount-1
Self.Vertices[4].PokeFloat(Index*16, Red)
Self.Vertices[4].PokeFloat(Index*16+4, Green)
Self.Vertices[4].PokeFloat(Index*16+8, Blue)
Self.Vertices[4].PokeFloat(Index*16+12, Alpha)
Next
If Update Then Self.UpdateVertices(False, False, False, False, True)
End Method
Method Render()
' Check for Material
If Self.Material Then
Local Layer:Int
Local UVSet:Int
' Set Material specific OpenGL-Settings
Self.Material.Render()
' Go through all layers
For Layer = 0 Until THardwareInfo.MaxTextures
If Self.Material.TextureList[Layer] Then
UVSet = 2 + Self.Material.TextureList[Layer].GetCoordset()
glClientActiveTexture(GL_TEXTURE0+Layer)
glEnableClientState(GL_TEXTURE_COORD_ARRAY)
glActiveTexture(GL_TEXTURE0+Layer)
If THardwareInfo.VBOSupport Then
' Bind Texture-Coordinates 0
glBindBufferARB(GL_ARRAY_BUFFER, Self.VertexBuffer[UVSet])
glTexCoordPointer(2, GL_FLOAT, 0, Null)
Else
glTexCoordPointer(2, GL_FLOAT, 0, Self.Vertices[UVSet].Buf())
EndIf
Self.Material.TextureList[Layer].Render()
EndIf
Next
Else
' No Material -> Set defaults
TMaterial.RenderDefault()
EndIf
' Check for VertexBufferObject-Support
If THardwareInfo.VBOSupport Then
' Render all Buffers of the VideoRAM
' Bind Vertex-Color
glBindBufferARB(GL_ARRAY_BUFFER, Self.VertexBuffer[4])
glColorPointer(4, GL_FLOAT, 0, Null)
' Bind Normals
glBindBufferARB(GL_ARRAY_BUFFER, Self.VertexBuffer[1])
glNormalPointer(GL_FLOAT, 0, Null)
' Bind Vertices
glBindBufferARB(GL_ARRAY_BUFFER, Self.VertexBuffer[0])
glVertexPointer(3, GL_FLOAT, 0, Null)
' Bind TriangleBuffer
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, Self.TriangleBuffer)
' Display Triangles
glDrawElements(GL_TRIANGLES, Self.TriangleCount*3, GL_UNSIGNED_INT, Null)
Else
' Render all Buffers of the WorkRAM
glColorPointer(4, GL_FLOAT, 0, Self.Vertices[4].Buf())
glNormalPointer(GL_FLOAT, 0, Self.Vertices[1].Buf())
glVertexPointer(3, GL_FLOAT, 0, Self.Vertices[0].Buf())
glDrawElements(GL_TRIANGLES, Self.TriangleCount*3, GL_UNSIGNED_INT, ..
Self.Triangles.Buf())
EndIf
End Method
Method New()
Local Index:Int
Self.Material = Null
Self.Dynamic = False
Self.VertexCount = 0
' Create Vertex- and TriangleBuffer(s)
For Index = 0 To 4
Self.Vertices[Index] = CreateBank()
Next
Self.Triangles = CreateBank()
If THardwareInfo.VBOSupport Then
' Generate HardwareBuffers for Vertices and Traingles
glGenBuffersARB(5, Self.VertexBuffer)
glGenBuffersARB(1, Varptr(Self.TriangleBuffer))
EndIf
Self.TriangleCount = 0
TSurface.List.AddLast(Self)
End Method
Method Delete()
If THardwareInfo.VBOSupport Then
' Delete HardwareBuffers for Vertices and Traingles
glDeleteBuffers(5, Self.VertexBuffer)
glDeleteBuffers(1, Varptr(Self.TriangleBuffer))
EndIf
End Method
End Type