mirror of
https://github.com/bloeys/assimp-go.git
synced 2025-12-29 08:28:20 +00:00
Working on mats&textures+better release handling+readme
This commit is contained in:
13
README.md
13
README.md
@ -1,5 +1,14 @@
|
|||||||
# assimp-go
|
# assimp-go
|
||||||
|
|
||||||
|
## Using assimp-go
|
||||||
|
|
||||||
|
The `release()` function is used to free underlying C resources and should be called after all processing that requires C code is done.
|
||||||
|
`release()` Will not affect the returned Go structs like `Scene` or `Mesh`. Returned Go data will remain valid.
|
||||||
|
|
||||||
|
`asig.X` functions call into C and therefore should not be used on released objects. Calling any `asig.X` function after `release()` is **undefined**.
|
||||||
|
|
||||||
|
While `asig` functions should NOT be called on a Scene (or its objects) after they have been released, methods on structs (e.g. `myScene.XYZ`, `myMesh.ABCD()`) are **safe** even after release.
|
||||||
|
|
||||||
## Developing assimp-go
|
## Developing assimp-go
|
||||||
|
|
||||||
We link against static assimp libraries that are built for each platform and added to the `asig/libs` package.
|
We link against static assimp libraries that are built for each platform and added to the `asig/libs` package.
|
||||||
@ -21,11 +30,11 @@ For platform specific steps:
|
|||||||
**Windows**:
|
**Windows**:
|
||||||
|
|
||||||
> Note: You must compile with the same C/C++ compiler you use with Go (e.g. if you use MinGW with Go, then compile assimp with MinGW by sepcifying the correct `-G` option)
|
> Note: You must compile with the same C/C++ compiler you use with Go (e.g. if you use MinGW with Go, then compile assimp with MinGW by sepcifying the correct `-G` option)
|
||||||
|
---
|
||||||
> Note: If you get compilation errors with things like `File too big` or `can't write 166 bytes to section` then cmake isn't detecting you are using MinGW, so add this flag `-D CMAKE_COMPILER_IS_MINGW=TRUE`
|
> Note: If you get compilation errors with things like `File too big` or `can't write 166 bytes to section` then cmake isn't detecting you are using MinGW, so add this flag `-D CMAKE_COMPILER_IS_MINGW=TRUE`
|
||||||
|
|
||||||
Now assuming you are using MinGW on windows:
|
Now assuming you are using MinGW on windows:
|
||||||
|
|
||||||
- Clone wanted release of assimp and run `cmake CMakeLists.txt -D BUILD_SHARED_LIBS=OFF -D ASSIMP_BUILD_ZLIB=ON -D ASSIMP_BUILD_ASSIMP_TOOLS=OFF -D ASSIMP_BUILD_TESTS=OFF -G "MinGW Makefiles"` in the root folder
|
- Clone wanted release of assimp and run `cmake CMakeLists.txt -D BUILD_SHARED_LIBS=OFF -D ASSIMP_BUILD_ZLIB=ON -D ASSIMP_BUILD_ASSIMP_TOOLS=OFF -D ASSIMP_BUILD_TESTS=OFF -G "MinGW Makefiles"` in the root folder
|
||||||
- Run `cmake --build . --parallel 6`
|
- Run `cmake --build . --parallel 6`
|
||||||
- Copy the generated `*.lib` file into `asig/lib`
|
- Copy the generated `*.lib` (or `*.a`) files into `asig/lib`
|
||||||
|
|||||||
76
asig/asig.go
76
asig/asig.go
@ -28,7 +28,59 @@ type Node struct {
|
|||||||
type Animation struct {
|
type Animation struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Texel struct {
|
||||||
|
R, G, B, A byte
|
||||||
|
}
|
||||||
|
|
||||||
type Texture struct {
|
type Texture struct {
|
||||||
|
/** Width of the texture, in pixels
|
||||||
|
*
|
||||||
|
* If mHeight is zero the texture is compressed in a format
|
||||||
|
* like JPEG. In this case mWidth specifies the size of the
|
||||||
|
* memory area pcData is pointing to, in bytes.
|
||||||
|
*/
|
||||||
|
Width uint
|
||||||
|
|
||||||
|
/** Height of the texture, in pixels
|
||||||
|
*
|
||||||
|
* If this value is zero, pcData points to an compressed texture
|
||||||
|
* in any format (e.g. JPEG).
|
||||||
|
*/
|
||||||
|
Height uint
|
||||||
|
|
||||||
|
/** A hint from the loader to make it easier for applications
|
||||||
|
* to determine the type of embedded textures.
|
||||||
|
*
|
||||||
|
* If mHeight != 0 this member is show how data is packed. Hint will consist of
|
||||||
|
* two parts: channel order and channel bitness (count of the bits for every
|
||||||
|
* color channel). For simple parsing by the viewer it's better to not omit
|
||||||
|
* absent color channel and just use 0 for bitness. For example:
|
||||||
|
* 1. Image contain RGBA and 8 bit per channel, achFormatHint == "rgba8888";
|
||||||
|
* 2. Image contain ARGB and 8 bit per channel, achFormatHint == "argb8888";
|
||||||
|
* 3. Image contain RGB and 5 bit for R and B channels and 6 bit for G channel, achFormatHint == "rgba5650";
|
||||||
|
* 4. One color image with B channel and 1 bit for it, achFormatHint == "rgba0010";
|
||||||
|
* If mHeight == 0 then achFormatHint is set set to '\\0\\0\\0\\0' if the loader has no additional
|
||||||
|
* information about the texture file format used OR the
|
||||||
|
* file extension of the format without a trailing dot. If there
|
||||||
|
* are multiple file extensions for a format, the shortest
|
||||||
|
* extension is chosen (JPEG maps to 'jpg', not to 'jpeg').
|
||||||
|
* E.g. 'dds\\0', 'pcx\\0', 'jpg\\0'. All characters are lower-case.
|
||||||
|
* The fourth character will always be '\\0'.
|
||||||
|
*/
|
||||||
|
FormatHint string
|
||||||
|
|
||||||
|
/** Data of the texture.
|
||||||
|
*
|
||||||
|
* Points to an array of mWidth * mHeight aiTexel's.
|
||||||
|
* The format of the texture data is always ARGB8888 to
|
||||||
|
* make the implementation for user of the library as easy
|
||||||
|
* as possible. If mHeight = 0 this is a pointer to a memory
|
||||||
|
* buffer of size mWidth containing the compressed texture
|
||||||
|
* data. Good luck, have fun!
|
||||||
|
*/
|
||||||
|
Texels []Texel
|
||||||
|
|
||||||
|
Filename string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Light struct {
|
type Light struct {
|
||||||
@ -41,6 +93,7 @@ type Metadata struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Scene struct {
|
type Scene struct {
|
||||||
|
cScene *C.struct_aiScene
|
||||||
Flags SceneFlag
|
Flags SceneFlag
|
||||||
|
|
||||||
RootNode *Node
|
RootNode *Node
|
||||||
@ -52,27 +105,39 @@ type Scene struct {
|
|||||||
Cameras []*Camera
|
Cameras []*Camera
|
||||||
}
|
}
|
||||||
|
|
||||||
func ImportFile(file string, postProcessFlags PostProcess) (*Scene, error) {
|
func (s *Scene) releaseCResources() {
|
||||||
|
C.aiReleaseImport(s.cScene)
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Assimp API
|
||||||
|
//
|
||||||
|
|
||||||
|
func ImportFile(file string, postProcessFlags PostProcess) (s *Scene, release func(), err error) {
|
||||||
|
|
||||||
cstr := C.CString(file)
|
cstr := C.CString(file)
|
||||||
defer C.free(unsafe.Pointer(cstr))
|
defer C.free(unsafe.Pointer(cstr))
|
||||||
|
|
||||||
cs := C.aiImportFile(cstr, C.uint(postProcessFlags))
|
cs := C.aiImportFile(cstr, C.uint(postProcessFlags))
|
||||||
if cs == nil {
|
if cs == nil {
|
||||||
return nil, getAiErr()
|
return nil, func() {}, getAiErr()
|
||||||
}
|
}
|
||||||
defer C.aiReleaseImport(cs)
|
|
||||||
|
|
||||||
return parseScene(cs), nil
|
s = parseScene(cs)
|
||||||
|
return s, func() { s.releaseCResources() }, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAiErr() error {
|
func getAiErr() error {
|
||||||
return errors.New("asig error: " + C.GoString(C.aiGetErrorString()))
|
return errors.New("asig error: " + C.GoString(C.aiGetErrorString()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Parsers
|
||||||
|
//
|
||||||
|
|
||||||
func parseScene(cs *C.struct_aiScene) *Scene {
|
func parseScene(cs *C.struct_aiScene) *Scene {
|
||||||
|
|
||||||
s := &Scene{}
|
s := &Scene{cScene: cs}
|
||||||
s.Flags = SceneFlag(cs.mFlags)
|
s.Flags = SceneFlag(cs.mFlags)
|
||||||
s.Meshes = parseMeshes(cs.mMeshes, uint(cs.mNumMeshes))
|
s.Meshes = parseMeshes(cs.mMeshes, uint(cs.mNumMeshes))
|
||||||
s.Materials = parseMaterials(cs.mMaterials, uint(cs.mNumMaterials))
|
s.Materials = parseMaterials(cs.mMaterials, uint(cs.mNumMaterials))
|
||||||
@ -350,6 +415,7 @@ func parseMaterials(cMatsIn **C.struct_aiMaterial, count uint) []*Material {
|
|||||||
for i := 0; i < int(count); i++ {
|
for i := 0; i < int(count); i++ {
|
||||||
|
|
||||||
mats[i] = &Material{
|
mats[i] = &Material{
|
||||||
|
cMat: cMats[i],
|
||||||
Properties: parseMatProperties(cMats[i].mProperties, uint(cMats[i].mNumProperties)),
|
Properties: parseMatProperties(cMats[i].mProperties, uint(cMats[i].mNumProperties)),
|
||||||
AllocatedStorage: uint(cMats[i].mNumAllocated),
|
AllocatedStorage: uint(cMats[i].mNumAllocated),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,32 @@
|
|||||||
package asig
|
package asig
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo CFLAGS: -I .
|
||||||
|
#cgo LDFLAGS: -L ./libs -l assimp_windows_amd64 -l IrrXML_windows_amd64 -l zlib_windows_amd64
|
||||||
|
|
||||||
|
#include <stdlib.h> //Needed for C.free
|
||||||
|
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
|
//Functions
|
||||||
|
unsigned int aiGetMaterialTextureCount(const struct aiMaterial* pMat, enum aiTextureType type);
|
||||||
|
|
||||||
|
enum aiReturn aiGetMaterialTexture(
|
||||||
|
const struct aiMaterial* mat,
|
||||||
|
enum aiTextureType type,
|
||||||
|
unsigned int index,
|
||||||
|
struct aiString* path,
|
||||||
|
enum aiTextureMapping* mapping,
|
||||||
|
unsigned int* uvindex,
|
||||||
|
ai_real* blend,
|
||||||
|
enum aiTextureOp* op,
|
||||||
|
enum aiTextureMapMode* mapmode,
|
||||||
|
unsigned int* flags);
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
|
||||||
type Material struct {
|
type Material struct {
|
||||||
|
cMat *C.struct_aiMaterial
|
||||||
|
|
||||||
/** List of all material properties loaded. */
|
/** List of all material properties loaded. */
|
||||||
Properties []*MaterialProperty
|
Properties []*MaterialProperty
|
||||||
@ -38,3 +64,7 @@ type MaterialProperty struct {
|
|||||||
*/
|
*/
|
||||||
Data []byte
|
Data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetMaterialTextureCount(m *Material, texType TextureType) int {
|
||||||
|
return int(C.aiGetMaterialTextureCount(m.cMat, uint32(texType)))
|
||||||
|
}
|
||||||
|
|||||||
6
main.go
6
main.go
@ -8,7 +8,9 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
scene, err := asig.ImportFile("tex-cube.fbx", asig.PostProcessTriangulate)
|
scene, release, err := asig.ImportFile("tex-cube.fbx", asig.PostProcessTriangulate)
|
||||||
|
defer release()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
@ -28,6 +30,8 @@ func main() {
|
|||||||
|
|
||||||
p := scene.Materials[i].Properties[j]
|
p := scene.Materials[i].Properties[j]
|
||||||
fmt.Printf("Data Type: %v; Len Bytes: %v; Texture Type: %v\n", p.TypeInfo.String(), len(p.Data), p.Semantic.String())
|
fmt.Printf("Data Type: %v; Len Bytes: %v; Texture Type: %v\n", p.TypeInfo.String(), len(p.Data), p.Semantic.String())
|
||||||
|
|
||||||
|
fmt.Println("Texture count:", asig.GetMaterialTextureCount(scene.Materials[i], asig.TextureTypeDiffuse))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user