mirror of
https://github.com/bloeys/nmage.git
synced 2025-12-29 13:28:20 +00:00
Day8: Assimp+Basic Lights+Asserts+vert normals&colors
This commit is contained in:
18
asserts/asserts.go
Executable file
18
asserts/asserts.go
Executable file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -21,11 +21,14 @@ const (
|
|||||||
BufTypeVertPos
|
BufTypeVertPos
|
||||||
BufTypeColor
|
BufTypeColor
|
||||||
BufTypeIndex
|
BufTypeIndex
|
||||||
|
BufTypeNormal
|
||||||
)
|
)
|
||||||
|
|
||||||
func (bt BufType) GetBufferGLType() BufGLType {
|
func (bt BufType) GetBufferGLType() BufGLType {
|
||||||
switch bt {
|
switch bt {
|
||||||
|
|
||||||
|
case BufTypeNormal:
|
||||||
|
fallthrough
|
||||||
case BufTypeColor:
|
case BufTypeColor:
|
||||||
fallthrough
|
fallthrough
|
||||||
case BufTypeVertPos:
|
case BufTypeVertPos:
|
||||||
@ -68,6 +71,7 @@ func (b *Buffer) Deactivate() {
|
|||||||
type BufferObject struct {
|
type BufferObject struct {
|
||||||
VAOID uint32
|
VAOID uint32
|
||||||
VertPosBuf *Buffer
|
VertPosBuf *Buffer
|
||||||
|
NormalBuf *Buffer
|
||||||
ColorBuf *Buffer
|
ColorBuf *Buffer
|
||||||
IndexBuf *Buffer
|
IndexBuf *Buffer
|
||||||
}
|
}
|
||||||
@ -133,6 +137,8 @@ func (bo *BufferObject) SetBuffer(buf *Buffer) {
|
|||||||
switch buf.Type {
|
switch buf.Type {
|
||||||
case BufTypeVertPos:
|
case BufTypeVertPos:
|
||||||
bo.VertPosBuf = buf
|
bo.VertPosBuf = buf
|
||||||
|
case BufTypeNormal:
|
||||||
|
bo.NormalBuf = buf
|
||||||
case BufTypeColor:
|
case BufTypeColor:
|
||||||
bo.ColorBuf = buf
|
bo.ColorBuf = buf
|
||||||
case BufTypeIndex:
|
case BufTypeIndex:
|
||||||
|
|||||||
7
consts/flags_debug.go
Executable file
7
consts/flags_debug.go
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
//go:build debug
|
||||||
|
|
||||||
|
package consts
|
||||||
|
|
||||||
|
const (
|
||||||
|
Debug = true
|
||||||
|
)
|
||||||
7
consts/flags_release.go
Executable file
7
consts/flags_release.go
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
//go:build !debug
|
||||||
|
|
||||||
|
package consts
|
||||||
|
|
||||||
|
const (
|
||||||
|
Debug = false
|
||||||
|
)
|
||||||
5
go.mod
5
go.mod
@ -11,4 +11,7 @@ require (
|
|||||||
github.com/inkyblackness/imgui-go/v4 v4.3.0
|
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
|
||||||
|
)
|
||||||
|
|||||||
2
go.sum
2
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 h1:juLE2OqobKKamMq7IKkplOJcZaM45CAcmbS0rCND3Hc=
|
||||||
github.com/bloeys/gglm v0.1.1/go.mod h1:qwJQ0WzV191wAMwlGicbfbChbKoSedMk7gFFX6GnyOk=
|
github.com/bloeys/gglm v0.1.1/go.mod h1:qwJQ0WzV191wAMwlGicbfbChbKoSedMk7gFFX6GnyOk=
|
||||||
github.com/bloeys/gglm v0.2.4 h1:dHw+VHTdkr1GCsFWPJ7LAiEH1Ry+p4ReGhVK0/ssopo=
|
github.com/bloeys/gglm v0.2.4 h1:dHw+VHTdkr1GCsFWPJ7LAiEH1Ry+p4ReGhVK0/ssopo=
|
||||||
|
|||||||
5
imgui.ini
Executable file
5
imgui.ini
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
[Window][Debug##Default]
|
||||||
|
Pos=809,63
|
||||||
|
Size=449,377
|
||||||
|
Collapsed=0
|
||||||
|
|
||||||
103
main.go
103
main.go
@ -1,13 +1,15 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/bloeys/assimp-go/asig"
|
||||||
"github.com/bloeys/gglm/gglm"
|
"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/buffers"
|
||||||
"github.com/bloeys/go-sdl-engine/input"
|
"github.com/bloeys/go-sdl-engine/input"
|
||||||
"github.com/bloeys/go-sdl-engine/logging"
|
"github.com/bloeys/go-sdl-engine/logging"
|
||||||
"github.com/bloeys/go-sdl-engine/res/models"
|
|
||||||
"github.com/bloeys/go-sdl-engine/shaders"
|
"github.com/bloeys/go-sdl-engine/shaders"
|
||||||
"github.com/go-gl/gl/v4.1-core/gl"
|
"github.com/go-gl/gl/v4.1-core/gl"
|
||||||
"github.com/inkyblackness/imgui-go/v4"
|
"github.com/inkyblackness/imgui-go/v4"
|
||||||
@ -77,11 +79,15 @@ func main() {
|
|||||||
loadBuffers()
|
loadBuffers()
|
||||||
initImGUI()
|
initImGUI()
|
||||||
|
|
||||||
simpleShader.SetAttribute("vertPos", bo, bo.VertPosBuf)
|
//Enable vertex attributes
|
||||||
simpleShader.EnableAttribute("vertPos")
|
simpleShader.SetAttribute("vertPosIn", bo, bo.VertPosBuf)
|
||||||
|
simpleShader.EnableAttribute("vertPosIn")
|
||||||
|
|
||||||
// simpleShader.SetAttribute("vertColor", bo, bo.ColorBuf)
|
simpleShader.SetAttribute("vertColorIn", bo, bo.ColorBuf)
|
||||||
// simpleShader.EnableAttribute("vertColor")
|
simpleShader.EnableAttribute("vertColorIn")
|
||||||
|
|
||||||
|
simpleShader.SetAttribute("vertNormalIn", bo, bo.NormalBuf)
|
||||||
|
simpleShader.EnableAttribute("vertNormalIn")
|
||||||
|
|
||||||
//Movement, scale and rotation
|
//Movement, scale and rotation
|
||||||
translationMat := gglm.NewTranslationMat(gglm.NewVec3(0, 0, 0))
|
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)
|
projMat := gglm.Perspective(45*gglm.Deg2Rad, float32(winWidth)/float32(winHeight), 0.1, 20)
|
||||||
simpleShader.SetUnifMat4("projMat", projMat)
|
simpleShader.SetUnifMat4("projMat", projMat)
|
||||||
|
|
||||||
|
//Lights
|
||||||
|
simpleShader.SetUnifVec3("lightPos1", &lightPos1)
|
||||||
|
simpleShader.SetUnifVec3("lightColor1", &lightColor1)
|
||||||
|
|
||||||
//Game loop
|
//Game loop
|
||||||
for isRunning {
|
for isRunning {
|
||||||
|
|
||||||
@ -189,36 +199,58 @@ func loadShaders() {
|
|||||||
imShader.Link()
|
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() {
|
func loadBuffers() {
|
||||||
|
|
||||||
vertices := []float32{
|
scene, release, err := asig.ImportFile("./res/models/color-cube.fbx", asig.PostProcessTriangulate)
|
||||||
-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")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
logging.ErrLog.Panicln("Failed to load model. Err: " + err.Error())
|
||||||
}
|
}
|
||||||
// logging.InfoLog.Printf("%v", objInfo.TriIndices)
|
release()
|
||||||
|
|
||||||
vertices = objInfo.VertPos
|
|
||||||
indices = objInfo.TriIndices
|
|
||||||
|
|
||||||
bo = buffers.NewBufferObject()
|
bo = buffers.NewBufferObject()
|
||||||
bo.GenBuffer(vertices, buffers.BufUsageStatic, buffers.BufTypeVertPos, buffers.DataTypeVec3)
|
bo.GenBuffer(flattenVec3(scene.Meshes[0].Vertices), buffers.BufUsageStatic, buffers.BufTypeVertPos, buffers.DataTypeVec3)
|
||||||
// bo.GenBuffer(colors, buffers.BufUsageStatic, buffers.BufTypeColor, buffers.DataTypeVec3)
|
bo.GenBuffer(flattenVec3(scene.Meshes[0].Normals), buffers.BufUsageStatic, buffers.BufTypeNormal, buffers.DataTypeVec3)
|
||||||
bo.GenBufferUint32(indices, buffers.BufUsageStatic, buffers.BufTypeIndex, buffers.DataTypeUint32)
|
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() {
|
func initImGUI() {
|
||||||
@ -380,9 +412,12 @@ func handleWindowResize(newWinWidth, newWinHeight int32) {
|
|||||||
var time uint64 = 0
|
var time uint64 = 0
|
||||||
var name string = ""
|
var name string = ""
|
||||||
|
|
||||||
var ambientColor gglm.Vec3
|
var ambientColor gglm.Vec3 = *gglm.NewVec3(1, 1, 1)
|
||||||
var ambientColorStrength float32 = 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() {
|
func runGameLogic() {
|
||||||
|
|
||||||
if input.KeyDown(sdl.K_w) {
|
if input.KeyDown(sdl.K_w) {
|
||||||
@ -428,6 +463,14 @@ func runGameLogic() {
|
|||||||
simpleShader.SetUnifFloat32("ambientStrength", ambientColorStrength)
|
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()
|
imgui.Render()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
BIN
res/models/color-cube.fbx
Executable file
BIN
res/models/color-cube.fbx
Executable file
Binary file not shown.
@ -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
|
|
||||||
}
|
|
||||||
@ -1,14 +1,23 @@
|
|||||||
#version 410
|
#version 410
|
||||||
|
|
||||||
in vec3 outColor;
|
in vec3 vertColor;
|
||||||
|
in vec3 vertNormal;
|
||||||
|
in vec3 fragPos;
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
uniform vec3 ambientLightColor = vec3(1, 0, 0);
|
|
||||||
uniform float ambientStrength = 1;
|
uniform float ambientStrength = 1;
|
||||||
|
uniform vec3 ambientLightColor = vec3(1, 1, 1);
|
||||||
|
|
||||||
|
uniform vec3 lightPos1;
|
||||||
|
uniform vec3 lightColor1;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec3 objColor = vec3(1, 1, 1);
|
// vec3 norm = normalize(Normal);
|
||||||
fragColor = vec4(objColor * ambientLightColor * ambientStrength, 1.0);
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
#version 410
|
#version 410
|
||||||
|
|
||||||
in vec3 vertPos;
|
in vec3 vertPosIn;
|
||||||
in vec3 vertColor;
|
in vec3 vertColorIn;
|
||||||
|
in vec3 vertNormalIn;
|
||||||
|
|
||||||
out vec3 outColor;
|
out vec3 vertColor;
|
||||||
|
out vec3 vertNormal;
|
||||||
|
out vec3 fragPos;
|
||||||
|
|
||||||
//MVP = Model View Projection
|
//MVP = Model View Projection
|
||||||
uniform mat4 modelMat;
|
uniform mat4 modelMat;
|
||||||
@ -12,6 +15,9 @@ uniform mat4 projMat;
|
|||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
outColor = vertColor;
|
vertColor = vertColorIn;
|
||||||
gl_Position = projMat * viewMat * modelMat * (vec4(vertPos, 1.0)); // vec4(vertPos.x, vertPos.y, vertPos.z, 1.0)
|
vertNormal = vertNormalIn;
|
||||||
|
fragPos = vec3(modelMat * vec4(vertPosIn, 1.0));
|
||||||
|
|
||||||
|
gl_Position = projMat * viewMat * modelMat * vec4(vertPosIn, 1.0);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user