mirror of
https://github.com/bloeys/nmage.git
synced 2025-12-29 13:28:20 +00:00
Switch to opengl rendering
This commit is contained in:
2
go.mod
2
go.mod
@ -3,3 +3,5 @@ module github.com/bloeys/go-sdl-engine
|
|||||||
go 1.17
|
go 1.17
|
||||||
|
|
||||||
require github.com/veandco/go-sdl2 v0.4.10
|
require github.com/veandco/go-sdl2 v0.4.10
|
||||||
|
|
||||||
|
require github.com/go-gl/gl v0.0.0-20210905235341-f7a045908259
|
||||||
|
|||||||
2
go.sum
2
go.sum
@ -1,2 +1,4 @@
|
|||||||
|
github.com/go-gl/gl v0.0.0-20210905235341-f7a045908259 h1:8q7+xl2D2qHPLTII1t4vSMNP2VKwDcn+Avf2WXvdB1A=
|
||||||
|
github.com/go-gl/gl v0.0.0-20210905235341-f7a045908259/go.mod h1:wjpnOv6ONl2SuJSxqCPVaPZibGFdSci9HFocT9qtVYM=
|
||||||
github.com/veandco/go-sdl2 v0.4.10 h1:8QoD2bhWl7SbQDflIAUYWfl9Vq+mT8/boJFAUzAScgY=
|
github.com/veandco/go-sdl2 v0.4.10 h1:8QoD2bhWl7SbQDflIAUYWfl9Vq+mT8/boJFAUzAScgY=
|
||||||
github.com/veandco/go-sdl2 v0.4.10/go.mod h1:OROqMhHD43nT4/i9crJukyVecjPNYYuCofep6SNiAjY=
|
github.com/veandco/go-sdl2 v0.4.10/go.mod h1:OROqMhHD43nT4/i9crJukyVecjPNYYuCofep6SNiAjY=
|
||||||
|
|||||||
135
main.go
135
main.go
@ -2,19 +2,21 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
|
|
||||||
|
"github.com/bloeys/go-sdl-engine/timing"
|
||||||
|
"github.com/go-gl/gl/v4.6-compatibility/gl"
|
||||||
"github.com/veandco/go-sdl2/sdl"
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
winWidth int32 = 800
|
winWidth int32 = 1280
|
||||||
winHeight int32 = 600
|
winHeight int32 = 720
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
isRunning = true
|
isRunning = true
|
||||||
window *sdl.Window
|
window *sdl.Window
|
||||||
|
glContext sdl.GLContext
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -25,69 +27,90 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer sdl.Quit()
|
defer sdl.Quit()
|
||||||
|
|
||||||
|
//Size of each pixel field
|
||||||
|
err = sdl.GLSetAttribute(sdl.GL_RED_SIZE, 8)
|
||||||
|
panicIfErr(err, "")
|
||||||
|
|
||||||
|
err = sdl.GLSetAttribute(sdl.GL_GREEN_SIZE, 8)
|
||||||
|
panicIfErr(err, "")
|
||||||
|
|
||||||
|
err = sdl.GLSetAttribute(sdl.GL_BLUE_SIZE, 8)
|
||||||
|
panicIfErr(err, "")
|
||||||
|
|
||||||
|
err = sdl.GLSetAttribute(sdl.GL_ALPHA_SIZE, 8)
|
||||||
|
panicIfErr(err, "")
|
||||||
|
|
||||||
|
//Min frame buffer size
|
||||||
|
err = sdl.GLSetAttribute(sdl.GL_BUFFER_SIZE, 4*8)
|
||||||
|
panicIfErr(err, "")
|
||||||
|
|
||||||
|
//Whether to enable a double buffer
|
||||||
|
err = sdl.GLSetAttribute(sdl.GL_DOUBLEBUFFER, 1)
|
||||||
|
panicIfErr(err, "")
|
||||||
|
|
||||||
|
//Run in compatiability (old and modern opengl) or modern (core) opengl only
|
||||||
|
// sdl.GLSetAttribute(sdl.GL_CONTEXT_PROFILE_MASK, sdl.GL_CONTEXT_PROFILE_CORE)
|
||||||
|
err = sdl.GLSetAttribute(sdl.GL_CONTEXT_PROFILE_MASK, sdl.GL_CONTEXT_PROFILE_COMPATIBILITY)
|
||||||
|
panicIfErr(err, "")
|
||||||
|
|
||||||
|
//Set wanted opengl version
|
||||||
|
err = sdl.GLSetAttribute(sdl.GL_CONTEXT_MAJOR_VERSION, 4)
|
||||||
|
panicIfErr(err, "")
|
||||||
|
|
||||||
|
err = sdl.GLSetAttribute(sdl.GL_CONTEXT_MINOR_VERSION, 6)
|
||||||
|
panicIfErr(err, "")
|
||||||
|
|
||||||
|
//Create window
|
||||||
window, err = sdl.CreateWindow(
|
window, err = sdl.CreateWindow(
|
||||||
"test",
|
"Go Game Engine",
|
||||||
sdl.WINDOWPOS_CENTERED,
|
sdl.WINDOWPOS_CENTERED,
|
||||||
sdl.WINDOWPOS_CENTERED,
|
sdl.WINDOWPOS_CENTERED,
|
||||||
winWidth,
|
winWidth,
|
||||||
winHeight,
|
winHeight,
|
||||||
sdl.WINDOW_SHOWN)
|
sdl.WINDOW_OPENGL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("Failed to create window. Err: " + err.Error())
|
panic("Failed to create window. Err: " + err.Error())
|
||||||
}
|
}
|
||||||
defer window.Destroy()
|
defer window.Destroy()
|
||||||
|
|
||||||
rend, err := sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED)
|
//Create GL context
|
||||||
|
glContext, err = window.GLCreateContext()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("Creating renderer failed. Err: " + err.Error())
|
panic("Creating OpenGL context failed. Err: " + err.Error())
|
||||||
}
|
}
|
||||||
defer rend.Destroy()
|
defer sdl.GLDeleteContext(glContext)
|
||||||
|
|
||||||
tex, err := rend.CreateTexture(sdl.PIXELFORMAT_ABGR8888, 0, winWidth, winHeight)
|
if err := gl.Init(); err != nil {
|
||||||
if err != nil {
|
panic("Initing OpenGL Context failed. Err: " + err.Error())
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//x4 to allow for RGBA
|
initGL()
|
||||||
pixels := make([]byte, winHeight*winWidth*4)
|
gameLoop()
|
||||||
for y := 0; y < int(winHeight); y++ {
|
}
|
||||||
for x := 0; x < int(winWidth); x++ {
|
|
||||||
|
|
||||||
c := sdl.Color{
|
func initGL() {
|
||||||
R: byte(int(float64(x)/float64(winWidth)*256) % 256),
|
|
||||||
G: byte(int(float64(y)/float64(winHeight)*256) % 256),
|
|
||||||
}
|
|
||||||
|
|
||||||
setPixel(x, y, c, pixels)
|
gl.ClearColor(0, 0, 0, 0)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Update texture with new pixel values
|
gl.Enable(gl.DEPTH_TEST)
|
||||||
tex.Update(nil, pixels, int(winWidth)*4)
|
gl.ClearDepth(1)
|
||||||
//Copy texture to renderer
|
gl.DepthFunc(gl.LEQUAL)
|
||||||
rend.Copy(tex, nil, nil)
|
gl.Viewport(0, 0, winWidth, winHeight)
|
||||||
//Blit
|
}
|
||||||
rend.Present()
|
|
||||||
|
func gameLoop() {
|
||||||
|
|
||||||
var fps float32 = 60
|
|
||||||
var dt float32 = 1.0 / 60.0
|
|
||||||
var dtLimit float32 = 1.0 / 120.0
|
|
||||||
for isRunning {
|
for isRunning {
|
||||||
|
|
||||||
frameStartTime := time.Now()
|
timing.FrameStarted()
|
||||||
|
|
||||||
handleEvents()
|
handleEvents()
|
||||||
|
draw()
|
||||||
|
|
||||||
//If FPS is more than 120 then limit to that
|
window.GLSwap()
|
||||||
dt = float32(time.Since(frameStartTime).Seconds())
|
|
||||||
if dt < dtLimit {
|
|
||||||
sdl.Delay(8 - uint32(dt*1000))
|
|
||||||
dt = float32(time.Since(frameStartTime).Seconds())
|
|
||||||
}
|
|
||||||
|
|
||||||
//Display FPS is the average of the FPS of this frame and the last frame
|
timing.FrameEnded()
|
||||||
fps = (fps + 1/dt) / 2
|
window.SetTitle(fmt.Sprintf("FPS: %.2f; dt: %.3f", timing.FPS(), timing.DT()))
|
||||||
window.SetTitle(fmt.Sprintf("FPS: %.2f; dt: %.3f", fps, dt))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,12 +127,28 @@ func handleEvents() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//handleEvents assumes sdl.PIXELFORMAT_ABGR8888
|
func draw() {
|
||||||
func setPixel(x, y int, c sdl.Color, pixels []byte) {
|
//Clear screen and depth buffers
|
||||||
|
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
|
||||||
|
|
||||||
index := (y*int(winWidth) + x) * 4
|
gl.Begin(gl.TRIANGLES)
|
||||||
pixels[index] = c.R
|
|
||||||
pixels[index+1] = c.G
|
gl.Color3f(1, 0, 0)
|
||||||
pixels[index+2] = c.B
|
gl.Vertex3f(0, 0.5, 0)
|
||||||
pixels[index+3] = c.A
|
|
||||||
|
gl.Color3f(1, 0, 0)
|
||||||
|
gl.Vertex3f(0.5, 0, 0)
|
||||||
|
|
||||||
|
gl.Color3f(1, 0, 0)
|
||||||
|
gl.Vertex3f(-0.5, 0, 0)
|
||||||
|
gl.End()
|
||||||
|
}
|
||||||
|
|
||||||
|
func panicIfErr(err error, msg string) {
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
panic(msg + "; Err: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|||||||
41
timing/timing.go
Executable file
41
timing/timing.go
Executable file
@ -0,0 +1,41 @@
|
|||||||
|
package timing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
fps float32 = 60
|
||||||
|
dt float32 = 1.0 / 60.0
|
||||||
|
dtLimit float32 = 1.0 / 120.0
|
||||||
|
frameStartTime time.Time = time.Now()
|
||||||
|
)
|
||||||
|
|
||||||
|
func FrameStarted() {
|
||||||
|
frameStartTime = time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
|
func FrameEnded() {
|
||||||
|
|
||||||
|
//If FPS is more than 120 then limit to that
|
||||||
|
dt = float32(time.Since(frameStartTime).Seconds())
|
||||||
|
if dt < dtLimit {
|
||||||
|
sdl.Delay(8 - uint32(dt*1000))
|
||||||
|
dt = float32(time.Since(frameStartTime).Seconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
//Display FPS is the average of the FPS of this frame and the last frame
|
||||||
|
fps = (fps + 1/dt) / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
//DT returns last frame delta time (number of seconds frame took)
|
||||||
|
func DT() float32 {
|
||||||
|
return dt
|
||||||
|
}
|
||||||
|
|
||||||
|
//FPS returns fps
|
||||||
|
func FPS() float32 {
|
||||||
|
return fps
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user