mirror of
https://github.com/bloeys/nmage.git
synced 2025-12-29 13:28:20 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1b858bd4ac | |||
| d550767cb6 | |||
| 271b1c0cea | |||
| 0da031aa57 | |||
| 62194c4cad | |||
| bd79f6e274 | |||
| ac0ca8ee39 | |||
| 35ff496a9a | |||
| 52b77e017e | |||
| b85056dd31 |
@ -1,4 +1,4 @@
|
|||||||
package asserts
|
package assert
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/bloeys/nmage/consts"
|
"github.com/bloeys/nmage/consts"
|
||||||
@ -3,7 +3,7 @@ package buffers
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/bloeys/nmage/asserts"
|
"github.com/bloeys/nmage/assert"
|
||||||
"github.com/go-gl/gl/v4.1-core/gl"
|
"github.com/go-gl/gl/v4.1-core/gl"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -28,6 +28,6 @@ func (b BufUsage) ToGL() uint32 {
|
|||||||
return gl.STREAM_DRAW
|
return gl.STREAM_DRAW
|
||||||
}
|
}
|
||||||
|
|
||||||
asserts.T(false, fmt.Sprintf("Unexpected BufUsage value '%v'", b))
|
assert.T(false, fmt.Sprintf("Unexpected BufUsage value '%v'", b))
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ package buffers
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/bloeys/nmage/asserts"
|
"github.com/bloeys/nmage/assert"
|
||||||
"github.com/go-gl/gl/v4.1-core/gl"
|
"github.com/go-gl/gl/v4.1-core/gl"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ func (dt ElementType) GLType() uint32 {
|
|||||||
return gl.FLOAT
|
return gl.FLOAT
|
||||||
|
|
||||||
default:
|
default:
|
||||||
asserts.T(false, fmt.Sprintf("Unknown data type passed. DataType '%v'", dt))
|
assert.T(false, fmt.Sprintf("Unknown data type passed. DataType '%v'", dt))
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,7 +68,7 @@ func (dt ElementType) CompSize() int32 {
|
|||||||
return 4
|
return 4
|
||||||
|
|
||||||
default:
|
default:
|
||||||
asserts.T(false, fmt.Sprintf("Unknown data type passed. DataType '%v'", dt))
|
assert.T(false, fmt.Sprintf("Unknown data type passed. DataType '%v'", dt))
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ func (dt ElementType) CompCount() int32 {
|
|||||||
return 4
|
return 4
|
||||||
|
|
||||||
default:
|
default:
|
||||||
asserts.T(false, fmt.Sprintf("Unknown data type passed. DataType '%v'", dt))
|
assert.T(false, fmt.Sprintf("Unknown data type passed. DataType '%v'", dt))
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,7 +116,7 @@ func (dt ElementType) Size() int32 {
|
|||||||
return 4 * 4
|
return 4 * 4
|
||||||
|
|
||||||
default:
|
default:
|
||||||
asserts.T(false, fmt.Sprintf("Unknown data type passed. DataType '%v'", dt))
|
assert.T(false, fmt.Sprintf("Unknown data type passed. DataType '%v'", dt))
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
100
camera/camera.go
Executable file
100
camera/camera.go
Executable file
@ -0,0 +1,100 @@
|
|||||||
|
package camera
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/bloeys/gglm/gglm"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Type int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
Type_Unknown Type = iota
|
||||||
|
Type_Perspective
|
||||||
|
Type_Orthographic
|
||||||
|
)
|
||||||
|
|
||||||
|
type Camera struct {
|
||||||
|
Type Type
|
||||||
|
|
||||||
|
Pos gglm.Vec3
|
||||||
|
Forward gglm.Vec3
|
||||||
|
WorldUp gglm.Vec3
|
||||||
|
|
||||||
|
NearClip float32
|
||||||
|
FarClip float32
|
||||||
|
|
||||||
|
// Perspective data
|
||||||
|
Fov float32
|
||||||
|
AspectRatio float32
|
||||||
|
|
||||||
|
// Ortho data
|
||||||
|
Left, Right, Top, Bottom float32
|
||||||
|
|
||||||
|
// Matrices
|
||||||
|
ViewMat gglm.Mat4
|
||||||
|
ProjMat gglm.Mat4
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update recalculates view matrix and projection matrix.
|
||||||
|
// Should be called whenever a camera parameter changes
|
||||||
|
func (c *Camera) Update() {
|
||||||
|
|
||||||
|
c.ViewMat = gglm.LookAtRH(&c.Pos, c.Pos.Clone().Add(&c.Forward), &c.WorldUp).Mat4
|
||||||
|
|
||||||
|
if c.Type == Type_Perspective {
|
||||||
|
c.ProjMat = *gglm.Perspective(c.Fov, c.AspectRatio, c.NearClip, c.FarClip)
|
||||||
|
} else {
|
||||||
|
c.ProjMat = gglm.Ortho(c.Left, c.Right, c.Top, c.Bottom, c.NearClip, c.FarClip).Mat4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateRotation calculates a new forward vector and then calls camera.Update()
|
||||||
|
func (c *Camera) UpdateRotation(pitch, yaw float32) {
|
||||||
|
|
||||||
|
dir := gglm.NewVec3(
|
||||||
|
gglm.Cos32(yaw)*gglm.Cos32(pitch),
|
||||||
|
gglm.Sin32(pitch),
|
||||||
|
gglm.Sin32(yaw)*gglm.Cos32(pitch),
|
||||||
|
)
|
||||||
|
c.Forward = *dir.Normalize()
|
||||||
|
c.Update()
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPerspective(pos, forward, worldUp *gglm.Vec3, nearClip, farClip, fovRadians, aspectRatio float32) *Camera {
|
||||||
|
|
||||||
|
cam := &Camera{
|
||||||
|
Type: Type_Perspective,
|
||||||
|
Pos: *pos,
|
||||||
|
Forward: *forward,
|
||||||
|
WorldUp: *worldUp,
|
||||||
|
|
||||||
|
NearClip: nearClip,
|
||||||
|
FarClip: farClip,
|
||||||
|
|
||||||
|
Fov: fovRadians,
|
||||||
|
AspectRatio: aspectRatio,
|
||||||
|
}
|
||||||
|
cam.Update()
|
||||||
|
|
||||||
|
return cam
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewOrthographic(pos, forward, worldUp *gglm.Vec3, nearClip, farClip, left, right, top, bottom float32) *Camera {
|
||||||
|
|
||||||
|
cam := &Camera{
|
||||||
|
Type: Type_Orthographic,
|
||||||
|
Pos: *pos,
|
||||||
|
Forward: *forward,
|
||||||
|
WorldUp: *worldUp,
|
||||||
|
|
||||||
|
NearClip: nearClip,
|
||||||
|
FarClip: farClip,
|
||||||
|
|
||||||
|
Left: left,
|
||||||
|
Right: right,
|
||||||
|
Top: top,
|
||||||
|
Bottom: bottom,
|
||||||
|
}
|
||||||
|
cam.Update()
|
||||||
|
|
||||||
|
return cam
|
||||||
|
}
|
||||||
@ -3,7 +3,7 @@ package engine
|
|||||||
import (
|
import (
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/bloeys/nmage/asserts"
|
"github.com/bloeys/nmage/assert"
|
||||||
"github.com/bloeys/nmage/input"
|
"github.com/bloeys/nmage/input"
|
||||||
"github.com/bloeys/nmage/renderer"
|
"github.com/bloeys/nmage/renderer"
|
||||||
"github.com/bloeys/nmage/timing"
|
"github.com/bloeys/nmage/timing"
|
||||||
@ -146,7 +146,7 @@ func CreateOpenGLWindowCentered(title string, width, height int32, flags WindowF
|
|||||||
|
|
||||||
func createWindow(title string, x, y, width, height int32, flags WindowFlags, rend renderer.Render) (*Window, error) {
|
func createWindow(title string, x, y, width, height int32, flags WindowFlags, rend renderer.Render) (*Window, error) {
|
||||||
|
|
||||||
asserts.T(isInited, "engine.Init was not called!")
|
assert.T(isInited, "engine.Init was not called!")
|
||||||
if x == -1 && y == -1 {
|
if x == -1 && y == -1 {
|
||||||
x = sdl.WINDOWPOS_CENTERED
|
x = sdl.WINDOWPOS_CENTERED
|
||||||
y = sdl.WINDOWPOS_CENTERED
|
y = sdl.WINDOWPOS_CENTERED
|
||||||
@ -194,7 +194,7 @@ func initOpenGL() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SetVSync(enabled bool) {
|
func SetVSync(enabled bool) {
|
||||||
asserts.T(isInited, "engine.Init was not called!")
|
assert.T(isInited, "engine.Init was not called!")
|
||||||
|
|
||||||
if enabled {
|
if enabled {
|
||||||
sdl.GLSetSwapInterval(1)
|
sdl.GLSetSwapInterval(1)
|
||||||
|
|||||||
77
entity/entity.go
Executable file
77
entity/entity.go
Executable file
@ -0,0 +1,77 @@
|
|||||||
|
package entity
|
||||||
|
|
||||||
|
type EntityFlag byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
EntityFlag_Unknown EntityFlag = 0
|
||||||
|
EntityFlag_Dead EntityFlag = 1 << (iota - 1)
|
||||||
|
EntityFlag_Alive
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
GenerationShiftBits = 64 - 8
|
||||||
|
FlagsShiftBits = 64 - 16
|
||||||
|
IndexBitMask = 0x00_00_FFFF_FFFF_FFFF
|
||||||
|
)
|
||||||
|
|
||||||
|
type Entity struct {
|
||||||
|
|
||||||
|
// Byte 1: Generation; Byte 2: Flags; Bytes 3-8: Index
|
||||||
|
ID uint64
|
||||||
|
Comps []Comp
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetGeneration(id uint64) byte {
|
||||||
|
return byte(id >> GenerationShiftBits)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetFlags(id uint64) byte {
|
||||||
|
return byte(id >> FlagsShiftBits)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetIndex(id uint64) uint64 {
|
||||||
|
return id & IndexBitMask
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Entity) HasFlag(ef EntityFlag) bool {
|
||||||
|
return GetFlags(e.ID)&byte(ef) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEntityId(generation, flags byte, index uint64) uint64 {
|
||||||
|
return index | (uint64(generation) << GenerationShiftBits) | (uint64(flags) << FlagsShiftBits)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Comp interface {
|
||||||
|
Name() string
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddComp(e *Entity, c Comp) {
|
||||||
|
e.Comps = append(e.Comps, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetComp[T Comp](e *Entity) (out T) {
|
||||||
|
|
||||||
|
for i := 0; i < len(e.Comps); i++ {
|
||||||
|
|
||||||
|
comp, ok := e.Comps[i].(T)
|
||||||
|
if ok {
|
||||||
|
return comp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetAllCompOfType[T Comp](e *Entity) (out []T) {
|
||||||
|
|
||||||
|
out = []T{}
|
||||||
|
for i := 0; i < len(e.Comps); i++ {
|
||||||
|
|
||||||
|
comp, ok := e.Comps[i].(T)
|
||||||
|
if ok {
|
||||||
|
out = append(out, comp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
94
entity/registry.go
Executable file
94
entity/registry.go
Executable file
@ -0,0 +1,94 @@
|
|||||||
|
package entity
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/bloeys/nmage/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
type freeListitem struct {
|
||||||
|
EntityIndex uint64
|
||||||
|
nextFree *freeListitem
|
||||||
|
}
|
||||||
|
|
||||||
|
type Registry struct {
|
||||||
|
EntityCount uint64
|
||||||
|
Entities []Entity
|
||||||
|
FreeList *freeListitem
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Registry) NewEntity() *Entity {
|
||||||
|
|
||||||
|
assert.T(r.EntityCount < uint64(len(r.Entities)), "Can not add more entities to registry because it is full")
|
||||||
|
|
||||||
|
entityToUseIndex := uint64(0)
|
||||||
|
var entityToUse *Entity = nil
|
||||||
|
|
||||||
|
if r.FreeList != nil {
|
||||||
|
|
||||||
|
entityToUseIndex = r.FreeList.EntityIndex
|
||||||
|
entityToUse = &r.Entities[entityToUseIndex]
|
||||||
|
r.FreeList = r.FreeList.nextFree
|
||||||
|
} else {
|
||||||
|
|
||||||
|
for i := 0; i < len(r.Entities); i++ {
|
||||||
|
|
||||||
|
e := &r.Entities[i]
|
||||||
|
if GetFlags(e.ID) != byte(EntityFlag_Unknown) && !e.HasFlag(EntityFlag_Dead) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
entityToUse = e
|
||||||
|
entityToUseIndex = uint64(i)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if entityToUse == nil {
|
||||||
|
panic("failed to create new entity because we did not find a free spot in the registry. Why did the assert not go off?")
|
||||||
|
}
|
||||||
|
|
||||||
|
r.EntityCount++
|
||||||
|
entityToUse.ID = NewEntityId(GetGeneration(entityToUse.ID)+1, byte(EntityFlag_Alive), entityToUseIndex)
|
||||||
|
assert.T(entityToUse.ID != 0, "Entity ID must not be zero")
|
||||||
|
return entityToUse
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Registry) GetEntity(id uint64) *Entity {
|
||||||
|
|
||||||
|
index := GetIndex(id)
|
||||||
|
gen := GetGeneration(id)
|
||||||
|
|
||||||
|
e := &r.Entities[index]
|
||||||
|
eGen := GetGeneration(e.ID)
|
||||||
|
|
||||||
|
if gen != eGen {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Registry) FreeEntity(id uint64) {
|
||||||
|
|
||||||
|
e := r.GetEntity(id)
|
||||||
|
if e == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.EntityCount--
|
||||||
|
eIndex := GetIndex(e.ID)
|
||||||
|
|
||||||
|
e.Comps = []Comp{}
|
||||||
|
e.ID = NewEntityId(GetGeneration(e.ID), byte(EntityFlag_Dead), eIndex)
|
||||||
|
|
||||||
|
r.FreeList = &freeListitem{
|
||||||
|
EntityIndex: eIndex,
|
||||||
|
nextFree: r.FreeList,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRegistry(size uint32) *Registry {
|
||||||
|
assert.T(size > 0, "Registry size must be more than zero")
|
||||||
|
return &Registry{
|
||||||
|
Entities: make([]Entity, size),
|
||||||
|
}
|
||||||
|
}
|
||||||
12
go.mod
12
go.mod
@ -1,13 +1,13 @@
|
|||||||
module github.com/bloeys/nmage
|
module github.com/bloeys/nmage
|
||||||
|
|
||||||
go 1.17
|
go 1.18
|
||||||
|
|
||||||
require github.com/veandco/go-sdl2 v0.4.10
|
require github.com/veandco/go-sdl2 v0.4.25
|
||||||
|
|
||||||
require github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784
|
require github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/bloeys/assimp-go v0.4.2
|
github.com/bloeys/assimp-go v0.4.4
|
||||||
github.com/bloeys/gglm v0.41.10
|
github.com/bloeys/gglm v0.42.0
|
||||||
github.com/inkyblackness/imgui-go/v4 v4.3.0
|
github.com/inkyblackness/imgui-go/v4 v4.6.0
|
||||||
)
|
)
|
||||||
|
|||||||
22
go.sum
22
go.sum
@ -1,19 +1,17 @@
|
|||||||
github.com/bloeys/assimp-go v0.4.2 h1:ArVK74BCFcTO/rCGj2NgZG9xtbjnJdEn5npIeJx1Z04=
|
github.com/bloeys/assimp-go v0.4.4 h1:Yn5e/RpE0Oes0YMBy8O7KkwAO4R/RpgrZPJCt08dVIU=
|
||||||
github.com/bloeys/assimp-go v0.4.2/go.mod h1:my3yRxT7CfOztmvi+0svmwbaqw0KFrxaHxncoyaEIP0=
|
github.com/bloeys/assimp-go v0.4.4/go.mod h1:my3yRxT7CfOztmvi+0svmwbaqw0KFrxaHxncoyaEIP0=
|
||||||
github.com/bloeys/gglm v0.3.1 h1:Sy9upW7SBsBfDXrSmEhid3aQ+7J7itej+upwcxOnPMQ=
|
github.com/bloeys/gglm v0.42.0 h1:UAUFGTaZv3dpZ0YSIQVum3bdeCZgNmx965VLnD2v11k=
|
||||||
github.com/bloeys/gglm v0.3.1/go.mod h1:qwJQ0WzV191wAMwlGicbfbChbKoSedMk7gFFX6GnyOk=
|
github.com/bloeys/gglm v0.42.0/go.mod h1:qwJQ0WzV191wAMwlGicbfbChbKoSedMk7gFFX6GnyOk=
|
||||||
github.com/bloeys/gglm v0.41.10 h1:R9FMiI+VQVXAI+vDwCB7z9xqzy5VAR1657u8TQTDNKA=
|
|
||||||
github.com/bloeys/gglm v0.41.10/go.mod h1:qwJQ0WzV191wAMwlGicbfbChbKoSedMk7gFFX6GnyOk=
|
|
||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784 h1:1Zi56D0LNfvkzM+BdoxKryvUEdyWO7LP8oRT+oSYJW0=
|
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 h1:zDw5v7qm4yH7N8C8uWd+8Ii9rROdgWxQuGoJ9WDXxfk=
|
||||||
github.com/go-gl/gl v0.0.0-20211025173605-bda47ffaa784/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
|
github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
|
||||||
github.com/inkyblackness/imgui-go/v4 v4.3.0 h1:iyAzqWXq/dG5+6ckDPhGivtrIo6AywGQMvENKzun04s=
|
github.com/inkyblackness/imgui-go/v4 v4.6.0 h1:ShcnXEYl80+xREGBY9OpGWePA6FfJChY9Varsm+3jjE=
|
||||||
github.com/inkyblackness/imgui-go/v4 v4.3.0/go.mod h1:g8SAGtOYUP7rYaOB2AsVKCEHmPMDmJKgt4z6d+flhb0=
|
github.com/inkyblackness/imgui-go/v4 v4.6.0/go.mod h1:g8SAGtOYUP7rYaOB2AsVKCEHmPMDmJKgt4z6d+flhb0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/veandco/go-sdl2 v0.4.10 h1:8QoD2bhWl7SbQDflIAUYWfl9Vq+mT8/boJFAUzAScgY=
|
github.com/veandco/go-sdl2 v0.4.25 h1:J5ac3KKOccp/0xGJA1PaNYKPUcZm19IxhDGs8lJofPI=
|
||||||
github.com/veandco/go-sdl2 v0.4.10/go.mod h1:OROqMhHD43nT4/i9crJukyVecjPNYYuCofep6SNiAjY=
|
github.com/veandco/go-sdl2 v0.4.25/go.mod h1:OROqMhHD43nT4/i9crJukyVecjPNYYuCofep6SNiAjY=
|
||||||
|
|||||||
20
level/level.go
Executable file
20
level/level.go
Executable file
@ -0,0 +1,20 @@
|
|||||||
|
package level
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/bloeys/nmage/assert"
|
||||||
|
"github.com/bloeys/nmage/entity"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Level struct {
|
||||||
|
*entity.Registry
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLevel(name string, maxEntities uint32) *Level {
|
||||||
|
|
||||||
|
assert.T(name != "", "Level name can not be empty")
|
||||||
|
return &Level{
|
||||||
|
Name: name,
|
||||||
|
Registry: entity.NewRegistry(maxEntities),
|
||||||
|
}
|
||||||
|
}
|
||||||
279
main.go
279
main.go
@ -6,8 +6,11 @@ import (
|
|||||||
"github.com/bloeys/assimp-go/asig"
|
"github.com/bloeys/assimp-go/asig"
|
||||||
"github.com/bloeys/gglm/gglm"
|
"github.com/bloeys/gglm/gglm"
|
||||||
"github.com/bloeys/nmage/assets"
|
"github.com/bloeys/nmage/assets"
|
||||||
|
"github.com/bloeys/nmage/camera"
|
||||||
"github.com/bloeys/nmage/engine"
|
"github.com/bloeys/nmage/engine"
|
||||||
|
"github.com/bloeys/nmage/entity"
|
||||||
"github.com/bloeys/nmage/input"
|
"github.com/bloeys/nmage/input"
|
||||||
|
"github.com/bloeys/nmage/level"
|
||||||
"github.com/bloeys/nmage/logging"
|
"github.com/bloeys/nmage/logging"
|
||||||
"github.com/bloeys/nmage/materials"
|
"github.com/bloeys/nmage/materials"
|
||||||
"github.com/bloeys/nmage/meshes"
|
"github.com/bloeys/nmage/meshes"
|
||||||
@ -18,9 +21,10 @@ import (
|
|||||||
"github.com/veandco/go-sdl2/sdl"
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
)
|
)
|
||||||
|
|
||||||
//TODO: Tasks:
|
// @Todo:
|
||||||
// Camera class
|
// Complete entity registry (e.g. HasEntity, GetEntity, Generational Indices etc...)
|
||||||
// Entities and components
|
// Helper functions to update active entities
|
||||||
|
|
||||||
// Integrate physx
|
// Integrate physx
|
||||||
// Create VAO struct independent from VBO to support multi-VBO use cases (e.g. instancing)
|
// Create VAO struct independent from VBO to support multi-VBO use cases (e.g. instancing)
|
||||||
// Renderer batching
|
// Renderer batching
|
||||||
@ -31,18 +35,24 @@ import (
|
|||||||
// Frustum culling
|
// Frustum culling
|
||||||
// Material system editor with fields automatically extracted from the shader
|
// Material system editor with fields automatically extracted from the shader
|
||||||
|
|
||||||
|
const (
|
||||||
|
camSpeed = 15
|
||||||
|
mouseSensitivity = 0.5
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
window *engine.Window
|
window *engine.Window
|
||||||
|
|
||||||
|
pitch float32 = 0
|
||||||
|
yaw float32 = -90
|
||||||
|
cam *camera.Camera
|
||||||
|
|
||||||
simpleMat *materials.Material
|
simpleMat *materials.Material
|
||||||
cubeMesh *meshes.Mesh
|
cubeMesh *meshes.Mesh
|
||||||
|
|
||||||
modelMat = gglm.NewTrMatId()
|
cubeModelMat = gglm.NewTrMatId()
|
||||||
projMat = &gglm.Mat4{}
|
|
||||||
camPos = gglm.NewVec3(0, 0, -10)
|
|
||||||
camForward = gglm.NewVec3(0, 0, 1)
|
|
||||||
|
|
||||||
lightPos1 = gglm.NewVec3(2, 2, 0)
|
lightPos1 = gglm.NewVec3(-2, 0, 2)
|
||||||
lightColor1 = gglm.NewVec3(1, 1, 1)
|
lightColor1 = gglm.NewVec3(1, 1, 1)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -51,6 +61,91 @@ type OurGame struct {
|
|||||||
ImGUIInfo nmageimgui.ImguiInfo
|
ImGUIInfo nmageimgui.ImguiInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TransformComp struct {
|
||||||
|
Pos *gglm.Vec3
|
||||||
|
Rot *gglm.Quat
|
||||||
|
Scale *gglm.Vec3
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t TransformComp) Name() string {
|
||||||
|
return "Transform Component"
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test() {
|
||||||
|
|
||||||
|
lvl := level.NewLevel("test level", 1000)
|
||||||
|
e1 := lvl.Registry.NewEntity()
|
||||||
|
|
||||||
|
trComp := entity.GetComp[*TransformComp](e1)
|
||||||
|
fmt.Println("Got comp 1:", trComp)
|
||||||
|
|
||||||
|
e1.Comps = append(e1.Comps, &TransformComp{
|
||||||
|
Pos: gglm.NewVec3(0, 0, 0),
|
||||||
|
Rot: gglm.NewQuatEulerXYZ(0, 0, 0),
|
||||||
|
Scale: gglm.NewVec3(0, 0, 0),
|
||||||
|
}, &TransformComp{
|
||||||
|
Pos: gglm.NewVec3(0, 0, 0),
|
||||||
|
Rot: gglm.NewQuatEulerXYZ(0, 0, 0),
|
||||||
|
Scale: gglm.NewVec3(1, 1, 1),
|
||||||
|
})
|
||||||
|
|
||||||
|
trComp = entity.GetComp[*TransformComp](e1)
|
||||||
|
fmt.Println("Got comp 2:", trComp)
|
||||||
|
|
||||||
|
trComps := entity.GetAllCompOfType[*TransformComp](e1)
|
||||||
|
fmt.Printf("Got comp 3: %+v, %+v\n", trComps[0], trComps[1])
|
||||||
|
|
||||||
|
fmt.Printf("Entity: %+v\n", e1)
|
||||||
|
fmt.Printf("Entity: %+v\n", lvl.Registry.NewEntity())
|
||||||
|
fmt.Printf("Entity: %+v\n", lvl.Registry.NewEntity())
|
||||||
|
fmt.Printf("Entity: %+v\n", lvl.Registry.NewEntity())
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// Test()
|
||||||
|
// return
|
||||||
|
|
||||||
|
//Init engine
|
||||||
|
err := engine.Init()
|
||||||
|
if err != nil {
|
||||||
|
logging.ErrLog.Fatalln("Failed to init nMage. Err:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create window
|
||||||
|
window, err = engine.CreateOpenGLWindowCentered("nMage", 1280, 720, engine.WindowFlags_RESIZABLE, rend3dgl.NewRend3DGL())
|
||||||
|
if err != nil {
|
||||||
|
logging.ErrLog.Fatalln("Failed to create window. Err: ", err)
|
||||||
|
}
|
||||||
|
defer window.Destroy()
|
||||||
|
|
||||||
|
engine.SetVSync(false)
|
||||||
|
|
||||||
|
game := &OurGame{
|
||||||
|
Win: window,
|
||||||
|
ImGUIInfo: nmageimgui.NewImGUI(),
|
||||||
|
}
|
||||||
|
window.EventCallbacks = append(window.EventCallbacks, game.handleWindowEvents)
|
||||||
|
|
||||||
|
engine.Run(game, window, game.ImGUIInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *OurGame) handleWindowEvents(e sdl.Event) {
|
||||||
|
|
||||||
|
switch e := e.(type) {
|
||||||
|
case *sdl.WindowEvent:
|
||||||
|
if e.Event == sdl.WINDOWEVENT_SIZE_CHANGED {
|
||||||
|
|
||||||
|
width := e.Data1
|
||||||
|
height := e.Data2
|
||||||
|
cam.AspectRatio = float32(width) / float32(height)
|
||||||
|
cam.Update()
|
||||||
|
|
||||||
|
simpleMat.SetUnifMat4("projMat", &cam.ProjMat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (g *OurGame) Init() {
|
func (g *OurGame) Init() {
|
||||||
|
|
||||||
//Create materials
|
//Create materials
|
||||||
@ -77,70 +172,126 @@ func (g *OurGame) Init() {
|
|||||||
scaleMat := gglm.NewScaleMat(gglm.NewVec3(0.25, 0.25, 0.25))
|
scaleMat := gglm.NewScaleMat(gglm.NewVec3(0.25, 0.25, 0.25))
|
||||||
rotMat := gglm.NewRotMat(gglm.NewQuatEuler(gglm.NewVec3(0, 0, 0).AsRad()))
|
rotMat := gglm.NewRotMat(gglm.NewQuatEuler(gglm.NewVec3(0, 0, 0).AsRad()))
|
||||||
|
|
||||||
modelMat.Mul(translationMat.Mul(rotMat.Mul(scaleMat)))
|
cubeModelMat.Mul(translationMat.Mul(rotMat.Mul(scaleMat)))
|
||||||
simpleMat.SetUnifMat4("modelMat", &modelMat.Mat4)
|
simpleMat.SetUnifMat4("modelMat", &cubeModelMat.Mat4)
|
||||||
|
|
||||||
|
// Camera
|
||||||
|
winWidth, winHeight := g.Win.SDLWin.GetSize()
|
||||||
|
cam = camera.NewPerspective(
|
||||||
|
gglm.NewVec3(0, 0, 10),
|
||||||
|
gglm.NewVec3(0, 0, -1),
|
||||||
|
gglm.NewVec3(0, 1, 0),
|
||||||
|
0.1, 20,
|
||||||
|
45*gglm.Deg2Rad,
|
||||||
|
float32(winWidth)/float32(winHeight),
|
||||||
|
)
|
||||||
|
simpleMat.SetUnifMat4("projMat", &cam.ProjMat)
|
||||||
|
|
||||||
//Moves objects into the cameras view
|
|
||||||
updateViewMat()
|
updateViewMat()
|
||||||
|
|
||||||
//Perspective/Depth
|
|
||||||
projMat := gglm.Perspective(45*gglm.Deg2Rad, float32(1280)/float32(720), 0.1, 500)
|
|
||||||
simpleMat.SetUnifMat4("projMat", projMat)
|
|
||||||
|
|
||||||
//Lights
|
//Lights
|
||||||
simpleMat.SetUnifVec3("lightPos1", lightPos1)
|
simpleMat.SetUnifVec3("lightPos1", lightPos1)
|
||||||
simpleMat.SetUnifVec3("lightColor1", lightColor1)
|
simpleMat.SetUnifVec3("lightColor1", lightColor1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @TODO: Add this to gglm
|
||||||
|
// func vecRotByQuat(v *gglm.Vec3, q *gglm.Quat) *gglm.Vec3 {
|
||||||
|
|
||||||
|
// // Reference: https://gamedev.stackexchange.com/questions/28395/rotating-vector3-by-a-quaternion
|
||||||
|
// qVec := gglm.NewVec3(q.X(), q.Y(), q.Z())
|
||||||
|
|
||||||
|
// rotatedVec := qVec.Clone().Scale(2 * gglm.DotVec3(v, qVec))
|
||||||
|
|
||||||
|
// t1 := q.W()*q.W() - gglm.DotVec3(qVec, qVec)
|
||||||
|
// rotatedVec.Add(v.Clone().Scale(t1))
|
||||||
|
|
||||||
|
// rotatedVec.Add(gglm.Cross(qVec, v).Scale(2 * q.W()))
|
||||||
|
// return rotatedVec
|
||||||
|
// }
|
||||||
|
|
||||||
func (g *OurGame) Update() {
|
func (g *OurGame) Update() {
|
||||||
|
|
||||||
if input.IsQuitClicked() || input.KeyClicked(sdl.K_ESCAPE) {
|
if input.IsQuitClicked() || input.KeyClicked(sdl.K_ESCAPE) {
|
||||||
engine.Quit()
|
engine.Quit()
|
||||||
}
|
}
|
||||||
|
|
||||||
winWidth, winHeight := g.Win.SDLWin.GetSize()
|
g.updateCameraLookAround()
|
||||||
projMat = gglm.Perspective(45*gglm.Deg2Rad, float32(winWidth)/float32(winHeight), 0.1, 20)
|
g.updateCameraPos()
|
||||||
simpleMat.SetUnifMat4("projMat", projMat)
|
|
||||||
|
|
||||||
//Camera movement
|
|
||||||
var camSpeed float32 = 15
|
|
||||||
if input.KeyDown(sdl.K_w) {
|
|
||||||
camPos.Data[1] += camSpeed * timing.DT()
|
|
||||||
updateViewMat()
|
|
||||||
}
|
|
||||||
if input.KeyDown(sdl.K_s) {
|
|
||||||
camPos.Data[1] -= camSpeed * timing.DT()
|
|
||||||
updateViewMat()
|
|
||||||
}
|
|
||||||
if input.KeyDown(sdl.K_d) {
|
|
||||||
camPos.Data[0] += camSpeed * timing.DT()
|
|
||||||
updateViewMat()
|
|
||||||
}
|
|
||||||
if input.KeyDown(sdl.K_a) {
|
|
||||||
camPos.Data[0] -= camSpeed * timing.DT()
|
|
||||||
updateViewMat()
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.GetMouseWheelYNorm() > 0 {
|
|
||||||
camPos.Data[2] += 1
|
|
||||||
updateViewMat()
|
|
||||||
} else if input.GetMouseWheelYNorm() < 0 {
|
|
||||||
camPos.Data[2] -= 1
|
|
||||||
updateViewMat()
|
|
||||||
}
|
|
||||||
|
|
||||||
//Rotating cubes
|
//Rotating cubes
|
||||||
if input.KeyDown(sdl.K_SPACE) {
|
if input.KeyDown(sdl.K_SPACE) {
|
||||||
modelMat.Rotate(10*timing.DT()*gglm.Deg2Rad, gglm.NewVec3(1, 1, 1).Normalize())
|
cubeModelMat.Rotate(10*timing.DT()*gglm.Deg2Rad, gglm.NewVec3(1, 1, 1).Normalize())
|
||||||
simpleMat.SetUnifMat4("modelMat", &modelMat.Mat4)
|
simpleMat.SetUnifMat4("modelMat", &cubeModelMat.Mat4)
|
||||||
}
|
}
|
||||||
|
|
||||||
imgui.DragFloat3("Cam Pos", &camPos.Data)
|
if imgui.DragFloat3("Cam Pos", &cam.Pos.Data) {
|
||||||
|
updateViewMat()
|
||||||
|
}
|
||||||
|
if imgui.DragFloat3("Cam Forward", &cam.Forward.Data) {
|
||||||
|
updateViewMat()
|
||||||
|
}
|
||||||
|
|
||||||
|
if input.KeyClicked(sdl.K_F4) {
|
||||||
|
fmt.Printf("Pos: %s; Forward: %s; |Forward|: %f\n", cam.Pos.String(), cam.Forward.String(), cam.Forward.Mag())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *OurGame) updateCameraLookAround() {
|
||||||
|
|
||||||
|
mouseX, mouseY := input.GetMouseMotion()
|
||||||
|
if mouseX == 0 && mouseY == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Yaw
|
||||||
|
yaw += float32(mouseX) * mouseSensitivity * timing.DT()
|
||||||
|
|
||||||
|
// Pitch
|
||||||
|
pitch += float32(-mouseY) * mouseSensitivity * timing.DT()
|
||||||
|
if pitch > 89.0 {
|
||||||
|
pitch = 89.0
|
||||||
|
}
|
||||||
|
|
||||||
|
if pitch < -89.0 {
|
||||||
|
pitch = -89.0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update cam forward
|
||||||
|
cam.UpdateRotation(pitch, yaw)
|
||||||
|
|
||||||
|
updateViewMat()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *OurGame) updateCameraPos() {
|
||||||
|
|
||||||
|
update := false
|
||||||
|
|
||||||
|
// Forward and backward
|
||||||
|
if input.KeyDown(sdl.K_w) {
|
||||||
|
cam.Pos.Add(cam.Forward.Clone().Scale(camSpeed * timing.DT()))
|
||||||
|
update = true
|
||||||
|
} else if input.KeyDown(sdl.K_s) {
|
||||||
|
cam.Pos.Add(cam.Forward.Clone().Scale(-camSpeed * timing.DT()))
|
||||||
|
update = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Left and right
|
||||||
|
if input.KeyDown(sdl.K_d) {
|
||||||
|
cam.Pos.Add(gglm.Cross(&cam.Forward, &cam.WorldUp).Normalize().Scale(camSpeed * timing.DT()))
|
||||||
|
update = true
|
||||||
|
} else if input.KeyDown(sdl.K_a) {
|
||||||
|
cam.Pos.Add(gglm.Cross(&cam.Forward, &cam.WorldUp).Normalize().Scale(-camSpeed * timing.DT()))
|
||||||
|
update = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if update {
|
||||||
|
updateViewMat()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *OurGame) Render() {
|
func (g *OurGame) Render() {
|
||||||
|
|
||||||
tempModelMat := modelMat.Clone()
|
tempModelMat := cubeModelMat.Clone()
|
||||||
|
|
||||||
rowSize := 100
|
rowSize := 100
|
||||||
for y := 0; y < rowSize; y++ {
|
for y := 0; y < rowSize; y++ {
|
||||||
@ -161,33 +312,7 @@ func (g *OurGame) DeInit() {
|
|||||||
g.Win.Destroy()
|
g.Win.Destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
|
||||||
|
|
||||||
//Init engine
|
|
||||||
err := engine.Init()
|
|
||||||
if err != nil {
|
|
||||||
logging.ErrLog.Fatalln("Failed to init nMage. Err:", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
//Create window
|
|
||||||
window, err = engine.CreateOpenGLWindowCentered("nMage", 1280, 720, engine.WindowFlags_RESIZABLE, rend3dgl.NewRend3DGL())
|
|
||||||
if err != nil {
|
|
||||||
logging.ErrLog.Fatalln("Failed to create window. Err: ", err)
|
|
||||||
}
|
|
||||||
defer window.Destroy()
|
|
||||||
|
|
||||||
engine.SetVSync(false)
|
|
||||||
|
|
||||||
game := &OurGame{
|
|
||||||
Win: window,
|
|
||||||
ImGUIInfo: nmageimgui.NewImGUI(),
|
|
||||||
}
|
|
||||||
|
|
||||||
engine.Run(game, window, game.ImGUIInfo)
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateViewMat() {
|
func updateViewMat() {
|
||||||
targetPos := camPos.Clone().Add(camForward)
|
cam.Update()
|
||||||
viewMat := gglm.LookAt(camPos, targetPos, gglm.NewVec3(0, 1, 0))
|
simpleMat.SetUnifMat4("viewMat", &cam.ViewMat)
|
||||||
simpleMat.SetUnifMat4("viewMat", &viewMat.Mat4)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package materials
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/bloeys/gglm/gglm"
|
"github.com/bloeys/gglm/gglm"
|
||||||
"github.com/bloeys/nmage/asserts"
|
"github.com/bloeys/nmage/assert"
|
||||||
"github.com/bloeys/nmage/logging"
|
"github.com/bloeys/nmage/logging"
|
||||||
"github.com/bloeys/nmage/shaders"
|
"github.com/bloeys/nmage/shaders"
|
||||||
"github.com/go-gl/gl/v4.1-core/gl"
|
"github.com/go-gl/gl/v4.1-core/gl"
|
||||||
@ -42,7 +42,7 @@ func (m *Material) GetAttribLoc(attribName string) int32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loc = gl.GetAttribLocation(m.ShaderProg.ID, gl.Str(attribName+"\x00"))
|
loc = gl.GetAttribLocation(m.ShaderProg.ID, gl.Str(attribName+"\x00"))
|
||||||
asserts.T(loc != -1, "Attribute '"+attribName+"' doesn't exist on material "+m.Name)
|
assert.T(loc != -1, "Attribute '"+attribName+"' doesn't exist on material "+m.Name)
|
||||||
m.AttribLocs[attribName] = loc
|
m.AttribLocs[attribName] = loc
|
||||||
return loc
|
return loc
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ func (m *Material) GetUnifLoc(uniformName string) int32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
loc = gl.GetUniformLocation(m.ShaderProg.ID, gl.Str(uniformName+"\x00"))
|
loc = gl.GetUniformLocation(m.ShaderProg.ID, gl.Str(uniformName+"\x00"))
|
||||||
asserts.T(loc != -1, "Uniform '"+uniformName+"' doesn't exist on material "+m.Name)
|
assert.T(loc != -1, "Uniform '"+uniformName+"' doesn't exist on material "+m.Name)
|
||||||
m.UnifLocs[uniformName] = loc
|
m.UnifLocs[uniformName] = loc
|
||||||
return loc
|
return loc
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import (
|
|||||||
|
|
||||||
"github.com/bloeys/assimp-go/asig"
|
"github.com/bloeys/assimp-go/asig"
|
||||||
"github.com/bloeys/gglm/gglm"
|
"github.com/bloeys/gglm/gglm"
|
||||||
"github.com/bloeys/nmage/asserts"
|
"github.com/bloeys/nmage/assert"
|
||||||
"github.com/bloeys/nmage/buffers"
|
"github.com/bloeys/nmage/buffers"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,7 +31,10 @@ func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (*Mesh,
|
|||||||
sceneMesh := scene.Meshes[0]
|
sceneMesh := scene.Meshes[0]
|
||||||
mesh.Buf = buffers.NewBuffer()
|
mesh.Buf = buffers.NewBuffer()
|
||||||
|
|
||||||
asserts.T(len(sceneMesh.TexCoords[0]) > 0, "Mesh has no UV0")
|
if len(sceneMesh.TexCoords[0]) == 0 {
|
||||||
|
sceneMesh.TexCoords[0] = make([]gglm.Vec3, len(sceneMesh.Vertices))
|
||||||
|
}
|
||||||
|
|
||||||
layoutToUse := []buffers.Element{{ElementType: buffers.DataTypeVec3}, {ElementType: buffers.DataTypeVec3}, {ElementType: buffers.DataTypeVec2}}
|
layoutToUse := []buffers.Element{{ElementType: buffers.DataTypeVec3}, {ElementType: buffers.DataTypeVec3}, {ElementType: buffers.DataTypeVec2}}
|
||||||
|
|
||||||
if len(sceneMesh.ColorSets) > 0 && len(sceneMesh.ColorSets[0]) > 0 {
|
if len(sceneMesh.ColorSets) > 0 && len(sceneMesh.ColorSets[0]) > 0 {
|
||||||
@ -73,9 +76,9 @@ type arrToInterleave struct {
|
|||||||
|
|
||||||
func (a *arrToInterleave) get(i int) []float32 {
|
func (a *arrToInterleave) get(i int) []float32 {
|
||||||
|
|
||||||
asserts.T(len(a.V2s) == 0 || len(a.V3s) == 0, "One array should be set in arrToInterleave, but both arrays are set")
|
assert.T(len(a.V2s) == 0 || len(a.V3s) == 0, "One array should be set in arrToInterleave, but both arrays are set")
|
||||||
asserts.T(len(a.V2s) == 0 || len(a.V4s) == 0, "One array should be set in arrToInterleave, but both arrays are set")
|
assert.T(len(a.V2s) == 0 || len(a.V4s) == 0, "One array should be set in arrToInterleave, but both arrays are set")
|
||||||
asserts.T(len(a.V3s) == 0 || len(a.V4s) == 0, "One array should be set in arrToInterleave, but both arrays are set")
|
assert.T(len(a.V3s) == 0 || len(a.V4s) == 0, "One array should be set in arrToInterleave, but both arrays are set")
|
||||||
|
|
||||||
if len(a.V2s) > 0 {
|
if len(a.V2s) > 0 {
|
||||||
return a.V2s[i].Data[:]
|
return a.V2s[i].Data[:]
|
||||||
@ -88,8 +91,8 @@ func (a *arrToInterleave) get(i int) []float32 {
|
|||||||
|
|
||||||
func interleave(arrs ...arrToInterleave) []float32 {
|
func interleave(arrs ...arrToInterleave) []float32 {
|
||||||
|
|
||||||
asserts.T(len(arrs) > 0, "No input sent to interleave")
|
assert.T(len(arrs) > 0, "No input sent to interleave")
|
||||||
asserts.T(len(arrs[0].V2s) > 0 || len(arrs[0].V3s) > 0 || len(arrs[0].V4s) > 0, "Interleave arrays are empty")
|
assert.T(len(arrs[0].V2s) > 0 || len(arrs[0].V3s) > 0 || len(arrs[0].V4s) > 0, "Interleave arrays are empty")
|
||||||
|
|
||||||
elementCount := 0
|
elementCount := 0
|
||||||
if len(arrs[0].V2s) > 0 {
|
if len(arrs[0].V2s) > 0 {
|
||||||
@ -104,7 +107,7 @@ func interleave(arrs ...arrToInterleave) []float32 {
|
|||||||
totalSize := 0
|
totalSize := 0
|
||||||
for i := 0; i < len(arrs); i++ {
|
for i := 0; i < len(arrs); i++ {
|
||||||
|
|
||||||
asserts.T(len(arrs[i].V2s) == elementCount || len(arrs[i].V3s) == elementCount || len(arrs[i].V4s) == elementCount, "Mesh vertex data given to interleave is not the same length")
|
assert.T(len(arrs[i].V2s) == elementCount || len(arrs[i].V3s) == elementCount || len(arrs[i].V4s) == elementCount, "Mesh vertex data given to interleave is not the same length")
|
||||||
|
|
||||||
if len(arrs[i].V2s) > 0 {
|
if len(arrs[i].V2s) > 0 {
|
||||||
totalSize += len(arrs[i].V2s) * 2
|
totalSize += len(arrs[i].V2s) * 2
|
||||||
@ -125,34 +128,9 @@ func interleave(arrs ...arrToInterleave) []float32 {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
func flattenVec3(vec3s []gglm.Vec3) []float32 {
|
|
||||||
|
|
||||||
floats := make([]float32, len(vec3s)*3)
|
|
||||||
for i := 0; i < len(vec3s); i++ {
|
|
||||||
floats[i*3+0] = vec3s[i].X()
|
|
||||||
floats[i*3+1] = vec3s[i].Y()
|
|
||||||
floats[i*3+2] = vec3s[i].Z()
|
|
||||||
}
|
|
||||||
|
|
||||||
return floats
|
|
||||||
}
|
|
||||||
|
|
||||||
func flattenVec4(vec4s []gglm.Vec4) []float32 {
|
|
||||||
|
|
||||||
floats := make([]float32, len(vec4s)*4)
|
|
||||||
for i := 0; i < len(vec4s); i++ {
|
|
||||||
floats[i*4+0] = vec4s[i].X()
|
|
||||||
floats[i*4+1] = vec4s[i].Y()
|
|
||||||
floats[i*4+2] = vec4s[i].Z()
|
|
||||||
floats[i*4+3] = vec4s[i].W()
|
|
||||||
}
|
|
||||||
|
|
||||||
return floats
|
|
||||||
}
|
|
||||||
|
|
||||||
func flattenFaces(faces []asig.Face) []uint32 {
|
func flattenFaces(faces []asig.Face) []uint32 {
|
||||||
|
|
||||||
asserts.T(len(faces[0].Indices) == 3, fmt.Sprintf("Face doesn't have 3 indices. Index count: %v\n", len(faces[0].Indices)))
|
assert.T(len(faces[0].Indices) == 3, fmt.Sprintf("Face doesn't have 3 indices. Index count: %v\n", len(faces[0].Indices)))
|
||||||
|
|
||||||
uints := make([]uint32, len(faces)*3)
|
uints := make([]uint32, len(faces)*3)
|
||||||
for i := 0; i < len(faces); i++ {
|
for i := 0; i < len(faces); i++ {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package nmageimgui
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/bloeys/gglm/gglm"
|
"github.com/bloeys/gglm/gglm"
|
||||||
"github.com/bloeys/nmage/asserts"
|
"github.com/bloeys/nmage/assert"
|
||||||
"github.com/bloeys/nmage/materials"
|
"github.com/bloeys/nmage/materials"
|
||||||
"github.com/bloeys/nmage/timing"
|
"github.com/bloeys/nmage/timing"
|
||||||
"github.com/go-gl/gl/v4.1-core/gl"
|
"github.com/go-gl/gl/v4.1-core/gl"
|
||||||
@ -23,7 +23,7 @@ type ImguiInfo struct {
|
|||||||
func (i *ImguiInfo) FrameStart(winWidth, winHeight float32) {
|
func (i *ImguiInfo) FrameStart(winWidth, winHeight float32) {
|
||||||
|
|
||||||
if err := i.ImCtx.SetCurrent(); err != nil {
|
if err := i.ImCtx.SetCurrent(); err != nil {
|
||||||
asserts.T(false, "Setting imgui ctx as current failed. Err: "+err.Error())
|
assert.T(false, "Setting imgui ctx as current failed. Err: "+err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
imIO := imgui.CurrentIO()
|
imIO := imgui.CurrentIO()
|
||||||
@ -36,7 +36,7 @@ func (i *ImguiInfo) FrameStart(winWidth, winHeight float32) {
|
|||||||
func (i *ImguiInfo) Render(winWidth, winHeight float32, fbWidth, fbHeight int32) {
|
func (i *ImguiInfo) Render(winWidth, winHeight float32, fbWidth, fbHeight int32) {
|
||||||
|
|
||||||
if err := i.ImCtx.SetCurrent(); err != nil {
|
if err := i.ImCtx.SetCurrent(); err != nil {
|
||||||
asserts.T(false, "Setting imgui ctx as current failed. Err: "+err.Error())
|
assert.T(false, "Setting imgui ctx as current failed. Err: "+err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
imgui.Render()
|
imgui.Render()
|
||||||
|
|||||||
Reference in New Issue
Block a user