diff --git a/asserts/asserts.go b/asserts/asserts.go new file mode 100755 index 0000000..6b0d5b9 --- /dev/null +++ b/asserts/asserts.go @@ -0,0 +1,18 @@ +package asserts + +import ( + "github.com/bloeys/go-sdl-engine/consts" + "github.com/bloeys/go-sdl-engine/logging" +) + +func True(check bool, msg string) { + if consts.Debug && !check { + logging.ErrLog.Panicln(msg) + } +} + +func False(check bool, msg string) { + if consts.Debug && check { + logging.ErrLog.Panicln(msg) + } +} diff --git a/buffers/buffers.go b/buffers/buffers.go index 9396a9b..9edc4ef 100755 --- a/buffers/buffers.go +++ b/buffers/buffers.go @@ -21,11 +21,14 @@ const ( BufTypeVertPos BufTypeColor BufTypeIndex + BufTypeNormal ) func (bt BufType) GetBufferGLType() BufGLType { switch bt { + case BufTypeNormal: + fallthrough case BufTypeColor: fallthrough case BufTypeVertPos: @@ -68,6 +71,7 @@ func (b *Buffer) Deactivate() { type BufferObject struct { VAOID uint32 VertPosBuf *Buffer + NormalBuf *Buffer ColorBuf *Buffer IndexBuf *Buffer } @@ -133,6 +137,8 @@ func (bo *BufferObject) SetBuffer(buf *Buffer) { switch buf.Type { case BufTypeVertPos: bo.VertPosBuf = buf + case BufTypeNormal: + bo.NormalBuf = buf case BufTypeColor: bo.ColorBuf = buf case BufTypeIndex: diff --git a/consts/flags_debug.go b/consts/flags_debug.go new file mode 100755 index 0000000..142cb5a --- /dev/null +++ b/consts/flags_debug.go @@ -0,0 +1,7 @@ +//go:build debug + +package consts + +const ( + Debug = true +) diff --git a/consts/flags_release.go b/consts/flags_release.go new file mode 100755 index 0000000..66d1ed0 --- /dev/null +++ b/consts/flags_release.go @@ -0,0 +1,7 @@ +//go:build !debug + +package consts + +const ( + Debug = false +) diff --git a/go.mod b/go.mod index cc99228..a2ab2f6 100755 --- a/go.mod +++ b/go.mod @@ -11,4 +11,7 @@ require ( github.com/inkyblackness/imgui-go/v4 v4.3.0 ) -require github.com/inkyblackness/imgui-go v1.12.0 // indirect +require ( + github.com/bloeys/assimp-go v0.2.0 // indirect + github.com/inkyblackness/imgui-go v1.12.0 // indirect +) diff --git a/go.sum b/go.sum index f07240f..67ee2b1 100755 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/bloeys/assimp-go v0.2.0 h1:CiqxTXsjUlNaCDhULmqZ2swsCsRahmg9BaOFA9a8vQU= +github.com/bloeys/assimp-go v0.2.0/go.mod h1:b9nj+ANpGPQ0mZ2r4Ma6nH1ExBTs9WIJF0N9zk1dWyk= github.com/bloeys/gglm v0.1.1 h1:juLE2OqobKKamMq7IKkplOJcZaM45CAcmbS0rCND3Hc= github.com/bloeys/gglm v0.1.1/go.mod h1:qwJQ0WzV191wAMwlGicbfbChbKoSedMk7gFFX6GnyOk= github.com/bloeys/gglm v0.2.4 h1:dHw+VHTdkr1GCsFWPJ7LAiEH1Ry+p4ReGhVK0/ssopo= diff --git a/imgui.ini b/imgui.ini new file mode 100755 index 0000000..29f0279 --- /dev/null +++ b/imgui.ini @@ -0,0 +1,5 @@ +[Window][Debug##Default] +Pos=809,63 +Size=449,377 +Collapsed=0 + diff --git a/main.go b/main.go index 26bb36a..4ce467e 100755 --- a/main.go +++ b/main.go @@ -1,13 +1,15 @@ package main import ( + "fmt" "runtime" + "github.com/bloeys/assimp-go/asig" "github.com/bloeys/gglm/gglm" + "github.com/bloeys/go-sdl-engine/asserts" "github.com/bloeys/go-sdl-engine/buffers" "github.com/bloeys/go-sdl-engine/input" "github.com/bloeys/go-sdl-engine/logging" - "github.com/bloeys/go-sdl-engine/res/models" "github.com/bloeys/go-sdl-engine/shaders" "github.com/go-gl/gl/v4.1-core/gl" "github.com/inkyblackness/imgui-go/v4" @@ -77,11 +79,15 @@ func main() { loadBuffers() initImGUI() - simpleShader.SetAttribute("vertPos", bo, bo.VertPosBuf) - simpleShader.EnableAttribute("vertPos") + //Enable vertex attributes + simpleShader.SetAttribute("vertPosIn", bo, bo.VertPosBuf) + simpleShader.EnableAttribute("vertPosIn") - // simpleShader.SetAttribute("vertColor", bo, bo.ColorBuf) - // simpleShader.EnableAttribute("vertColor") + simpleShader.SetAttribute("vertColorIn", bo, bo.ColorBuf) + simpleShader.EnableAttribute("vertColorIn") + + simpleShader.SetAttribute("vertNormalIn", bo, bo.NormalBuf) + simpleShader.EnableAttribute("vertNormalIn") //Movement, scale and rotation translationMat := gglm.NewTranslationMat(gglm.NewVec3(0, 0, 0)) @@ -101,6 +107,10 @@ func main() { projMat := gglm.Perspective(45*gglm.Deg2Rad, float32(winWidth)/float32(winHeight), 0.1, 20) simpleShader.SetUnifMat4("projMat", projMat) + //Lights + simpleShader.SetUnifVec3("lightPos1", &lightPos1) + simpleShader.SetUnifVec3("lightColor1", &lightColor1) + //Game loop for isRunning { @@ -189,36 +199,58 @@ func loadShaders() { imShader.Link() } +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 { + + asserts.True(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++ { + uints[i*3+0] = uint32(faces[i].Indices[0]) + uints[i*3+1] = uint32(faces[i].Indices[1]) + uints[i*3+2] = uint32(faces[i].Indices[2]) + } + + return uints +} + func loadBuffers() { - vertices := []float32{ - -0.5, 0.5, 0, - 0.5, 0.5, 0, - 0.5, -0.5, 0, - -0.5, -0.5, 0, - } - // colors := []float32{ - // 1, 0, 0, - // 0, 0, 1, - // 0, 0, 1, - // 0, 0, 1, - // } - indices := []uint32{0, 1, 3, 1, 2, 3} - - //Load obj - objInfo, err := models.LoadObj("./res/models/obj.obj") + scene, release, err := asig.ImportFile("./res/models/color-cube.fbx", asig.PostProcessTriangulate) if err != nil { - panic(err) + logging.ErrLog.Panicln("Failed to load model. Err: " + err.Error()) } - // logging.InfoLog.Printf("%v", objInfo.TriIndices) - - vertices = objInfo.VertPos - indices = objInfo.TriIndices + release() bo = buffers.NewBufferObject() - bo.GenBuffer(vertices, buffers.BufUsageStatic, buffers.BufTypeVertPos, buffers.DataTypeVec3) - // bo.GenBuffer(colors, buffers.BufUsageStatic, buffers.BufTypeColor, buffers.DataTypeVec3) - bo.GenBufferUint32(indices, buffers.BufUsageStatic, buffers.BufTypeIndex, buffers.DataTypeUint32) + bo.GenBuffer(flattenVec3(scene.Meshes[0].Vertices), buffers.BufUsageStatic, buffers.BufTypeVertPos, buffers.DataTypeVec3) + bo.GenBuffer(flattenVec3(scene.Meshes[0].Normals), buffers.BufUsageStatic, buffers.BufTypeNormal, buffers.DataTypeVec3) + bo.GenBuffer(flattenVec4(scene.Meshes[0].ColorSets[0]), buffers.BufUsageStatic, buffers.BufTypeColor, buffers.DataTypeVec4) + bo.GenBufferUint32(flattenFaces(scene.Meshes[0].Faces), buffers.BufUsageStatic, buffers.BufTypeIndex, buffers.DataTypeUint32) } func initImGUI() { @@ -380,9 +412,12 @@ func handleWindowResize(newWinWidth, newWinHeight int32) { var time uint64 = 0 var name string = "" -var ambientColor gglm.Vec3 +var ambientColor gglm.Vec3 = *gglm.NewVec3(1, 1, 1) var ambientColorStrength float32 = 1 +var lightPos1 gglm.Vec3 = *gglm.NewVec3(2, 2, 0) +var lightColor1 gglm.Vec3 = *gglm.NewVec3(1, 1, 1) + func runGameLogic() { if input.KeyDown(sdl.K_w) { @@ -428,6 +463,14 @@ func runGameLogic() { simpleShader.SetUnifFloat32("ambientStrength", ambientColorStrength) } + if imgui.SliderFloat3("Light Pos 1", &lightPos1.Data, -10, 10) { + simpleShader.SetUnifVec3("lightPos1", &lightPos1) + } + + if imgui.SliderFloat3("Light Color 1", &lightColor1.Data, 0, 1) { + simpleShader.SetUnifVec3("lightColor1", &lightColor1) + } + imgui.Render() } diff --git a/res/models/color-cube.fbx b/res/models/color-cube.fbx new file mode 100755 index 0000000..bda8866 Binary files /dev/null and b/res/models/color-cube.fbx differ diff --git a/res/models/loader.go b/res/models/loader.go deleted file mode 100755 index b32c291..0000000 --- a/res/models/loader.go +++ /dev/null @@ -1,73 +0,0 @@ -package models - -import ( - "os" - "strconv" - "strings" - - "github.com/bloeys/go-sdl-engine/logging" -) - -type ObjInfo struct { - VertPos []float32 - TriIndices []uint32 -} - -func LoadObj(file string) (objInfo ObjInfo, err error) { - - b, err := os.ReadFile(file) - if err != nil { - return objInfo, err - } - - lines := strings.Split(string(b), "\n") - for i := 0; i < len(lines); i++ { - - s := strings.SplitN(lines[i], " ", 2) - switch s[0] { - case "v": - - vertPosStrings := strings.Split(s[1], " ") - - f, err := strconv.ParseFloat(vertPosStrings[0], 32) - if err != nil { - return objInfo, err - } - objInfo.VertPos = append(objInfo.VertPos, float32(f)) - - f, err = strconv.ParseFloat(vertPosStrings[1], 32) - if err != nil { - return objInfo, err - } - objInfo.VertPos = append(objInfo.VertPos, float32(f)) - - f, err = strconv.ParseFloat(vertPosStrings[2], 32) - if err != nil { - return objInfo, err - } - objInfo.VertPos = append(objInfo.VertPos, float32(f)) - - case "f": - - facesStrings := strings.Split(s[1], " ") - objInfo.TriIndices = append(objInfo.TriIndices, getVertIndexFromFace(facesStrings[0])) - objInfo.TriIndices = append(objInfo.TriIndices, getVertIndexFromFace(facesStrings[1])) - objInfo.TriIndices = append(objInfo.TriIndices, getVertIndexFromFace(facesStrings[2])) - - default: - } - } - - return objInfo, nil -} - -func getVertIndexFromFace(f string) uint32 { - - indxStr := strings.SplitN(f, "/", 2)[0] - index, err := strconv.Atoi(indxStr) - if err != nil { - logging.ErrLog.Printf("Invalid face index '%v'. Err: %v", indxStr, err) - return 0 - } - return uint32(index) - 1 -} diff --git a/res/shaders/simple.frag.glsl b/res/shaders/simple.frag.glsl index 2753ae6..de8d453 100755 --- a/res/shaders/simple.frag.glsl +++ b/res/shaders/simple.frag.glsl @@ -1,14 +1,23 @@ #version 410 -in vec3 outColor; +in vec3 vertColor; +in vec3 vertNormal; +in vec3 fragPos; out vec4 fragColor; -uniform vec3 ambientLightColor = vec3(1, 0, 0); uniform float ambientStrength = 1; +uniform vec3 ambientLightColor = vec3(1, 1, 1); + +uniform vec3 lightPos1; +uniform vec3 lightColor1; void main() { - vec3 objColor = vec3(1, 1, 1); - fragColor = vec4(objColor * ambientLightColor * ambientStrength, 1.0); + // vec3 norm = normalize(Normal); + vec3 lightDir = normalize(lightPos1 - fragPos); + float diffStrength = max(0.0, dot(normalize(vertNormal), lightDir)); + + vec3 finalAmbientColor = ambientLightColor * ambientStrength; + fragColor = vec4(vertColor * (finalAmbientColor + diffStrength*lightColor1), 1.0); } diff --git a/res/shaders/simple.vert.glsl b/res/shaders/simple.vert.glsl index 72aa04a..84a294d 100755 --- a/res/shaders/simple.vert.glsl +++ b/res/shaders/simple.vert.glsl @@ -1,9 +1,12 @@ #version 410 -in vec3 vertPos; -in vec3 vertColor; +in vec3 vertPosIn; +in vec3 vertColorIn; +in vec3 vertNormalIn; -out vec3 outColor; +out vec3 vertColor; +out vec3 vertNormal; +out vec3 fragPos; //MVP = Model View Projection uniform mat4 modelMat; @@ -12,6 +15,9 @@ uniform mat4 projMat; void main() { - outColor = vertColor; - gl_Position = projMat * viewMat * modelMat * (vec4(vertPos, 1.0)); // vec4(vertPos.x, vertPos.y, vertPos.z, 1.0) + vertColor = vertColorIn; + vertNormal = vertNormalIn; + fragPos = vec3(modelMat * vec4(vertPosIn, 1.0)); + + gl_Position = projMat * viewMat * modelMat * vec4(vertPosIn, 1.0); } \ No newline at end of file