mirror of
https://github.com/bloeys/nmage.git
synced 2025-12-29 13:28:20 +00:00
Camera package+ rename asserts->assert
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
package asserts
|
||||
package assert
|
||||
|
||||
import (
|
||||
"github.com/bloeys/nmage/consts"
|
||||
@ -3,7 +3,7 @@ package buffers
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/bloeys/nmage/asserts"
|
||||
"github.com/bloeys/nmage/assert"
|
||||
"github.com/go-gl/gl/v4.1-core/gl"
|
||||
)
|
||||
|
||||
@ -28,6 +28,6 @@ func (b BufUsage) ToGL() uint32 {
|
||||
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
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ package buffers
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/bloeys/nmage/asserts"
|
||||
"github.com/bloeys/nmage/assert"
|
||||
"github.com/go-gl/gl/v4.1-core/gl"
|
||||
)
|
||||
|
||||
@ -45,7 +45,7 @@ func (dt ElementType) GLType() uint32 {
|
||||
return gl.FLOAT
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -68,7 +68,7 @@ func (dt ElementType) CompSize() int32 {
|
||||
return 4
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -92,7 +92,7 @@ func (dt ElementType) CompCount() int32 {
|
||||
return 4
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
@ -116,7 +116,7 @@ func (dt ElementType) Size() int32 {
|
||||
return 4 * 4
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
96
camera/camera.go
Executable file
96
camera/camera.go
Executable file
@ -0,0 +1,96 @@
|
||||
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
|
||||
Target 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 and projection matrices
|
||||
func (c *Camera) Update() {
|
||||
|
||||
c.ViewMat = gglm.LookAt(&c.Pos, &c.Target, &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
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Camera) LookAt(targetPos, worldUp *gglm.Vec3) {
|
||||
c.Target = *targetPos
|
||||
c.WorldUp = *worldUp
|
||||
c.Update()
|
||||
}
|
||||
|
||||
func NewPerspective(pos, targetPos, worldUp *gglm.Vec3, nearClip, farClip, fovRadians, aspectRatio float32) *Camera {
|
||||
|
||||
cam := &Camera{
|
||||
Type: Type_Perspective,
|
||||
Pos: *pos,
|
||||
// Forward: *gglm.NewVec3(0, 0, 1),
|
||||
Target: *targetPos,
|
||||
WorldUp: *worldUp,
|
||||
|
||||
NearClip: nearClip,
|
||||
FarClip: farClip,
|
||||
|
||||
Fov: fovRadians,
|
||||
AspectRatio: aspectRatio,
|
||||
}
|
||||
cam.Update()
|
||||
|
||||
return cam
|
||||
}
|
||||
|
||||
func NewOrthographic(pos, targetPos, worldUp *gglm.Vec3, nearClip, farClip, left, right, top, bottom float32) *Camera {
|
||||
|
||||
cam := &Camera{
|
||||
Type: Type_Orthographic,
|
||||
Pos: *pos,
|
||||
// Forward: *gglm.NewVec3(0, 0, 0),
|
||||
Target: *targetPos,
|
||||
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 (
|
||||
"runtime"
|
||||
|
||||
"github.com/bloeys/nmage/asserts"
|
||||
"github.com/bloeys/nmage/assert"
|
||||
"github.com/bloeys/nmage/input"
|
||||
"github.com/bloeys/nmage/renderer"
|
||||
"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) {
|
||||
|
||||
asserts.T(isInited, "engine.Init was not called!")
|
||||
assert.T(isInited, "engine.Init was not called!")
|
||||
if x == -1 && y == -1 {
|
||||
x = sdl.WINDOWPOS_CENTERED
|
||||
y = sdl.WINDOWPOS_CENTERED
|
||||
@ -194,7 +194,7 @@ func initOpenGL() error {
|
||||
}
|
||||
|
||||
func SetVSync(enabled bool) {
|
||||
asserts.T(isInited, "engine.Init was not called!")
|
||||
assert.T(isInited, "engine.Init was not called!")
|
||||
|
||||
if enabled {
|
||||
sdl.GLSetSwapInterval(1)
|
||||
|
||||
123
main.go
123
main.go
@ -6,6 +6,7 @@ import (
|
||||
"github.com/bloeys/assimp-go/asig"
|
||||
"github.com/bloeys/gglm/gglm"
|
||||
"github.com/bloeys/nmage/assets"
|
||||
"github.com/bloeys/nmage/camera"
|
||||
"github.com/bloeys/nmage/engine"
|
||||
"github.com/bloeys/nmage/input"
|
||||
"github.com/bloeys/nmage/logging"
|
||||
@ -18,8 +19,7 @@ import (
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
)
|
||||
|
||||
//TODO: Tasks:
|
||||
// Camera class
|
||||
// @Todo:
|
||||
// Entities and components
|
||||
// Integrate physx
|
||||
// Create VAO struct independent from VBO to support multi-VBO use cases (e.g. instancing)
|
||||
@ -34,13 +34,12 @@ import (
|
||||
var (
|
||||
window *engine.Window
|
||||
|
||||
cam *camera.Camera
|
||||
|
||||
simpleMat *materials.Material
|
||||
cubeMesh *meshes.Mesh
|
||||
|
||||
modelMat = gglm.NewTrMatId()
|
||||
projMat = &gglm.Mat4{}
|
||||
camPos = gglm.NewVec3(0, 0, -10)
|
||||
camForward = gglm.NewVec3(0, 0, 1)
|
||||
modelMat = gglm.NewTrMatId()
|
||||
|
||||
lightPos1 = gglm.NewVec3(2, 2, 0)
|
||||
lightColor1 = gglm.NewVec3(1, 1, 1)
|
||||
@ -51,6 +50,48 @@ type OurGame struct {
|
||||
ImGUIInfo nmageimgui.ImguiInfo
|
||||
}
|
||||
|
||||
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(),
|
||||
}
|
||||
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() {
|
||||
|
||||
//Create materials
|
||||
@ -80,16 +121,24 @@ func (g *OurGame) Init() {
|
||||
modelMat.Mul(translationMat.Mul(rotMat.Mul(scaleMat)))
|
||||
simpleMat.SetUnifMat4("modelMat", &modelMat.Mat4)
|
||||
|
||||
//Moves objects into the cameras view
|
||||
updateViewMat()
|
||||
// Camera
|
||||
winWidth, winHeight := g.Win.SDLWin.GetSize()
|
||||
cam = camera.NewPerspective(
|
||||
gglm.NewVec3(0, 0, -10),
|
||||
gglm.NewVec3(0, 0, -9),
|
||||
gglm.NewVec3(0, 1, 0),
|
||||
0.1, 20,
|
||||
45*gglm.Deg2Rad,
|
||||
float32(winWidth)/float32(winHeight),
|
||||
)
|
||||
simpleMat.SetUnifMat4("projMat", &cam.ProjMat)
|
||||
|
||||
//Perspective/Depth
|
||||
projMat := gglm.Perspective(45*gglm.Deg2Rad, float32(1280)/float32(720), 0.1, 500)
|
||||
simpleMat.SetUnifMat4("projMat", projMat)
|
||||
updateViewMat()
|
||||
|
||||
//Lights
|
||||
simpleMat.SetUnifVec3("lightPos1", lightPos1)
|
||||
simpleMat.SetUnifVec3("lightColor1", lightColor1)
|
||||
|
||||
}
|
||||
|
||||
func (g *OurGame) Update() {
|
||||
@ -98,34 +147,30 @@ func (g *OurGame) Update() {
|
||||
engine.Quit()
|
||||
}
|
||||
|
||||
winWidth, winHeight := g.Win.SDLWin.GetSize()
|
||||
projMat = gglm.Perspective(45*gglm.Deg2Rad, float32(winWidth)/float32(winHeight), 0.1, 20)
|
||||
simpleMat.SetUnifMat4("projMat", projMat)
|
||||
|
||||
//Camera movement
|
||||
var camSpeed float32 = 15
|
||||
if input.KeyDown(sdl.K_w) {
|
||||
camPos.Data[1] += camSpeed * timing.DT()
|
||||
cam.Pos.AddY(camSpeed * timing.DT())
|
||||
updateViewMat()
|
||||
}
|
||||
if input.KeyDown(sdl.K_s) {
|
||||
camPos.Data[1] -= camSpeed * timing.DT()
|
||||
cam.Pos.AddY(-camSpeed * timing.DT())
|
||||
updateViewMat()
|
||||
}
|
||||
if input.KeyDown(sdl.K_d) {
|
||||
camPos.Data[0] += camSpeed * timing.DT()
|
||||
cam.Pos.AddX(camSpeed * timing.DT())
|
||||
updateViewMat()
|
||||
}
|
||||
if input.KeyDown(sdl.K_a) {
|
||||
camPos.Data[0] -= camSpeed * timing.DT()
|
||||
cam.Pos.AddX(-camSpeed * timing.DT())
|
||||
updateViewMat()
|
||||
}
|
||||
|
||||
if input.GetMouseWheelYNorm() > 0 {
|
||||
camPos.Data[2] += 1
|
||||
cam.Pos.AddZ(1)
|
||||
updateViewMat()
|
||||
} else if input.GetMouseWheelYNorm() < 0 {
|
||||
camPos.Data[2] -= 1
|
||||
cam.Pos.AddZ(-1)
|
||||
updateViewMat()
|
||||
}
|
||||
|
||||
@ -135,7 +180,7 @@ func (g *OurGame) Update() {
|
||||
simpleMat.SetUnifMat4("modelMat", &modelMat.Mat4)
|
||||
}
|
||||
|
||||
imgui.DragFloat3("Cam Pos", &camPos.Data)
|
||||
imgui.DragFloat3("Cam Pos", &cam.Pos.Data)
|
||||
}
|
||||
|
||||
func (g *OurGame) Render() {
|
||||
@ -161,33 +206,11 @@ func (g *OurGame) DeInit() {
|
||||
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() {
|
||||
targetPos := camPos.Clone().Add(camForward)
|
||||
viewMat := gglm.LookAt(camPos, targetPos, gglm.NewVec3(0, 1, 0))
|
||||
simpleMat.SetUnifMat4("viewMat", &viewMat.Mat4)
|
||||
target := cam.Pos.Clone()
|
||||
target.AddZ(1)
|
||||
cam.Target = *target
|
||||
cam.Update()
|
||||
|
||||
simpleMat.SetUnifMat4("viewMat", &cam.ViewMat)
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ package materials
|
||||
|
||||
import (
|
||||
"github.com/bloeys/gglm/gglm"
|
||||
"github.com/bloeys/nmage/asserts"
|
||||
"github.com/bloeys/nmage/assert"
|
||||
"github.com/bloeys/nmage/logging"
|
||||
"github.com/bloeys/nmage/shaders"
|
||||
"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"))
|
||||
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
|
||||
return loc
|
||||
}
|
||||
@ -55,7 +55,7 @@ func (m *Material) GetUnifLoc(uniformName string) int32 {
|
||||
}
|
||||
|
||||
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
|
||||
return loc
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
|
||||
"github.com/bloeys/assimp-go/asig"
|
||||
"github.com/bloeys/gglm/gglm"
|
||||
"github.com/bloeys/nmage/asserts"
|
||||
"github.com/bloeys/nmage/assert"
|
||||
"github.com/bloeys/nmage/buffers"
|
||||
)
|
||||
|
||||
@ -31,7 +31,7 @@ func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (*Mesh,
|
||||
sceneMesh := scene.Meshes[0]
|
||||
mesh.Buf = buffers.NewBuffer()
|
||||
|
||||
asserts.T(len(sceneMesh.TexCoords[0]) > 0, "Mesh has no UV0")
|
||||
assert.T(len(sceneMesh.TexCoords[0]) > 0, "Mesh has no UV0")
|
||||
layoutToUse := []buffers.Element{{ElementType: buffers.DataTypeVec3}, {ElementType: buffers.DataTypeVec3}, {ElementType: buffers.DataTypeVec2}}
|
||||
|
||||
if len(sceneMesh.ColorSets) > 0 && len(sceneMesh.ColorSets[0]) > 0 {
|
||||
@ -73,9 +73,9 @@ type arrToInterleave struct {
|
||||
|
||||
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")
|
||||
asserts.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.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.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 {
|
||||
return a.V2s[i].Data[:]
|
||||
@ -88,8 +88,8 @@ func (a *arrToInterleave) get(i int) []float32 {
|
||||
|
||||
func interleave(arrs ...arrToInterleave) []float32 {
|
||||
|
||||
asserts.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, "No input sent to interleave")
|
||||
assert.T(len(arrs[0].V2s) > 0 || len(arrs[0].V3s) > 0 || len(arrs[0].V4s) > 0, "Interleave arrays are empty")
|
||||
|
||||
elementCount := 0
|
||||
if len(arrs[0].V2s) > 0 {
|
||||
@ -104,7 +104,7 @@ func interleave(arrs ...arrToInterleave) []float32 {
|
||||
totalSize := 0
|
||||
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 {
|
||||
totalSize += len(arrs[i].V2s) * 2
|
||||
@ -152,7 +152,7 @@ func flattenVec4(vec4s []gglm.Vec4) []float32 {
|
||||
|
||||
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)
|
||||
for i := 0; i < len(faces); i++ {
|
||||
|
||||
@ -2,7 +2,7 @@ package nmageimgui
|
||||
|
||||
import (
|
||||
"github.com/bloeys/gglm/gglm"
|
||||
"github.com/bloeys/nmage/asserts"
|
||||
"github.com/bloeys/nmage/assert"
|
||||
"github.com/bloeys/nmage/materials"
|
||||
"github.com/bloeys/nmage/timing"
|
||||
"github.com/go-gl/gl/v4.1-core/gl"
|
||||
@ -23,7 +23,7 @@ type ImguiInfo struct {
|
||||
func (i *ImguiInfo) FrameStart(winWidth, winHeight float32) {
|
||||
|
||||
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()
|
||||
@ -36,7 +36,7 @@ func (i *ImguiInfo) FrameStart(winWidth, winHeight float32) {
|
||||
func (i *ImguiInfo) Render(winWidth, winHeight float32, fbWidth, fbHeight int32) {
|
||||
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user