Merge pull request #307 from Peternj42/Fix-for-UploadMesh

Fix for UnloadMesh per issue #303
This commit is contained in:
Milan Nikolic 2023-11-08 23:36:23 +01:00 committed by GitHub
commit b09590165d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -7,8 +7,10 @@ package rl
import "C" import "C"
import ( import (
"fmt"
"image/color" "image/color"
"runtime" "runtime"
"slices"
"unsafe" "unsafe"
) )
@ -335,8 +337,18 @@ func DrawBillboardPro(camera Camera, texture Texture2D, sourceRec Rectangle, pos
C.DrawBillboardPro(*ccamera, *ctexture, *csourceRec, *cposition, *cup, *csize, *corigin, crotation, *ctint) C.DrawBillboardPro(*ccamera, *ctexture, *csourceRec, *cposition, *cup, *csize, *corigin, crotation, *ctint)
} }
// List of VaoIDs of meshes created by calling UploadMesh()
// Used by UnloadMesh() to determine if mesh is go-managed or C-allocated
var goManagedMeshIDs []uint32 = make([]uint32, 0)
// UploadMesh - Upload vertex data into a VAO (if supported) and VBO // UploadMesh - Upload vertex data into a VAO (if supported) and VBO
func UploadMesh(mesh *Mesh, dynamic bool) { func UploadMesh(mesh *Mesh, dynamic bool) {
//check if mesh has already been uploaded to prevent duplication
if mesh.VaoID != 0 {
fmt.Printf("WARNING: VAO: [ID %d] Trying to re-load an already loaded mesh\n", mesh.VaoID)
return
}
pinner := runtime.Pinner{} pinner := runtime.Pinner{}
//Mesh pointer fields must be pinned to allow a Mesh pointer to be passed to C.UploadMesh() below //Mesh pointer fields must be pinned to allow a Mesh pointer to be passed to C.UploadMesh() below
//nil checks are required because Pin() will panic if passed nil //nil checks are required because Pin() will panic if passed nil
@ -381,6 +393,9 @@ func UploadMesh(mesh *Mesh, dynamic bool) {
cMesh := mesh.cptr() cMesh := mesh.cptr()
C.UploadMesh(cMesh, C.bool(dynamic)) C.UploadMesh(cMesh, C.bool(dynamic))
//Add new mesh VaoID to list
goManagedMeshIDs = append(goManagedMeshIDs, mesh.VaoID)
pinner.Unpin() pinner.Unpin()
} }
@ -394,14 +409,23 @@ func UpdateMeshBuffer(mesh Mesh, index int, data []byte, offset int) {
// UnloadMesh - Unload mesh from memory (RAM and/or VRAM) // UnloadMesh - Unload mesh from memory (RAM and/or VRAM)
func UnloadMesh(mesh *Mesh) { func UnloadMesh(mesh *Mesh) {
//C.UnloadMesh() only needs to read the VaoID & VboID //Check list of go-managed mesh IDs
//passing a temporary struct with all other fields nil makes it safe for the C code to call free() if slices.Contains(goManagedMeshIDs, mesh.VaoID) {
tempMesh := Mesh{ //C.UnloadMesh() only needs to read the VaoID & VboID
VaoID: mesh.VaoID, //passing a temporary struct with all other fields nil makes it safe for the C code to call free()
VboID: mesh.VboID, tempMesh := Mesh{
VaoID: mesh.VaoID,
VboID: mesh.VboID,
}
cmesh := tempMesh.cptr()
C.UnloadMesh(*cmesh)
//remove mesh VaoID from list
goManagedMeshIDs = slices.DeleteFunc(goManagedMeshIDs, func(id uint32) bool { return id == mesh.VaoID })
} else {
cmesh := mesh.cptr()
C.UnloadMesh(*cmesh)
} }
cmesh := tempMesh.cptr()
C.UnloadMesh(*cmesh)
} }
// DrawMesh - Draw a single mesh // DrawMesh - Draw a single mesh