Pārlūkot izejas kodu

Added example mesh type.

Brucey 5 gadi atpakaļ
vecāks
revīzija
0a44fdf6e8
1 mainītis faili ar 123 papildinājumiem un 0 dzēšanām
  1. 123 0
      examples/learnopengl/mesh.bmx

+ 123 - 0
examples/learnopengl/mesh.bmx

@@ -0,0 +1,123 @@
+SuperStrict
+
+Import "shader.bmx"
+
+Struct SVertex
+	Field position:SVec3F
+	Field normal:SVec3F
+	Field texCoords:SVec2F
+	Field tangent:SVec3F
+	Field bitangent:SVec3F
+End Struct
+
+Type TTexture
+	Field id:Int
+	Field textureType:String
+	Field path:String
+End Type
+
+
+Type TMesh
+	' Mesh Data
+	Field vertices:SVertex[]
+	Field indices:UInt[]
+	Field textures:TTexture[]
+	Field VAO:UInt
+	
+	Field VBO:UInt
+	Field EBO:UInt
+
+	Method New(vertices:SVertex[], indices:UInt[], textures:TTexture[])
+		Self.vertices = vertices
+		Self.indices = indices
+		Self.textures = textures
+		
+		' now that we have all the required data, set the vertex buffers and its attribute pointers.
+		setupMesh()
+	End Method
+
+	' render the mesh
+	Method Draw(shader:TShader)
+		' bind appropriate textures
+		Local diffuseNr:UInt = 1
+		Local specularNr:UInt = 1
+		Local normalNr:UInt = 1
+		Local heightNr:UInt = 1
+		
+		For Local i:Int = 0 Until textures.length
+			glActiveTexture(GL_TEXTURE0 + i) ' active proper texture unit before binding
+			' retrieve texture number (the N in diffuse_textureN)
+			Local number:String
+			Local name:String = textures[i].textureType
+			If name = "texture_diffuse" Then
+				number = diffuseNr
+				diffuseNr :+ 1
+			Else If name = "texture_specular" Then
+				number = specularNr ' transfer unsigned int to stream
+				specularNr :+ 1
+			Else If name = "texture_normal" Then
+				number = normalNr ' transfer unsigned int to stream
+				normalNr :+ 1
+			Else If name = "texture_height" Then
+				number = heightNr ' transfer unsigned int to stream
+				heightNr :+ 1
+			End If
+			
+			' now set the sampler to the correct texture unit
+			glUniform1i(glGetUniformLocation(shader.id, name + number), i)
+			' and finally bind the texture
+			glBindTexture(GL_TEXTURE_2D, textures[i].id)
+		Next
+		
+		' draw mesh
+		glBindVertexArray(VAO)
+		glDrawElements(GL_TRIANGLES, indices.length, GL_UNSIGNED_INT, 0)
+		glBindVertexArray(0)
+		
+		' always good practice to set everything back to defaults once configured
+		glActiveTexture(GL_TEXTURE0)
+	End Method
+
+Private
+	' initializes all the buffer objects/arrays
+	Method setupMesh()
+		' create buffers/arrays
+		glGenVertexArrays(1, Varptr VAO)
+		glGenBuffers(1, Varptr VBO)
+		glGenBuffers(1, Varptr EBO)
+
+		glBindVertexArray(VAO)
+		' load data into vertex buffers
+		glBindBuffer(GL_ARRAY_BUFFER, VBO)
+		
+		Local v:SVertex
+
+		' A great thing about structs is that their memory layout is sequential for all its items.
+		' The effect is that we can simply pass a pointer to the struct and it translates perfectly to a glm::vec3/2 array which
+		' again translates to 3/2 floats which translates to a byte array.
+		glBufferData(GL_ARRAY_BUFFER, vertices.length * SizeOf(v), vertices, GL_STATIC_DRAW)
+		
+		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO)
+		glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.length * SizeOf(0:UInt), indices, GL_STATIC_DRAW)
+
+		' set the vertex attribute pointers
+		' vertex Positions
+		glEnableVertexAttribArray(0)	
+		glVertexAttribPointer(0, 3, GL_FLOAT, False, SizeOf(v), Null);
+		' vertex normals
+		glEnableVertexAttribArray(1)	
+		glVertexAttribPointer(1, 3, GL_FLOAT, False, SizeOf(v), Byte Ptr(FieldOffset(SVertex, normal)))
+		' vertex texture coords
+		glEnableVertexAttribArray(2)	
+		glVertexAttribPointer(2, 2, GL_FLOAT, False, SizeOf(v), Byte Ptr(FieldOffset(SVertex, texCoords)))
+		' vertex tangent
+		glEnableVertexAttribArray(3)
+		glVertexAttribPointer(3, 3, GL_FLOAT, False, SizeOf(v), Byte Ptr(FieldOffset(SVertex, tangent)))
+		' vertex bitangent
+		glEnableVertexAttribArray(4)
+		glVertexAttribPointer(4, 3, GL_FLOAT, False, SizeOf(v), Byte Ptr(FieldOffset(SVertex, bitangent)))
+
+		glBindVertexArray(0)
+	End Method
+
+End Type