mirror of
https://github.com/bloeys/nmage.git
synced 2025-12-29 13:28:20 +00:00
Starting work on Engine+Mesh+Material systems/packages
This commit is contained in:
@ -153,11 +153,11 @@ func (bo *BufferObject) SetBuffer(buf *Buffer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bo *BufferObject) Activate() {
|
func (bo *BufferObject) Bind() {
|
||||||
gl.BindVertexArray(bo.VAOID)
|
gl.BindVertexArray(bo.VAOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bo *BufferObject) Deactivate() {
|
func (bo *BufferObject) UnBind() {
|
||||||
gl.BindVertexArray(0)
|
gl.BindVertexArray(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
108
engine/engine.go
Executable file
108
engine/engine.go
Executable file
@ -0,0 +1,108 @@
|
|||||||
|
package engine
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/bloeys/nmage/timing"
|
||||||
|
"github.com/go-gl/gl/v4.1-core/gl"
|
||||||
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Window struct {
|
||||||
|
SDLWin *sdl.Window
|
||||||
|
GlCtx sdl.GLContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) Destroy() error {
|
||||||
|
return w.SDLWin.Destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Init() error {
|
||||||
|
|
||||||
|
timing.Init()
|
||||||
|
err := initSDL()
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func initSDL() error {
|
||||||
|
|
||||||
|
err := sdl.Init(sdl.INIT_EVERYTHING)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
sdl.ShowCursor(1)
|
||||||
|
|
||||||
|
sdl.GLSetAttribute(sdl.MAJOR_VERSION, 4)
|
||||||
|
sdl.GLSetAttribute(sdl.MINOR_VERSION, 1)
|
||||||
|
|
||||||
|
// R(0-255) G(0-255) B(0-255)
|
||||||
|
sdl.GLSetAttribute(sdl.GL_RED_SIZE, 8)
|
||||||
|
sdl.GLSetAttribute(sdl.GL_GREEN_SIZE, 8)
|
||||||
|
sdl.GLSetAttribute(sdl.GL_BLUE_SIZE, 8)
|
||||||
|
|
||||||
|
sdl.GLSetAttribute(sdl.GL_DOUBLEBUFFER, 1)
|
||||||
|
sdl.GLSetAttribute(sdl.GL_DEPTH_SIZE, 24)
|
||||||
|
sdl.GLSetAttribute(sdl.GL_STENCIL_SIZE, 8)
|
||||||
|
|
||||||
|
sdl.GLSetAttribute(sdl.GL_CONTEXT_PROFILE_MASK, sdl.GL_CONTEXT_PROFILE_CORE)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateOpenGLWindow(title string, x, y, width, height int32, flags WindowFlags) (*Window, error) {
|
||||||
|
return createWindow(title, x, y, width, height, WindowFlags_OPENGL|flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateOpenGLWindowCentered(title string, width, height int32, flags WindowFlags) (*Window, error) {
|
||||||
|
return createWindow(title, -1, -1, width, height, WindowFlags_OPENGL|flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createWindow(title string, x, y, width, height int32, flags WindowFlags) (*Window, error) {
|
||||||
|
|
||||||
|
if x == -1 && y == -1 {
|
||||||
|
x = sdl.WINDOWPOS_CENTERED
|
||||||
|
y = sdl.WINDOWPOS_CENTERED
|
||||||
|
}
|
||||||
|
|
||||||
|
sdlWin, err := sdl.CreateWindow(title, x, y, width, height, uint32(flags))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
win := &Window{SDLWin: sdlWin}
|
||||||
|
|
||||||
|
win.GlCtx, err = sdlWin.GLCreateContext()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = initOpenGL()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return win, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func initOpenGL() error {
|
||||||
|
|
||||||
|
if err := gl.Init(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.Enable(gl.DEPTH_TEST)
|
||||||
|
|
||||||
|
gl.Enable(gl.CULL_FACE)
|
||||||
|
gl.CullFace(gl.BACK)
|
||||||
|
gl.FrontFace(gl.CCW)
|
||||||
|
|
||||||
|
gl.ClearColor(0, 0, 0, 1)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetVSync(enabled bool) {
|
||||||
|
if enabled {
|
||||||
|
sdl.GLSetSwapInterval(1)
|
||||||
|
} else {
|
||||||
|
sdl.GLSetSwapInterval(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
29
engine/windowflags.go
Executable file
29
engine/windowflags.go
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
package engine
|
||||||
|
|
||||||
|
import "github.com/veandco/go-sdl2/sdl"
|
||||||
|
|
||||||
|
type WindowFlags int
|
||||||
|
|
||||||
|
const (
|
||||||
|
WindowFlags_FULLSCREEN WindowFlags = sdl.WINDOW_FULLSCREEN
|
||||||
|
WindowFlags_OPENGL WindowFlags = sdl.WINDOW_OPENGL
|
||||||
|
WindowFlags_SHOWN WindowFlags = sdl.WINDOW_SHOWN
|
||||||
|
WindowFlags_HIDDEN WindowFlags = sdl.WINDOW_HIDDEN
|
||||||
|
WindowFlags_BORDERLESS WindowFlags = sdl.WINDOW_BORDERLESS
|
||||||
|
WindowFlags_RESIZABLE WindowFlags = sdl.WINDOW_RESIZABLE
|
||||||
|
WindowFlags_MINIMIZED WindowFlags = sdl.WINDOW_MINIMIZED
|
||||||
|
WindowFlags_MAXIMIZED WindowFlags = sdl.WINDOW_MAXIMIZED
|
||||||
|
WindowFlags_INPUT_GRABBED WindowFlags = sdl.WINDOW_INPUT_GRABBED
|
||||||
|
WindowFlags_INPUT_FOCUS WindowFlags = sdl.WINDOW_INPUT_FOCUS
|
||||||
|
WindowFlags_MOUSE_FOCUS WindowFlags = sdl.WINDOW_MOUSE_FOCUS
|
||||||
|
WindowFlags_FULLSCREEN_DESKTOP WindowFlags = sdl.WINDOW_FULLSCREEN_DESKTOP
|
||||||
|
WindowFlags_FOREIGN WindowFlags = sdl.WINDOW_FOREIGN
|
||||||
|
WindowFlags_ALLOW_HIGHDPI WindowFlags = sdl.WINDOW_ALLOW_HIGHDPI
|
||||||
|
WindowFlags_MOUSE_CAPTURE WindowFlags = sdl.WINDOW_MOUSE_CAPTURE
|
||||||
|
WindowFlags_ALWAYS_ON_TOP WindowFlags = sdl.WINDOW_ALWAYS_ON_TOP
|
||||||
|
WindowFlags_SKIP_TASKBAR WindowFlags = sdl.WINDOW_SKIP_TASKBAR
|
||||||
|
WindowFlags_UTILITY WindowFlags = sdl.WINDOW_UTILITY
|
||||||
|
WindowFlags_TOOLTIP WindowFlags = sdl.WINDOW_TOOLTIP
|
||||||
|
WindowFlags_POPUP_MENU WindowFlags = sdl.WINDOW_POPUP_MENU
|
||||||
|
// WindowFlags_VULKAN WindowFlags = sdl.WINDOW_VULKAN
|
||||||
|
)
|
||||||
307
main.go
307
main.go
@ -6,27 +6,30 @@ 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/engine"
|
||||||
"github.com/bloeys/nmage/buffers"
|
|
||||||
"github.com/bloeys/nmage/input"
|
"github.com/bloeys/nmage/input"
|
||||||
"github.com/bloeys/nmage/logging"
|
"github.com/bloeys/nmage/logging"
|
||||||
"github.com/bloeys/nmage/shaders"
|
"github.com/bloeys/nmage/materials"
|
||||||
|
"github.com/bloeys/nmage/meshes"
|
||||||
"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"
|
||||||
"github.com/inkyblackness/imgui-go/v4"
|
"github.com/inkyblackness/imgui-go/v4"
|
||||||
"github.com/veandco/go-sdl2/sdl"
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
)
|
)
|
||||||
|
|
||||||
//TODO:
|
//TODO: Tasks:
|
||||||
//Make a window/engine class
|
//Engine loop
|
||||||
//Mesh class
|
//Proper rendering setup
|
||||||
|
//Flesh out the material system
|
||||||
//Object
|
//Object
|
||||||
//Abstract UI
|
//Abstract UI
|
||||||
//Textures
|
//Textures
|
||||||
|
//Audio
|
||||||
|
|
||||||
|
//Low Priority:
|
||||||
// Proper Asset loading
|
// Proper Asset loading
|
||||||
// Rework buffers package
|
// Rework buffers package
|
||||||
// Interleaved or packed buffers (xyzxyzxyz OR xxxyyyzzz)
|
// Interleaved or packed buffers (xyzxyzxyz OR xxxyyyzzz)
|
||||||
//Audio
|
|
||||||
|
|
||||||
type ImguiInfo struct {
|
type ImguiInfo struct {
|
||||||
imCtx *imgui.Context
|
imCtx *imgui.Context
|
||||||
@ -42,11 +45,11 @@ var (
|
|||||||
winHeight int32 = 720
|
winHeight int32 = 720
|
||||||
|
|
||||||
isRunning bool = true
|
isRunning bool = true
|
||||||
window *sdl.Window
|
window *engine.Window
|
||||||
|
|
||||||
simpleShader shaders.ShaderProgram
|
simpleMat *materials.Material
|
||||||
imShader shaders.ShaderProgram
|
imguiMat *materials.Material
|
||||||
bo *buffers.BufferObject
|
cubeMesh *meshes.Mesh
|
||||||
|
|
||||||
modelMat = gglm.NewTrMatId()
|
modelMat = gglm.NewTrMatId()
|
||||||
projMat = &gglm.Mat4{}
|
projMat = &gglm.Mat4{}
|
||||||
@ -61,44 +64,42 @@ func main() {
|
|||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
|
||||||
err := initSDL()
|
//Init engine
|
||||||
|
err := engine.Init()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logging.ErrLog.Fatalln("Failed to init SDL. Err:", err)
|
logging.ErrLog.Fatalln("Failed to init nMage. Err:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
window, err = sdl.CreateWindow("Go SDL Engine", sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, winWidth, winHeight, sdl.WINDOW_OPENGL|sdl.WINDOW_RESIZABLE)
|
//Create window
|
||||||
|
window, err = engine.CreateOpenGLWindowCentered("nMage", winWidth, winHeight, engine.WindowFlags_RESIZABLE)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logging.ErrLog.Fatalln("Failed to create window. Err: ", err)
|
logging.ErrLog.Fatalln("Failed to create window. Err: ", err)
|
||||||
}
|
}
|
||||||
defer window.Destroy()
|
defer window.Destroy()
|
||||||
|
|
||||||
glCtx, err := window.GLCreateContext()
|
engine.SetVSync(false)
|
||||||
if err != nil {
|
|
||||||
logging.ErrLog.Fatalln("Failed to create OpenGL context. Err: ", err)
|
|
||||||
}
|
|
||||||
defer sdl.GLDeleteContext(glCtx)
|
|
||||||
|
|
||||||
err = initOpenGL()
|
//Create materials
|
||||||
|
simpleMat = materials.NewMaterial("Simple Mat", "./res/shaders/simple")
|
||||||
|
imguiMat = materials.NewMaterial("ImGUI Mat", "./res/shaders/imgui")
|
||||||
|
|
||||||
|
//Load meshes
|
||||||
|
cubeMesh, err = meshes.NewMesh("Cube", "./res/models/color-cube.fbx", asig.PostProcess(0))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logging.ErrLog.Fatalln(err)
|
logging.ErrLog.Fatalln("Failed to load cube mesh. Err: ", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Set vsync
|
|
||||||
sdl.GLSetSwapInterval(0)
|
|
||||||
|
|
||||||
loadShaders()
|
|
||||||
loadBuffers()
|
|
||||||
initImGUI()
|
initImGUI()
|
||||||
|
|
||||||
//Enable vertex attributes
|
//Enable vertex attributes
|
||||||
simpleShader.SetAttribute("vertPosIn", bo, bo.VertPosBuf)
|
simpleMat.SetAttribute("vertPosIn", cubeMesh.BufObj, cubeMesh.BufObj.VertPosBuf)
|
||||||
simpleShader.EnableAttribute("vertPosIn")
|
simpleMat.EnableAttribute("vertPosIn")
|
||||||
|
|
||||||
simpleShader.SetAttribute("vertColorIn", bo, bo.ColorBuf)
|
simpleMat.SetAttribute("vertColorIn", cubeMesh.BufObj, cubeMesh.BufObj.ColorBuf)
|
||||||
simpleShader.EnableAttribute("vertColorIn")
|
simpleMat.EnableAttribute("vertColorIn")
|
||||||
|
|
||||||
simpleShader.SetAttribute("vertNormalIn", bo, bo.NormalBuf)
|
simpleMat.SetAttribute("vertNormalIn", cubeMesh.BufObj, cubeMesh.BufObj.NormalBuf)
|
||||||
simpleShader.EnableAttribute("vertNormalIn")
|
simpleMat.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))
|
||||||
@ -106,21 +107,20 @@ func main() {
|
|||||||
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)))
|
modelMat.Mul(translationMat.Mul(rotMat.Mul(scaleMat)))
|
||||||
simpleShader.SetUnifMat4("modelMat", &modelMat.Mat4)
|
simpleMat.SetUnifMat4("modelMat", &modelMat.Mat4)
|
||||||
|
|
||||||
//Moves objects into the cameras view
|
//Moves objects into the cameras view
|
||||||
updateViewMat()
|
updateViewMat()
|
||||||
|
|
||||||
//Perspective/Depth
|
//Perspective/Depth
|
||||||
projMat := gglm.Perspective(45*gglm.Deg2Rad, float32(winWidth)/float32(winHeight), 0.1, 500)
|
projMat := gglm.Perspective(45*gglm.Deg2Rad, float32(winWidth)/float32(winHeight), 0.1, 500)
|
||||||
simpleShader.SetUnifMat4("projMat", projMat)
|
simpleMat.SetUnifMat4("projMat", projMat)
|
||||||
|
|
||||||
//Lights
|
//Lights
|
||||||
simpleShader.SetUnifVec3("lightPos1", &lightPos1)
|
simpleMat.SetUnifVec3("lightPos1", &lightPos1)
|
||||||
simpleShader.SetUnifVec3("lightColor1", &lightColor1)
|
simpleMat.SetUnifVec3("lightColor1", &lightColor1)
|
||||||
|
|
||||||
//Game loop
|
//Game loop
|
||||||
timing.Init()
|
|
||||||
for isRunning {
|
for isRunning {
|
||||||
|
|
||||||
timing.FrameStarted()
|
timing.FrameStarted()
|
||||||
@ -132,154 +132,14 @@ func main() {
|
|||||||
|
|
||||||
timing.FrameEnded()
|
timing.FrameEnded()
|
||||||
|
|
||||||
window.SetTitle(fmt.Sprintf("FPS: %.0f; Elapsed: %v", 1/timing.DT(), timing.ElapsedTime()))
|
window.SDLWin.SetTitle(fmt.Sprintf("FPS: %.0f; Elapsed: %v", 1/timing.DT(), timing.ElapsedTime()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateViewMat() {
|
func updateViewMat() {
|
||||||
targetPos := camPos.Clone().Add(camForward)
|
targetPos := camPos.Clone().Add(camForward)
|
||||||
viewMat := gglm.LookAt(camPos, targetPos, gglm.NewVec3(0, 1, 0))
|
viewMat := gglm.LookAt(camPos, targetPos, gglm.NewVec3(0, 1, 0))
|
||||||
simpleShader.SetUnifMat4("viewMat", &viewMat.Mat4)
|
simpleMat.SetUnifMat4("viewMat", &viewMat.Mat4)
|
||||||
}
|
|
||||||
|
|
||||||
func initSDL() error {
|
|
||||||
|
|
||||||
err := sdl.Init(sdl.INIT_EVERYTHING)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
sdl.ShowCursor(1)
|
|
||||||
|
|
||||||
sdl.GLSetAttribute(sdl.MAJOR_VERSION, 4)
|
|
||||||
sdl.GLSetAttribute(sdl.MINOR_VERSION, 1)
|
|
||||||
|
|
||||||
// R(0-255) G(0-255) B(0-255)
|
|
||||||
sdl.GLSetAttribute(sdl.GL_RED_SIZE, 8)
|
|
||||||
sdl.GLSetAttribute(sdl.GL_GREEN_SIZE, 8)
|
|
||||||
sdl.GLSetAttribute(sdl.GL_BLUE_SIZE, 8)
|
|
||||||
|
|
||||||
sdl.GLSetAttribute(sdl.GL_DOUBLEBUFFER, 1)
|
|
||||||
sdl.GLSetAttribute(sdl.GL_DEPTH_SIZE, 24)
|
|
||||||
sdl.GLSetAttribute(sdl.GL_STENCIL_SIZE, 8)
|
|
||||||
|
|
||||||
sdl.GLSetAttribute(sdl.GL_CONTEXT_PROFILE_MASK, sdl.GL_CONTEXT_PROFILE_CORE)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func initOpenGL() error {
|
|
||||||
|
|
||||||
if err := gl.Init(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
gl.Enable(gl.DEPTH_TEST)
|
|
||||||
|
|
||||||
gl.Enable(gl.CULL_FACE)
|
|
||||||
gl.CullFace(gl.BACK)
|
|
||||||
gl.FrontFace(gl.CCW)
|
|
||||||
|
|
||||||
gl.ClearColor(0, 0, 0, 1)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadShaders() {
|
|
||||||
|
|
||||||
var err error
|
|
||||||
simpleShader, err = shaders.NewShaderProgram()
|
|
||||||
if err != nil {
|
|
||||||
logging.ErrLog.Fatalln("Failed to create new shader program. Err: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
vertShader, err := shaders.LoadAndCompilerShader("./res/shaders/simple.vert.glsl", shaders.VertexShaderType)
|
|
||||||
if err != nil {
|
|
||||||
logging.ErrLog.Fatalln("Failed to create new shader. Err: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fragShader, err := shaders.LoadAndCompilerShader("./res/shaders/simple.frag.glsl", shaders.FragmentShaderType)
|
|
||||||
if err != nil {
|
|
||||||
logging.ErrLog.Fatalln("Failed to create new shader. Err: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
simpleShader.AttachShader(vertShader)
|
|
||||||
simpleShader.AttachShader(fragShader)
|
|
||||||
simpleShader.Link()
|
|
||||||
|
|
||||||
//ImGUI shader
|
|
||||||
imShader, err = shaders.NewShaderProgram()
|
|
||||||
if err != nil {
|
|
||||||
logging.ErrLog.Fatalln("Failed to create new shader program. Err: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
imguiVertShader, err := shaders.LoadAndCompilerShader("./res/shaders/imgui.vert.glsl", shaders.VertexShaderType)
|
|
||||||
if err != nil {
|
|
||||||
logging.ErrLog.Fatalln("Failed to create new shader. Err: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
imguiFragShader, err := shaders.LoadAndCompilerShader("./res/shaders/imgui.frag.glsl", shaders.FragmentShaderType)
|
|
||||||
if err != nil {
|
|
||||||
logging.ErrLog.Fatalln("Failed to create new shader. Err: ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
imShader.AttachShader(imguiVertShader)
|
|
||||||
imShader.AttachShader(imguiFragShader)
|
|
||||||
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() {
|
|
||||||
|
|
||||||
// scene, release, err := asig.ImportFile("./res/models/weird-cube.fbx", asig.PostProcessTriangulate)
|
|
||||||
scene, release, err := asig.ImportFile("./res/models/color-cube.fbx", asig.PostProcessTriangulate)
|
|
||||||
if err != nil {
|
|
||||||
logging.ErrLog.Panicln("Failed to load model. Err: " + err.Error())
|
|
||||||
}
|
|
||||||
release()
|
|
||||||
|
|
||||||
bo = buffers.NewBufferObject()
|
|
||||||
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() {
|
func initImGUI() {
|
||||||
@ -309,11 +169,11 @@ func initImGUI() {
|
|||||||
imIO.Fonts().SetTextureID(imgui.TextureID(imguiInfo.texID))
|
imIO.Fonts().SetTextureID(imgui.TextureID(imguiInfo.texID))
|
||||||
|
|
||||||
//Shader attributes
|
//Shader attributes
|
||||||
imShader.Activate()
|
imguiMat.Bind()
|
||||||
imShader.EnableAttribute("Position")
|
imguiMat.EnableAttribute("Position")
|
||||||
imShader.EnableAttribute("UV")
|
imguiMat.EnableAttribute("UV")
|
||||||
imShader.EnableAttribute("Color")
|
imguiMat.EnableAttribute("Color")
|
||||||
imShader.Deactivate()
|
imguiMat.UnBind()
|
||||||
|
|
||||||
//Init imgui input mapping
|
//Init imgui input mapping
|
||||||
keys := map[int]int{
|
keys := map[int]int{
|
||||||
@ -380,26 +240,12 @@ func handleInputs() {
|
|||||||
case *sdl.MouseMotionEvent:
|
case *sdl.MouseMotionEvent:
|
||||||
input.HandleMouseMotionEvent(e)
|
input.HandleMouseMotionEvent(e)
|
||||||
|
|
||||||
case *sdl.WindowEvent:
|
|
||||||
|
|
||||||
//NOTE: SDL is not firing window resize, but is resizing the window by itself
|
|
||||||
// if e.Type != sdl.WINDOWEVENT_SIZE_CHANGED {
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
|
|
||||||
// winWidth = e.Data1
|
|
||||||
// winHeight = e.Data2
|
|
||||||
// window.SetSize(int32(winWidth), int32(winHeight))
|
|
||||||
|
|
||||||
// projMat = gglm.Perspective(45*gglm.Deg2Rad, float32(winWidth)/float32(winHeight), 0.1, 20)
|
|
||||||
// simpleShader.SetUnifMat4("projMat", projMat)
|
|
||||||
|
|
||||||
case *sdl.QuitEvent:
|
case *sdl.QuitEvent:
|
||||||
isRunning = false
|
isRunning = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
currWinWidth, currWinHeight := window.GetSize()
|
currWinWidth, currWinHeight := window.SDLWin.GetSize()
|
||||||
if winWidth != currWinWidth || winHeight != currWinHeight {
|
if winWidth != currWinWidth || winHeight != currWinHeight {
|
||||||
handleWindowResize(currWinWidth, currWinHeight)
|
handleWindowResize(currWinWidth, currWinHeight)
|
||||||
}
|
}
|
||||||
@ -422,14 +268,14 @@ func handleWindowResize(newWinWidth, newWinHeight int32) {
|
|||||||
winWidth = newWinWidth
|
winWidth = newWinWidth
|
||||||
winHeight = newWinHeight
|
winHeight = newWinHeight
|
||||||
|
|
||||||
fbWidth, fbHeight := window.GLGetDrawableSize()
|
fbWidth, fbHeight := window.SDLWin.GLGetDrawableSize()
|
||||||
if fbWidth <= 0 || fbHeight <= 0 {
|
if fbWidth <= 0 || fbHeight <= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
gl.Viewport(0, 0, fbWidth, fbHeight)
|
gl.Viewport(0, 0, fbWidth, fbHeight)
|
||||||
|
|
||||||
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)
|
simpleMat.SetUnifMat4("projMat", projMat)
|
||||||
}
|
}
|
||||||
|
|
||||||
var time uint64 = 0
|
var time uint64 = 0
|
||||||
@ -443,7 +289,7 @@ var lightColor1 gglm.Vec3 = *gglm.NewVec3(1, 1, 1)
|
|||||||
|
|
||||||
func runGameLogic() {
|
func runGameLogic() {
|
||||||
|
|
||||||
var camSpeed float32 = 15.0
|
var camSpeed float32 = 15
|
||||||
if input.KeyDown(sdl.K_w) {
|
if input.KeyDown(sdl.K_w) {
|
||||||
camPos.Data[1] += camSpeed * timing.DT()
|
camPos.Data[1] += camSpeed * timing.DT()
|
||||||
updateViewMat()
|
updateViewMat()
|
||||||
@ -470,7 +316,7 @@ func runGameLogic() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
modelMat.Rotate(10*timing.DT()*gglm.Deg2Rad, gglm.NewVec3(1, 1, 1).Normalize())
|
modelMat.Rotate(10*timing.DT()*gglm.Deg2Rad, gglm.NewVec3(1, 1, 1).Normalize())
|
||||||
simpleShader.SetUnifMat4("modelMat", &modelMat.Mat4)
|
simpleMat.SetUnifMat4("modelMat", &modelMat.Mat4)
|
||||||
|
|
||||||
//ImGUI
|
//ImGUI
|
||||||
imIO := imgui.CurrentIO()
|
imIO := imgui.CurrentIO()
|
||||||
@ -489,19 +335,19 @@ func runGameLogic() {
|
|||||||
imgui.NewFrame()
|
imgui.NewFrame()
|
||||||
|
|
||||||
if imgui.SliderFloat3("Ambient Color", &ambientColor.Data, 0, 1) {
|
if imgui.SliderFloat3("Ambient Color", &ambientColor.Data, 0, 1) {
|
||||||
simpleShader.SetUnifVec3("ambientLightColor", &ambientColor)
|
simpleMat.SetUnifVec3("ambientLightColor", &ambientColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
if imgui.SliderFloat("Ambient Color Strength", &ambientColorStrength, 0, 1) {
|
if imgui.SliderFloat("Ambient Color Strength", &ambientColorStrength, 0, 1) {
|
||||||
simpleShader.SetUnifFloat32("ambientStrength", ambientColorStrength)
|
simpleMat.SetUnifFloat32("ambientStrength", ambientColorStrength)
|
||||||
}
|
}
|
||||||
|
|
||||||
if imgui.SliderFloat3("Light Pos 1", &lightPos1.Data, -10, 10) {
|
if imgui.SliderFloat3("Light Pos 1", &lightPos1.Data, -10, 10) {
|
||||||
simpleShader.SetUnifVec3("lightPos1", &lightPos1)
|
simpleMat.SetUnifVec3("lightPos1", &lightPos1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if imgui.SliderFloat3("Light Color 1", &lightColor1.Data, 0, 1) {
|
if imgui.SliderFloat3("Light Color 1", &lightColor1.Data, 0, 1) {
|
||||||
simpleShader.SetUnifVec3("lightColor1", &lightColor1)
|
simpleMat.SetUnifVec3("lightColor1", &lightColor1)
|
||||||
}
|
}
|
||||||
|
|
||||||
imgui.Render()
|
imgui.Render()
|
||||||
@ -509,38 +355,37 @@ func runGameLogic() {
|
|||||||
|
|
||||||
func draw() {
|
func draw() {
|
||||||
|
|
||||||
gl.Disable(gl.SCISSOR_TEST)
|
simpleMat.Bind()
|
||||||
gl.Enable(gl.CULL_FACE)
|
|
||||||
gl.Enable(gl.DEPTH_TEST)
|
|
||||||
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
|
||||||
|
|
||||||
simpleShader.Activate()
|
cubeMesh.BufObj.Bind()
|
||||||
|
|
||||||
//DRAW
|
|
||||||
bo.Activate()
|
|
||||||
tempModelMat := modelMat.Clone()
|
tempModelMat := modelMat.Clone()
|
||||||
|
|
||||||
rowSize := 10
|
rowSize := 10
|
||||||
for y := 0; y < rowSize; y++ {
|
for y := 0; y < rowSize; y++ {
|
||||||
for x := 0; x < rowSize; x++ {
|
for x := 0; x < rowSize; x++ {
|
||||||
simpleShader.SetUnifMat4("modelMat", &tempModelMat.Translate(gglm.NewVec3(-1, 0, 0)).Mat4)
|
simpleMat.SetUnifMat4("modelMat", &tempModelMat.Translate(gglm.NewVec3(-1, 0, 0)).Mat4)
|
||||||
gl.DrawElements(gl.TRIANGLES, int32(bo.IndexBuf.DataLen), gl.UNSIGNED_INT, gl.PtrOffset(0))
|
gl.DrawElements(gl.TRIANGLES, int32(cubeMesh.BufObj.IndexBuf.DataLen), gl.UNSIGNED_INT, gl.PtrOffset(0))
|
||||||
}
|
}
|
||||||
simpleShader.SetUnifMat4("modelMat", &tempModelMat.Translate(gglm.NewVec3(float32(rowSize), -1, 0)).Mat4)
|
simpleMat.SetUnifMat4("modelMat", &tempModelMat.Translate(gglm.NewVec3(float32(rowSize), -1, 0)).Mat4)
|
||||||
}
|
}
|
||||||
|
|
||||||
simpleShader.SetUnifMat4("modelMat", &modelMat.Mat4)
|
simpleMat.SetUnifMat4("modelMat", &modelMat.Mat4)
|
||||||
bo.Deactivate()
|
cubeMesh.BufObj.UnBind()
|
||||||
|
|
||||||
drawUI()
|
drawUI()
|
||||||
|
window.SDLWin.GLSwap()
|
||||||
|
|
||||||
window.GLSwap()
|
//Reset imgui changes before next draw
|
||||||
|
gl.Disable(gl.SCISSOR_TEST)
|
||||||
|
gl.Enable(gl.CULL_FACE)
|
||||||
|
gl.Enable(gl.DEPTH_TEST)
|
||||||
|
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
||||||
}
|
}
|
||||||
|
|
||||||
func drawUI() {
|
func drawUI() {
|
||||||
|
|
||||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||||
fbWidth, fbHeight := window.GLGetDrawableSize()
|
fbWidth, fbHeight := window.SDLWin.GLGetDrawableSize()
|
||||||
if fbWidth <= 0 || fbHeight <= 0 {
|
if fbWidth <= 0 || fbHeight <= 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -564,13 +409,13 @@ func drawUI() {
|
|||||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right).
|
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right).
|
||||||
// DisplayMin is typically (0,0) for single viewport apps.
|
// DisplayMin is typically (0,0) for single viewport apps.
|
||||||
|
|
||||||
imShader.Activate()
|
imguiMat.Bind()
|
||||||
|
|
||||||
gl.Uniform1i(gl.GetUniformLocation(imShader.ID, gl.Str("Texture\x00")), 0)
|
gl.Uniform1i(gl.GetUniformLocation(imguiMat.ShaderProg.ID, gl.Str("Texture\x00")), 0)
|
||||||
|
|
||||||
//PERF: only update the ortho matrix on window resize
|
//PERF: only update the ortho matrix on window resize
|
||||||
orthoMat := gglm.Ortho(0, float32(winWidth), 0, float32(winHeight), 0, 20)
|
orthoMat := gglm.Ortho(0, float32(winWidth), 0, float32(winHeight), 0, 20)
|
||||||
imShader.SetUnifMat4("ProjMtx", &orthoMat.Mat4)
|
imguiMat.SetUnifMat4("ProjMtx", &orthoMat.Mat4)
|
||||||
gl.BindSampler(0, 0) // Rely on combined texture/sampler state.
|
gl.BindSampler(0, 0) // Rely on combined texture/sampler state.
|
||||||
|
|
||||||
// Recreate the VAO every time
|
// Recreate the VAO every time
|
||||||
@ -580,12 +425,12 @@ func drawUI() {
|
|||||||
gl.BindBuffer(gl.ARRAY_BUFFER, imguiInfo.vboID)
|
gl.BindBuffer(gl.ARRAY_BUFFER, imguiInfo.vboID)
|
||||||
|
|
||||||
vertexSize, vertexOffsetPos, vertexOffsetUv, vertexOffsetCol := imgui.VertexBufferLayout()
|
vertexSize, vertexOffsetPos, vertexOffsetUv, vertexOffsetCol := imgui.VertexBufferLayout()
|
||||||
imShader.EnableAttribute("Position")
|
imguiMat.EnableAttribute("Position")
|
||||||
imShader.EnableAttribute("UV")
|
imguiMat.EnableAttribute("UV")
|
||||||
imShader.EnableAttribute("Color")
|
imguiMat.EnableAttribute("Color")
|
||||||
gl.VertexAttribPointerWithOffset(uint32(imShader.GetAttribLoc("Position")), 2, gl.FLOAT, false, int32(vertexSize), uintptr(vertexOffsetPos))
|
gl.VertexAttribPointerWithOffset(uint32(imguiMat.GetAttribLoc("Position")), 2, gl.FLOAT, false, int32(vertexSize), uintptr(vertexOffsetPos))
|
||||||
gl.VertexAttribPointerWithOffset(uint32(imShader.GetAttribLoc("UV")), 2, gl.FLOAT, false, int32(vertexSize), uintptr(vertexOffsetUv))
|
gl.VertexAttribPointerWithOffset(uint32(imguiMat.GetAttribLoc("UV")), 2, gl.FLOAT, false, int32(vertexSize), uintptr(vertexOffsetUv))
|
||||||
gl.VertexAttribPointerWithOffset(uint32(imShader.GetAttribLoc("Color")), 4, gl.UNSIGNED_BYTE, true, int32(vertexSize), uintptr(vertexOffsetCol))
|
gl.VertexAttribPointerWithOffset(uint32(imguiMat.GetAttribLoc("Color")), 4, gl.UNSIGNED_BYTE, true, int32(vertexSize), uintptr(vertexOffsetCol))
|
||||||
|
|
||||||
indexSize := imgui.IndexBufferLayout()
|
indexSize := imgui.IndexBufferLayout()
|
||||||
drawType := gl.UNSIGNED_SHORT
|
drawType := gl.UNSIGNED_SHORT
|
||||||
|
|||||||
109
materials/material.go
Executable file
109
materials/material.go
Executable file
@ -0,0 +1,109 @@
|
|||||||
|
package materials
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/bloeys/gglm/gglm"
|
||||||
|
"github.com/bloeys/nmage/buffers"
|
||||||
|
"github.com/bloeys/nmage/logging"
|
||||||
|
"github.com/bloeys/nmage/shaders"
|
||||||
|
"github.com/go-gl/gl/v4.1-core/gl"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Material struct {
|
||||||
|
Name string
|
||||||
|
ShaderProg shaders.ShaderProgram
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Material) Bind() {
|
||||||
|
gl.UseProgram(m.ShaderProg.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Material) UnBind() {
|
||||||
|
gl.UseProgram(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Material) GetAttribLoc(attribName string) int32 {
|
||||||
|
return gl.GetAttribLocation(m.ShaderProg.ID, gl.Str(attribName+"\x00"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Material) SetAttribute(attribName string, bufObj *buffers.BufferObject, buf *buffers.Buffer) {
|
||||||
|
|
||||||
|
bufObj.Bind()
|
||||||
|
buf.Activate()
|
||||||
|
|
||||||
|
attribLoc := m.GetAttribLoc(attribName)
|
||||||
|
gl.VertexAttribPointer(uint32(attribLoc), buf.ElementCount, buf.ElementType, false, buf.GetSize(), gl.PtrOffset(0))
|
||||||
|
|
||||||
|
bufObj.Bind()
|
||||||
|
buf.Deactivate()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Material) EnableAttribute(attribName string) {
|
||||||
|
gl.EnableVertexAttribArray(uint32(m.GetAttribLoc(attribName)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Material) DisableAttribute(attribName string) {
|
||||||
|
gl.DisableVertexAttribArray(uint32(m.GetAttribLoc(attribName)))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Material) SetUnifFloat32(uniformName string, val float32) {
|
||||||
|
loc := gl.GetUniformLocation(m.ShaderProg.ID, gl.Str(uniformName+"\x00"))
|
||||||
|
gl.ProgramUniform1f(m.ShaderProg.ID, loc, val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Material) SetUnifVec2(uniformName string, vec2 *gglm.Vec2) {
|
||||||
|
loc := gl.GetUniformLocation(m.ShaderProg.ID, gl.Str(uniformName+"\x00"))
|
||||||
|
gl.ProgramUniform2fv(m.ShaderProg.ID, loc, 1, &vec2.Data[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Material) SetUnifVec3(uniformName string, vec3 *gglm.Vec3) {
|
||||||
|
loc := gl.GetUniformLocation(m.ShaderProg.ID, gl.Str(uniformName+"\x00"))
|
||||||
|
gl.ProgramUniform3fv(m.ShaderProg.ID, loc, 1, &vec3.Data[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Material) SetUnifVec4(uniformName string, vec4 *gglm.Vec4) {
|
||||||
|
loc := gl.GetUniformLocation(m.ShaderProg.ID, gl.Str(uniformName+"\x00"))
|
||||||
|
gl.ProgramUniform4fv(m.ShaderProg.ID, loc, 1, &vec4.Data[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Material) SetUnifMat2(uniformName string, mat2 *gglm.Mat2) {
|
||||||
|
loc := gl.GetUniformLocation(m.ShaderProg.ID, gl.Str(uniformName+"\x00"))
|
||||||
|
gl.ProgramUniformMatrix2fv(m.ShaderProg.ID, loc, 1, false, &mat2.Data[0][0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Material) SetUnifMat3(uniformName string, mat3 *gglm.Mat3) {
|
||||||
|
loc := gl.GetUniformLocation(m.ShaderProg.ID, gl.Str(uniformName+"\x00"))
|
||||||
|
gl.ProgramUniformMatrix3fv(m.ShaderProg.ID, loc, 1, false, &mat3.Data[0][0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Material) SetUnifMat4(uniformName string, mat4 *gglm.Mat4) {
|
||||||
|
loc := gl.GetUniformLocation(m.ShaderProg.ID, gl.Str(uniformName+"\x00"))
|
||||||
|
gl.ProgramUniformMatrix4fv(m.ShaderProg.ID, loc, 1, false, &mat4.Data[0][0])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Material) Delete() {
|
||||||
|
gl.DeleteProgram(m.ShaderProg.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMaterial(matName, shaderPath string) *Material {
|
||||||
|
|
||||||
|
shdrProg, err := shaders.NewShaderProgram()
|
||||||
|
if err != nil {
|
||||||
|
logging.ErrLog.Fatalln("Failed to create new shader program. Err: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
vertShader, err := shaders.LoadAndCompilerShader(shaderPath+".vert.glsl", shaders.VertexShaderType)
|
||||||
|
if err != nil {
|
||||||
|
logging.ErrLog.Fatalln("Failed to load and create vertex shader. Err: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fragShader, err := shaders.LoadAndCompilerShader(shaderPath+".frag.glsl", shaders.FragmentShaderType)
|
||||||
|
if err != nil {
|
||||||
|
logging.ErrLog.Fatalln("Failed to load and create fragment shader. Err: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
shdrProg.AttachShader(vertShader)
|
||||||
|
shdrProg.AttachShader(fragShader)
|
||||||
|
shdrProg.Link()
|
||||||
|
|
||||||
|
return &Material{Name: matName, ShaderProg: shdrProg}
|
||||||
|
}
|
||||||
81
meshes/mesh.go
Executable file
81
meshes/mesh.go
Executable file
@ -0,0 +1,81 @@
|
|||||||
|
package meshes
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/bloeys/assimp-go/asig"
|
||||||
|
"github.com/bloeys/gglm/gglm"
|
||||||
|
"github.com/bloeys/nmage/asserts"
|
||||||
|
"github.com/bloeys/nmage/buffers"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Mesh struct {
|
||||||
|
Name string
|
||||||
|
BufObj *buffers.BufferObject
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMesh(name, modelPath string, postProcessFlags asig.PostProcess) (*Mesh, error) {
|
||||||
|
|
||||||
|
scene, release, err := asig.ImportFile(modelPath, asig.PostProcessTriangulate|postProcessFlags)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.New("Failed to load model. Err: " + err.Error())
|
||||||
|
}
|
||||||
|
defer release()
|
||||||
|
|
||||||
|
if len(scene.Meshes) == 0 {
|
||||||
|
return nil, errors.New("No meshes found in file: " + modelPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh := &Mesh{Name: name, BufObj: buffers.NewBufferObject()}
|
||||||
|
|
||||||
|
sceneMesh := scene.Meshes[0]
|
||||||
|
mesh.BufObj.GenBuffer(flattenVec3(sceneMesh.Normals), buffers.BufUsageStatic, buffers.BufTypeNormal, buffers.DataTypeVec3)
|
||||||
|
mesh.BufObj.GenBuffer(flattenVec3(sceneMesh.Vertices), buffers.BufUsageStatic, buffers.BufTypeVertPos, buffers.DataTypeVec3)
|
||||||
|
mesh.BufObj.GenBufferUint32(flattenFaces(sceneMesh.Faces), buffers.BufUsageStatic, buffers.BufTypeIndex, buffers.DataTypeUint32)
|
||||||
|
|
||||||
|
if len(sceneMesh.ColorSets) > 0 {
|
||||||
|
mesh.BufObj.GenBuffer(flattenVec4(sceneMesh.ColorSets[0]), buffers.BufUsageStatic, buffers.BufTypeColor, buffers.DataTypeVec4)
|
||||||
|
}
|
||||||
|
|
||||||
|
return mesh, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
@ -1,8 +1,6 @@
|
|||||||
package shaders
|
package shaders
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/bloeys/gglm/gglm"
|
|
||||||
"github.com/bloeys/nmage/buffers"
|
|
||||||
"github.com/bloeys/nmage/logging"
|
"github.com/bloeys/nmage/logging"
|
||||||
"github.com/go-gl/gl/v4.1-core/gl"
|
"github.com/go-gl/gl/v4.1-core/gl"
|
||||||
)
|
)
|
||||||
@ -37,74 +35,3 @@ func (sp *ShaderProgram) Link() {
|
|||||||
gl.DeleteShader(sp.FragShaderID)
|
gl.DeleteShader(sp.FragShaderID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sp *ShaderProgram) Activate() {
|
|
||||||
gl.UseProgram(sp.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *ShaderProgram) Deactivate() {
|
|
||||||
gl.UseProgram(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *ShaderProgram) GetAttribLoc(attribName string) int32 {
|
|
||||||
return gl.GetAttribLocation(sp.ID, gl.Str(attribName+"\x00"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *ShaderProgram) SetAttribute(attribName string, bufObj *buffers.BufferObject, buf *buffers.Buffer) {
|
|
||||||
|
|
||||||
bufObj.Activate()
|
|
||||||
buf.Activate()
|
|
||||||
|
|
||||||
attribLoc := sp.GetAttribLoc(attribName)
|
|
||||||
gl.VertexAttribPointer(uint32(attribLoc), buf.ElementCount, buf.ElementType, false, buf.GetSize(), gl.PtrOffset(0))
|
|
||||||
|
|
||||||
bufObj.Activate()
|
|
||||||
buf.Deactivate()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *ShaderProgram) EnableAttribute(attribName string) {
|
|
||||||
gl.EnableVertexAttribArray(uint32(sp.GetAttribLoc(attribName)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *ShaderProgram) DisableAttribute(attribName string) {
|
|
||||||
gl.DisableVertexAttribArray(uint32(sp.GetAttribLoc(attribName)))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *ShaderProgram) SetUnifFloat32(uniformName string, val float32) {
|
|
||||||
loc := gl.GetUniformLocation(sp.ID, gl.Str(uniformName+"\x00"))
|
|
||||||
gl.ProgramUniform1f(sp.ID, loc, val)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *ShaderProgram) SetUnifVec2(uniformName string, vec2 *gglm.Vec2) {
|
|
||||||
loc := gl.GetUniformLocation(sp.ID, gl.Str(uniformName+"\x00"))
|
|
||||||
gl.ProgramUniform2fv(sp.ID, loc, 1, &vec2.Data[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *ShaderProgram) SetUnifVec3(uniformName string, vec3 *gglm.Vec3) {
|
|
||||||
loc := gl.GetUniformLocation(sp.ID, gl.Str(uniformName+"\x00"))
|
|
||||||
gl.ProgramUniform3fv(sp.ID, loc, 1, &vec3.Data[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *ShaderProgram) SetUnifVec4(uniformName string, vec4 *gglm.Vec4) {
|
|
||||||
loc := gl.GetUniformLocation(sp.ID, gl.Str(uniformName+"\x00"))
|
|
||||||
gl.ProgramUniform4fv(sp.ID, loc, 1, &vec4.Data[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *ShaderProgram) SetUnifMat2(uniformName string, mat2 *gglm.Mat2) {
|
|
||||||
loc := gl.GetUniformLocation(sp.ID, gl.Str(uniformName+"\x00"))
|
|
||||||
gl.ProgramUniformMatrix2fv(sp.ID, loc, 1, false, &mat2.Data[0][0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *ShaderProgram) SetUnifMat3(uniformName string, mat3 *gglm.Mat3) {
|
|
||||||
loc := gl.GetUniformLocation(sp.ID, gl.Str(uniformName+"\x00"))
|
|
||||||
gl.ProgramUniformMatrix3fv(sp.ID, loc, 1, false, &mat3.Data[0][0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *ShaderProgram) SetUnifMat4(uniformName string, mat4 *gglm.Mat4) {
|
|
||||||
loc := gl.GetUniformLocation(sp.ID, gl.Str(uniformName+"\x00"))
|
|
||||||
gl.ProgramUniformMatrix4fv(sp.ID, loc, 1, false, &mat4.Data[0][0])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (sp *ShaderProgram) Delete() {
|
|
||||||
gl.DeleteProgram(sp.ID)
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user