08-30-2025, 07:06 AM
(This post was last modified: 08-30-2025, 07:09 AM by Unseen Machine.)
Code: (Select All)
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
'// Unseen GDK_GL - Examples - Flag Demo \\
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
REM $INCLUDE:'UnseenGDK_DEV\GDK2_GL.bi'
Debug%% = GDK_TRUE
DIM SHARED MainLight AS GDK2_Light
DIM SHARED Flag1 AS GDK_Cloth_Model
DIM SHARED Flag2 AS GDK_Cloth_Model
DIM SHARED TimeElapsed AS SINGLE
'///////////////////////////////////// System Initialisation ////////////////////////////////////////////////
GDK2_System_New "UnseenGDK_Dev\Projects\", 800, 600, GDK_FALSE, "Unseen GDK 3 Dev - Cloths v.01"
_DISPLAYORDER _GLRENDER , _SOFTWARE
_MOUSEHIDE
GDK_Init_GL = GDK_TRUE '// Set the _GL sub to initialise mode - i.e Load things
GDK_Allow_GL = GDK_TRUE '// Allow the GL sub to run
'//////////////////////////////////////// Main Loop ////////////////////////////////////////////////////////////
DO
GDK2_System_Update '// Update input handlers, set fps/limit
TimeElapsed = TimeElapsed + (GDK_System.GT - GDK_System.Last_GT) ' Accumulate elapsed time for the sine wave animation
IF GDK_Init_GL = GDK_FALSE THEN
GDK_GL_Cloth_Update Flag1, TimeElapsed
GDK_GL_Cloth_Update Flag2, TimeElapsed
END IF
LOOP UNTIL GDK_KB(0).ESC '// Quit on ESCAPE
GDK2_GL_Cloth_Free Flag1
GDK2_GL_Cloth_Free Flag2
SYSTEM
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
REM $INCLUDE:'UnseenGDK_Dev\GDK2_GL.bm'
'///////////////////////////////////////////////////////////////////////////////////////////////////////////////
SUB _GL
IF GDK_Allow_GL = GDK_TRUE THEN
'// Bog standard Open_GL Setup \\
_GLCLEARDEPTH 1
_GLCLEARCOLOR 0, 0, 0, 1
_GLENABLE _GL_DEPTH_TEST
_GLENABLE _GL_LIGHTING
_GLENABLE _GL_TEXTURE_2D
_GLMATRIXMODE _GL_PROJECTION
_GLLOADIDENTITY
_GLUPERSPECTIVE 65, GDK_System.WH.X / GDK_System.WH.Y, 1, 1000
_GLMATRIXMODE _GL_MODELVIEW
_GLLOADIDENTITY
_GLVIEWPORT 0, 0, GDK_System.WH.X, GDK_System.WH.Y
_GLENABLE MainLight.ID ' Enable the specific light source (GL_LIGHT0)
IF GDK_Init_GL = GDK_TRUE THEN '/////// Load Loop //////
DIM AmbientColor AS GDK2_Color_3
DIM SpecularColor AS GDK2_Color_3
DIM LightPosition(3) AS SINGLE
DIM LightDirLength AS SINGLE
DIM TextureID AS LONG
MainLight.ID = _GL_LIGHT0
MainLight.Type = 1
MainLight.Direction.X = 0
MainLight.Direction.Y = 1
MainLight.Direction.Z = -1
LightDirLength = SQR(MainLight.Direction.X * MainLight.Direction.X + MainLight.Direction.Y * MainLight.Direction.Y + MainLight.Direction.Z * MainLight.Direction.Z)
IF LightDirLength > 0 THEN
MainLight.Direction.X = MainLight.Direction.X / LightDirLength
MainLight.Direction.Y = MainLight.Direction.Y / LightDirLength
MainLight.Direction.Z = MainLight.Direction.Z / LightDirLength
END IF
MainLight.Color.R = 1
MainLight.Color.G = 1
MainLight.Color.B = 1
MainLight.Intensity = 1
MainLight.Enabled = 1
AmbientColor.R = 1
AmbientColor.G = 0.7
AmbientColor.B = 0.8
_GLLIGHTFV MainLight.ID, _GL_AMBIENT, _OFFSET(AmbientColor)
_GLLIGHTFV MainLight.ID, _GL_DIFFUSE, _OFFSET(MainLight.Color)
SpecularColor.R = 0.5
SpecularColor.G = 0.8
SpecularColor.B = 0.8
_GLLIGHTFV MainLight.ID, _GL_SPECULAR, _OFFSET(SpecularColor)
LightPosition(0) = MainLight.Direction.X
LightPosition(1) = MainLight.Direction.Y
LightPosition(2) = MainLight.Direction.Z
LightPosition(3) = 0
_GLLIGHTFV MainLight.ID, _GL_POSITION, _OFFSET(LightPosition(0))
TextureID = GDK_GL_LOAD_TEXTURE("England.png")
GDK_GL_Cloth_Create Flag1, 40, 40, 50, 50, TextureID
Flag1.Parameters.Wave_Amplitude = 2
Flag1.Parameters.Wave_Frequency = 0.6
Flag1.Parameters.Wave_Speed = .8
Flag1.Parameters.Wave_Direction.X = 1
Flag1.Parameters.Wave_Direction.Y = 0
Flag1.Parameters.Wave_Direction.Z = 0
GDK_GL_Cloth_Create Flag2, 10, 10, 60, 60, TextureID
Flag2.Parameters.Wave_Amplitude = 8
Flag2.Parameters.Wave_Frequency = 0.7
Flag2.Parameters.Wave_Speed = .1
Flag2.Parameters.Wave_Direction.X = 1
Flag2.Parameters.Wave_Direction.Y = 0
Flag2.Parameters.Wave_Direction.Z = 0
GDK_Init_GL = GDK_FALSE
ELSE '////// Render Loop //////
GDK_GL_CLS
_GLTRANSLATEF 0, 0, -100
_GLPUSHMATRIX
_GLTRANSLATEF -35, -10, 0
_GLROTATEF -90, 1, 0, 0
GDK_GL_Cloth_Render Flag1
_GLPOPMATRIX
_GLPUSHMATRIX
_GLTRANSLATEF 25, 0, 0
GDK_GL_Cloth_Render Flag2
_GLPOPMATRIX
_DISPLAY
END IF
END IF
END SUB
TYPE GDK_Cloth_Vertex
Initial_Position AS GDK2_Vertex_F ' Original 3D position (X, Y, Z) for sine wave base
Current_Position AS GDK2_Vertex_F ' Current deformed 3D position (X, Y, Z) for rendering
Normal AS GDK2_Vertex_F ' Vertex normal for smooth shading
TexCoord AS GDK2_UV_F ' Texture coordinates (U, V)
Fixed AS INTEGER ' Flag: 1 if fixed (e.g., attached to flagpole), 0 otherwise
END TYPE
TYPE GDK_Cloth_Parameters
Wave_Amplitude AS SINGLE ' Max displacement of the wave
Wave_Frequency AS SINGLE ' How many waves/ripples across the flag
Wave_Speed AS SINGLE ' How fast the wave propagates
Wave_Direction AS GDK2_Vertex_F ' Direction the wave travels
Damping_Factor AS SINGLE ' Reduce wave amplitude over distance if desired
END TYPE
TYPE GDK_Cloth_Model
' Mesh Data from GDK2_GL_Terrain
Vert_Data AS _MEM '// Where the vertices are stored
Tri_Data AS _MEM '// Where the triangles are stored (Index buffer)
Norm_Data AS _MEM '// Where the normals are stored
ST_Data AS _MEM '// Where the texture coords are stored
' Dimensions
Num_Verts AS LONG
Num_Tris AS LONG
Width AS INTEGER
Height AS INTEGER
' Cloth-Specific Data
Parameters AS GDK_Cloth_Parameters ' Physics parameters for this cloth
Texture_ID AS LONG ' ID of the texture applied to this cloth
Visible AS LONG ' Flag: 1 if visible, 0 otherwise
Needs_Normal_Update AS LONG ' Flag to trigger normal recalculation
END TYPE
SUB GDK_GL_Cloth_Create (Cloth AS GDK_Cloth_Model, Num_Rows AS LONG, Num_Cols AS LONG, Width AS SINGLE, Height AS SINGLE, Texture_ID AS LONG)
DIM idx AS LONG, r AS LONG, c AS LONG
DIM x_pos AS SINGLE, y_pos AS SINGLE, z_pos AS SINGLE
DIM v1 AS LONG, v2 AS LONG, v3 AS LONG, v4 AS LONG
DIM TempVertex AS GDK_Cloth_Vertex
DIM TempIndex AS LONG
DIM VertSize AS LONG
DIM TriSize AS LONG
VertSize = LEN(TempVertex)
TriSize = LEN(TempIndex)
Cloth.Width = Num_Cols
Cloth.Height = Num_Rows
Cloth.Num_Verts = Num_Rows * Num_Cols
Cloth.Vert_Data = _MEMNEW(VertSize * Cloth.Num_Verts)
FOR r = 0 TO Cloth.Height - 1
FOR c = 0 TO Cloth.Width - 1
idx = r * Cloth.Width + c
x_pos = (c / (Cloth.Width - 1)) * Width - Width / 2
y_pos = (r / (Cloth.Height - 1)) * Height - Height / 2
z_pos = 0
TempVertex.Initial_Position.X = x_pos
TempVertex.Initial_Position.Y = y_pos
TempVertex.Initial_Position.Z = z_pos
TempVertex.Current_Position = TempVertex.Initial_Position
TempVertex.TexCoord.U = c / (Cloth.Width - 1)
TempVertex.TexCoord.V = r / (Cloth.Height - 1)
TempVertex.Fixed = 0
IF c = 0 THEN TempVertex.Fixed = 1
_MEMPUT Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + idx * VertSize, TempVertex
NEXT c
NEXT r
Cloth.Num_Tris = (Cloth.Height - 1) * (Cloth.Width - 1) * 2
Cloth.Tri_Data = _MEMNEW(TriSize * Cloth.Num_Tris * 3)
idx = 0
FOR r = 0 TO Cloth.Height - 2
FOR c = 0 TO Cloth.Width - 2
v1 = r * Cloth.Width + c
v2 = v1 + 1
v3 = (r + 1) * Cloth.Width + c
v4 = (r + 1) * Cloth.Width + c + 1
_MEMPUT Cloth.Tri_Data, Cloth.Tri_Data.OFFSET + idx * TriSize, v1
_MEMPUT Cloth.Tri_Data, Cloth.Tri_Data.OFFSET + (idx + 1) * TriSize, v4
_MEMPUT Cloth.Tri_Data, Cloth.Tri_Data.OFFSET + (idx + 2) * TriSize, v2
_MEMPUT Cloth.Tri_Data, Cloth.Tri_Data.OFFSET + (idx + 3) * TriSize, v1
_MEMPUT Cloth.Tri_Data, Cloth.Tri_Data.OFFSET + (idx + 4) * TriSize, v3
_MEMPUT Cloth.Tri_Data, Cloth.Tri_Data.OFFSET + (idx + 5) * TriSize, v4
idx = idx + 6
NEXT c
NEXT r
Cloth.Texture_ID = Texture_ID
Cloth.Visible = 1
Cloth.Needs_Normal_Update = 1
END SUB
SUB GDK_GL_Cloth_Update (Cloth AS GDK_Cloth_Model, TimeElapsed AS SINGLE)
DIM idx AS LONG, r AS LONG, c AS LONG
DIM Wave AS GDK2_Vertex_F
DIM wavePos AS SINGLE
DIM TempVertex AS GDK_Cloth_Vertex
DIM VertSize AS LONG
IF Cloth.Visible = 0 THEN EXIT SUB
VertSize = LEN(TempVertex)
FOR r = 0 TO Cloth.Height - 1
FOR c = 0 TO Cloth.Width - 1
idx = r * Cloth.Width + c
_MEMGET Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + idx * VertSize, TempVertex
IF TempVertex.Fixed = 0 THEN
wavePos = (TempVertex.Initial_Position.X * Cloth.Parameters.Wave_Direction.X + _
TempVertex.Initial_Position.Y * Cloth.Parameters.Wave_Direction.Y + _
TempVertex.Initial_Position.Z * Cloth.Parameters.Wave_Direction.Z)
Wave.X = SIN((wavePos * Cloth.Parameters.Wave_Frequency) + (TimeElapsed * Cloth.Parameters.Wave_Speed)) * Cloth.Parameters.Wave_Amplitude
Wave.Y = 0
Wave.Z = 0
TempVertex.Current_Position.X = TempVertex.Initial_Position.X
TempVertex.Current_Position.Y = TempVertex.Initial_Position.Y
TempVertex.Current_Position.Z = TempVertex.Initial_Position.Z + Wave.X
_MEMPUT Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + idx * VertSize, TempVertex
END IF
NEXT c
NEXT r
Cloth.Needs_Normal_Update = 1
END SUB
SUB GDK_GL_Cloth_Render (Cloth AS GDK_Cloth_Model)
DIM i AS LONG, idx AS LONG
DIM TempVertex AS GDK_Cloth_Vertex
DIM TempIndex AS LONG
DIM VertSize AS LONG, TriSize AS LONG
IF Cloth.Visible = 0 THEN EXIT SUB
IF Cloth.Needs_Normal_Update THEN
GDK_GL_Cloth_CalculateNormals Cloth
Cloth.Needs_Normal_Update = 0
END IF
VertSize = LEN(TempVertex)
TriSize = LEN(TempIndex)
_GLBINDTEXTURE _GL_TEXTURE_2D, Cloth.Texture_ID
_GLBEGIN _GL_TRIANGLES
FOR i = 0 TO Cloth.Num_Tris * 3 - 1
_MEMGET Cloth.Tri_Data, Cloth.Tri_Data.OFFSET + i * TriSize, idx
_MEMGET Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + idx * VertSize, TempVertex
_GLNORMAL3F TempVertex.Normal.X, TempVertex.Normal.Y, TempVertex.Normal.Z
_GLTEXCOORD2F TempVertex.TexCoord.U, TempVertex.TexCoord.V
_GLVERTEX3F TempVertex.Current_Position.X, TempVertex.Current_Position.Y, TempVertex.Current_Position.Z
NEXT i
_GLEND
END SUB
SUB GDK_GL_Cloth_CalculateNormals (Cloth AS GDK_Cloth_Model)
DIM i AS LONG, idx AS LONG
DIM v1 AS GDK2_Vertex_F, v2 AS GDK2_Vertex_F, v3 AS GDK2_Vertex_F
DIM normal AS GDK2_Vertex_F
DIM Vector1 AS GDK2_Vertex_F, Vector2 AS GDK2_Vertex_F
DIM len_sqr AS SINGLE, vecLen AS SINGLE ' Renamed from 'len'
DIM TempVertex AS GDK_Cloth_Vertex
DIM TempIndex AS LONG
DIM VertSize AS LONG, TriSize AS LONG
DIM v_idx1 AS LONG, v_idx2 AS LONG, v_idx3 AS LONG
VertSize = LEN(TempVertex)
TriSize = LEN(TempIndex)
' Reset all normals to zero
FOR i = 0 TO Cloth.Num_Verts - 1
_MEMGET Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + i * VertSize, TempVertex
TempVertex.Normal.X = 0
TempVertex.Normal.Y = 0
TempVertex.Normal.Z = 0
_MEMPUT Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + i * VertSize, TempVertex
NEXT i
' Calculate face normals and add them to vertex normals
FOR i = 0 TO Cloth.Num_Tris * 3 - 1 STEP 3
_MEMGET Cloth.Tri_Data, Cloth.Tri_Data.OFFSET + i * TriSize, v_idx1
_MEMGET Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + v_idx1 * VertSize, TempVertex
v1 = TempVertex.Current_Position
_MEMGET Cloth.Tri_Data, Cloth.Tri_Data.OFFSET + (i + 1) * TriSize, v_idx2
_MEMGET Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + v_idx2 * VertSize, TempVertex
v2 = TempVertex.Current_Position
_MEMGET Cloth.Tri_Data, Cloth.Tri_Data.OFFSET + (i + 2) * TriSize, v_idx3
_MEMGET Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + v_idx3 * VertSize, TempVertex
v3 = TempVertex.Current_Position
Vector1.X = v2.X - v1.X
Vector1.Y = v2.Y - v1.Y
Vector1.Z = v2.Z - v1.Z
Vector2.X = v3.X - v1.X
Vector2.Y = v3.Y - v1.Y
Vector2.Z = v3.Z - v1.Z
normal.X = Vector1.Y * Vector2.Z - Vector1.Z * Vector2.Y
normal.Y = Vector1.Z * Vector2.X - Vector1.X * Vector2.Z
normal.Z = Vector1.X * Vector2.Y - Vector1.Y * Vector2.X
_MEMGET Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + v_idx1 * VertSize, TempVertex
TempVertex.Normal.X = TempVertex.Normal.X + normal.X
TempVertex.Normal.Y = TempVertex.Normal.Y + normal.Y
TempVertex.Normal.Z = TempVertex.Normal.Z + normal.Z
_MEMPUT Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + v_idx1 * VertSize, TempVertex
_MEMGET Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + v_idx2 * VertSize, TempVertex
TempVertex.Normal.X = TempVertex.Normal.X + normal.X
TempVertex.Normal.Y = TempVertex.Normal.Y + normal.Y
TempVertex.Normal.Z = TempVertex.Normal.Z + normal.Z
_MEMPUT Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + v_idx2 * VertSize, TempVertex
_MEMGET Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + v_idx3 * VertSize, TempVertex
TempVertex.Normal.X = TempVertex.Normal.X + normal.X
TempVertex.Normal.Y = TempVertex.Normal.Y + normal.Y
TempVertex.Normal.Z = TempVertex.Normal.Z + normal.Z
_MEMPUT Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + v_idx3 * VertSize, TempVertex
NEXT i
' Normalize all vertex normals
FOR i = 0 TO Cloth.Num_Verts - 1
_MEMGET Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + i * VertSize, TempVertex
len_sqr = TempVertex.Normal.X * TempVertex.Normal.X + TempVertex.Normal.Y * TempVertex.Normal.Y + TempVertex.Normal.Z * TempVertex.Normal.Z
vecLen = SQR(len_sqr)
IF vecLen > 0 THEN
TempVertex.Normal.X = TempVertex.Normal.X / vecLen
TempVertex.Normal.Y = TempVertex.Normal.Y / vecLen
TempVertex.Normal.Z = TempVertex.Normal.Z / vecLen
_MEMPUT Cloth.Vert_Data, Cloth.Vert_Data.OFFSET + i * VertSize, TempVertex
END IF
NEXT i
END SUB
SUB GDK2_GL_Cloth_Free (Cloth AS GDK_Cloth_Model)
IF Cloth.Vert_Data.OFFSET > 0 THEN _MEMFREE Cloth.Vert_Data
IF Cloth.Tri_Data.OFFSET > 0 THEN _MEMFREE Cloth.Tri_Data
END SUB
Youll need to provide your own flag texture though...enjoy oh and the latest GDK is now up youll need that to...link in first post in the libs bit...im sure youll figure it out!
John

