mirror of
https://github.com/bloeys/nmage.git
synced 2025-12-29 05:18:21 +00:00
Day7: ImGUI interaction+OpenGL 4.1+Bugs+ambient color control
This commit is contained in:
@ -2,7 +2,7 @@ package buffers
|
||||
|
||||
import (
|
||||
"github.com/bloeys/go-sdl-engine/logging"
|
||||
"github.com/go-gl/gl/v4.6-core/gl"
|
||||
"github.com/go-gl/gl/v4.1-core/gl"
|
||||
)
|
||||
|
||||
type BufGLType int
|
||||
@ -78,7 +78,7 @@ func (bo *BufferObject) GenBuffer(data []float32, bufUsage BufUsage, bufType Buf
|
||||
|
||||
//Create vertex buffer object
|
||||
var vboID uint32
|
||||
gl.CreateBuffers(1, &vboID)
|
||||
gl.GenBuffers(1, &vboID)
|
||||
if vboID == 0 {
|
||||
logging.ErrLog.Println("Failed to create openGL buffer")
|
||||
}
|
||||
@ -106,7 +106,7 @@ func (bo *BufferObject) GenBufferUint32(data []uint32, bufUsage BufUsage, bufTyp
|
||||
|
||||
//Create vertex buffer object
|
||||
var vboID uint32
|
||||
gl.CreateBuffers(1, &vboID)
|
||||
gl.GenBuffers(1, &vboID)
|
||||
if vboID == 0 {
|
||||
logging.ErrLog.Println("Failed to create openGL buffer")
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ package buffers
|
||||
|
||||
import (
|
||||
"github.com/bloeys/go-sdl-engine/logging"
|
||||
"github.com/go-gl/gl/v4.6-core/gl"
|
||||
"github.com/go-gl/gl/v4.1-core/gl"
|
||||
)
|
||||
|
||||
type DataType int
|
||||
|
||||
188
main.go
188
main.go
@ -1,22 +1,21 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/bloeys/gglm/gglm"
|
||||
"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.6-core/gl"
|
||||
"github.com/go-gl/gl/v4.1-core/gl"
|
||||
"github.com/inkyblackness/imgui-go/v4"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
)
|
||||
|
||||
//TODO:
|
||||
//Resizeable window - Done
|
||||
//Moving camera - Done
|
||||
//FIX Ortho function
|
||||
//ImGUI integration
|
||||
//Abstract UI
|
||||
//Asset loading
|
||||
//Rework buffers package
|
||||
//Interleaved or packed buffers (xyzxyzxyz OR xxxyyyzzz)
|
||||
@ -50,7 +49,9 @@ var (
|
||||
|
||||
func main() {
|
||||
|
||||
err := sdl.Init(sdl.INIT_EVERYTHING)
|
||||
runtime.LockOSThread()
|
||||
|
||||
err := initSDL()
|
||||
if err != nil {
|
||||
logging.ErrLog.Fatalln("Failed to init SDL. Err:", err)
|
||||
}
|
||||
@ -67,7 +68,11 @@ func main() {
|
||||
}
|
||||
defer sdl.GLDeleteContext(glCtx)
|
||||
|
||||
initOpenGL()
|
||||
err = initOpenGL()
|
||||
if err != nil {
|
||||
logging.ErrLog.Fatalln(err)
|
||||
}
|
||||
|
||||
loadShaders()
|
||||
loadBuffers()
|
||||
initImGUI()
|
||||
@ -107,14 +112,15 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func initOpenGL() {
|
||||
func initSDL() error {
|
||||
|
||||
if err := gl.Init(); err != nil {
|
||||
logging.ErrLog.Fatalln(err)
|
||||
err := sdl.Init(sdl.INIT_EVERYTHING)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sdl.GLSetAttribute(sdl.MAJOR_VERSION, 4)
|
||||
sdl.GLSetAttribute(sdl.MINOR_VERSION, 6)
|
||||
sdl.GLSetAttribute(sdl.MINOR_VERSION, 1)
|
||||
|
||||
// R(0-255) G(0-255) B(0-255)
|
||||
sdl.GLSetAttribute(sdl.GL_RED_SIZE, 8)
|
||||
@ -125,8 +131,19 @@ func initOpenGL() {
|
||||
sdl.GLSetAttribute(sdl.GL_DEPTH_SIZE, 24)
|
||||
sdl.GLSetAttribute(sdl.GL_STENCIL_SIZE, 8)
|
||||
|
||||
gl.ClearColor(0, 0, 0, 1)
|
||||
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.ClearColor(0, 0, 0, 1)
|
||||
return nil
|
||||
}
|
||||
|
||||
func loadShaders() {
|
||||
@ -236,40 +253,135 @@ func initImGUI() {
|
||||
imShader.EnableAttribute("UV")
|
||||
imShader.EnableAttribute("Color")
|
||||
imShader.Deactivate()
|
||||
|
||||
//Init imgui input mapping
|
||||
keys := map[int]int{
|
||||
imgui.KeyTab: sdl.SCANCODE_TAB,
|
||||
imgui.KeyLeftArrow: sdl.SCANCODE_LEFT,
|
||||
imgui.KeyRightArrow: sdl.SCANCODE_RIGHT,
|
||||
imgui.KeyUpArrow: sdl.SCANCODE_UP,
|
||||
imgui.KeyDownArrow: sdl.SCANCODE_DOWN,
|
||||
imgui.KeyPageUp: sdl.SCANCODE_PAGEUP,
|
||||
imgui.KeyPageDown: sdl.SCANCODE_PAGEDOWN,
|
||||
imgui.KeyHome: sdl.SCANCODE_HOME,
|
||||
imgui.KeyEnd: sdl.SCANCODE_END,
|
||||
imgui.KeyInsert: sdl.SCANCODE_INSERT,
|
||||
imgui.KeyDelete: sdl.SCANCODE_DELETE,
|
||||
imgui.KeyBackspace: sdl.SCANCODE_BACKSPACE,
|
||||
imgui.KeySpace: sdl.SCANCODE_BACKSPACE,
|
||||
imgui.KeyEnter: sdl.SCANCODE_RETURN,
|
||||
imgui.KeyEscape: sdl.SCANCODE_ESCAPE,
|
||||
imgui.KeyA: sdl.SCANCODE_A,
|
||||
imgui.KeyC: sdl.SCANCODE_C,
|
||||
imgui.KeyV: sdl.SCANCODE_V,
|
||||
imgui.KeyX: sdl.SCANCODE_X,
|
||||
imgui.KeyY: sdl.SCANCODE_Y,
|
||||
imgui.KeyZ: sdl.SCANCODE_Z,
|
||||
}
|
||||
|
||||
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array.
|
||||
for imguiKey, nativeKey := range keys {
|
||||
imIO.KeyMap(imguiKey, nativeKey)
|
||||
}
|
||||
}
|
||||
|
||||
func handleInputs() {
|
||||
|
||||
input.EventLoopStart()
|
||||
imIO := imgui.CurrentIO()
|
||||
|
||||
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
|
||||
|
||||
switch e := event.(type) {
|
||||
|
||||
case *sdl.KeyboardEvent:
|
||||
input.HandleKeyboardEvent(e)
|
||||
case *sdl.MouseButtonEvent:
|
||||
input.HandleMouseEvent(e)
|
||||
case *sdl.WindowEvent:
|
||||
case *sdl.MouseWheelEvent:
|
||||
|
||||
if e.Type != sdl.WINDOWEVENT_RESIZED {
|
||||
continue
|
||||
var deltaX, deltaY float32
|
||||
if e.X > 0 {
|
||||
deltaX++
|
||||
} else if e.X < 0 {
|
||||
deltaX--
|
||||
}
|
||||
|
||||
winWidth = e.Data1
|
||||
winHeight = e.Data2
|
||||
window.SetSize(int32(winWidth), int32(winHeight))
|
||||
if e.Y > 0 {
|
||||
deltaY++
|
||||
} else if e.Y < 0 {
|
||||
deltaY--
|
||||
}
|
||||
|
||||
projMat = gglm.Perspective(45*gglm.Deg2Rad, float32(winWidth)/float32(winHeight), 0.1, 20)
|
||||
simpleShader.SetUnifMat4("projMat", projMat)
|
||||
imIO.AddMouseWheelDelta(deltaX, deltaY)
|
||||
|
||||
case *sdl.KeyboardEvent:
|
||||
input.HandleKeyboardEvent(e)
|
||||
|
||||
if e.Type == sdl.KEYDOWN {
|
||||
imIO.KeyPress(int(e.Keysym.Scancode))
|
||||
} else if e.Type == sdl.KEYUP {
|
||||
imIO.KeyRelease(int(e.Keysym.Scancode))
|
||||
}
|
||||
|
||||
case *sdl.TextInputEvent:
|
||||
imIO.AddInputCharacters(string(e.Text[:]))
|
||||
|
||||
case *sdl.MouseButtonEvent:
|
||||
input.HandleMouseEvent(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:
|
||||
isRunning = false
|
||||
}
|
||||
}
|
||||
|
||||
currWinWidth, currWinHeight := window.GetSize()
|
||||
if winWidth != currWinWidth || winHeight != currWinHeight {
|
||||
handleWindowResize(currWinWidth, currWinHeight)
|
||||
}
|
||||
|
||||
// If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
|
||||
x, y, _ := sdl.GetMouseState()
|
||||
imIO.SetMousePosition(imgui.Vec2{X: float32(x), Y: float32(y)})
|
||||
|
||||
imIO.SetMouseButtonDown(0, input.MouseDown(sdl.BUTTON_LEFT))
|
||||
imIO.SetMouseButtonDown(1, input.MouseDown(sdl.BUTTON_RIGHT))
|
||||
imIO.SetMouseButtonDown(2, input.MouseDown(sdl.BUTTON_MIDDLE))
|
||||
|
||||
imIO.KeyShift(sdl.SCANCODE_LSHIFT, sdl.SCANCODE_RSHIFT)
|
||||
imIO.KeyCtrl(sdl.SCANCODE_LCTRL, sdl.SCANCODE_RCTRL)
|
||||
imIO.KeyAlt(sdl.SCANCODE_LALT, sdl.SCANCODE_RALT)
|
||||
}
|
||||
|
||||
func handleWindowResize(newWinWidth, newWinHeight int32) {
|
||||
|
||||
winWidth = newWinWidth
|
||||
winHeight = newWinHeight
|
||||
|
||||
fbWidth, fbHeight := window.GLGetDrawableSize()
|
||||
if fbWidth <= 0 || fbHeight <= 0 {
|
||||
return
|
||||
}
|
||||
gl.Viewport(0, 0, fbWidth, fbHeight)
|
||||
|
||||
projMat = gglm.Perspective(45*gglm.Deg2Rad, float32(winWidth)/float32(winHeight), 0.1, 20)
|
||||
simpleShader.SetUnifMat4("projMat", projMat)
|
||||
}
|
||||
|
||||
var time uint64 = 0
|
||||
var name string = ""
|
||||
|
||||
var ambientColor gglm.Vec3
|
||||
var ambientColorStrength float32 = 1
|
||||
|
||||
func runGameLogic() {
|
||||
|
||||
@ -303,13 +415,19 @@ func runGameLogic() {
|
||||
time = currentTime
|
||||
|
||||
imgui.NewFrame()
|
||||
|
||||
if imgui.Button("Click Me!") {
|
||||
logging.InfoLog.Println("Clicked!")
|
||||
}
|
||||
imgui.InputText("Name", &name)
|
||||
|
||||
if imgui.SliderFloat3("Ambient Color", &ambientColor.Data, 0, 1) {
|
||||
simpleShader.SetUnifVec3("ambientLightColor", &ambientColor)
|
||||
}
|
||||
|
||||
if imgui.SliderFloat("Ambient Color Strength", &ambientColorStrength, 0, 1) {
|
||||
simpleShader.SetUnifFloat32("ambientStrength", ambientColorStrength)
|
||||
}
|
||||
|
||||
// open := true
|
||||
// imgui.ShowDemoWindow(&open)
|
||||
imgui.Render()
|
||||
}
|
||||
|
||||
@ -337,7 +455,7 @@ func drawUI() {
|
||||
if fbWidth <= 0 || fbHeight <= 0 {
|
||||
return
|
||||
}
|
||||
gl.Viewport(0, 0, fbWidth, fbHeight)
|
||||
|
||||
drawData := imgui.RenderedDrawData()
|
||||
drawData.ScaleClipRects(imgui.Vec2{
|
||||
X: float32(fbWidth) / float32(winWidth),
|
||||
@ -356,20 +474,14 @@ func drawUI() {
|
||||
// Setup viewport, orthographic projection matrix
|
||||
// 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.
|
||||
orthoProjection := [4][4]float32{
|
||||
{2.0 / float32(winWidth), 0.0, 0.0, 0.0},
|
||||
{0.0, 2.0 / -float32(winHeight), 0.0, 0.0},
|
||||
{0.0, 0.0, -1.0, 0.0},
|
||||
{-1.0, 1.0, 0.0, 1.0},
|
||||
}
|
||||
|
||||
imShader.Activate()
|
||||
|
||||
gl.Uniform1i(gl.GetUniformLocation(imShader.ID, gl.Str("Texture\x00")), 0)
|
||||
|
||||
gl.UniformMatrix4fv(gl.GetUniformLocation(imShader.ID, gl.Str("ProjMtx"+"\x00")), 1, false, &orthoProjection[0][0])
|
||||
// orthoMat := gglm.Ortho(0, float32(winWidth), float32(winHeight), 0, 0.1, 20)
|
||||
// imShader.SetUnifMat4("ProjMtx", &orthoMat.Mat4)
|
||||
//PERF: only update the ortho matrix on window resize
|
||||
orthoMat := gglm.Ortho(0, float32(winWidth), 0, float32(winHeight), 0, 20)
|
||||
imShader.SetUnifMat4("ProjMtx", &orthoMat.Mat4)
|
||||
gl.BindSampler(0, 0) // Rely on combined texture/sampler state.
|
||||
|
||||
// Recreate the VAO every time
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#version 460
|
||||
#version 410
|
||||
|
||||
uniform sampler2D Texture;
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#version 460
|
||||
#version 410
|
||||
|
||||
uniform mat4 ProjMtx;
|
||||
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
#version 460
|
||||
#version 410
|
||||
|
||||
in vec3 outColor;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform vec3 ambientLightColor = vec3(1, 0, 0);
|
||||
uniform float ambientStrength = 1;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragColor = vec4(1,1,1, 1.0);
|
||||
// fragColor = vec4(outColor, 1.0);
|
||||
vec3 objColor = vec3(1, 1, 1);
|
||||
fragColor = vec4(objColor * ambientLightColor * ambientStrength, 1.0);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#version 460
|
||||
#version 410
|
||||
|
||||
in vec3 vertPos;
|
||||
in vec3 vertColor;
|
||||
|
||||
@ -4,7 +4,7 @@ import (
|
||||
"github.com/bloeys/gglm/gglm"
|
||||
"github.com/bloeys/go-sdl-engine/buffers"
|
||||
"github.com/bloeys/go-sdl-engine/logging"
|
||||
"github.com/go-gl/gl/v4.6-core/gl"
|
||||
"github.com/go-gl/gl/v4.1-core/gl"
|
||||
)
|
||||
|
||||
type ShaderProgram struct {
|
||||
@ -70,6 +70,11 @@ 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])
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
package shaders
|
||||
|
||||
import "github.com/go-gl/gl/v4.6-core/gl"
|
||||
import "github.com/go-gl/gl/v4.1-core/gl"
|
||||
|
||||
type ShaderType int
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/bloeys/go-sdl-engine/logging"
|
||||
"github.com/go-gl/gl/v4.6-core/gl"
|
||||
"github.com/go-gl/gl/v4.1-core/gl"
|
||||
)
|
||||
|
||||
type Shader struct {
|
||||
|
||||
Reference in New Issue
Block a user