package main
import (
"fmt"
"github.com/banthar/Go-SDL/sdl"
"github.com/banthar/gl"
"math"
"os"
)
const (
SCREEN_WIDTH = 1366
SCREEN_HEIGHT = 768
SCREEN_BPP = 32
)
var (
surface *sdl.Surface
)
// release/destroy our resources and restoring the old desktop
func Quit(status int) {
// clean up the window
sdl.Quit()
// and exit appropriately
os.Exit(status)
}
// reset our viewport after a window resize
func resizeWindow(width, height int) {
// protect against a divide by zero
if height == 0 {
height = 1
}
// Setup our viewport
gl.Viewport(0, 0, width, height)
// change to the projection matrix and set our viewing volume.
gl.MatrixMode(gl.PROJECTION)
gl.LoadIdentity()
// aspect ratio
aspect := gl.GLdouble(width / height)
// Set our perspective.
// This code is equivalent to using gluPerspective as in the original tutorial.
var fov, near, far gl.GLdouble
fov = 45.0
near = 0.1
far = 100.0
top := gl.GLdouble(math.Tan(float64(fov*math.Pi/360.0))) * near
bottom := -top
left := aspect * bottom
right := aspect * top
gl.Frustum(float64(left), float64(right), float64(bottom), float64(top), float64(near), float64(far))
// Make sure we're changing the model view and not the projection
gl.MatrixMode(gl.MODELVIEW)
// Reset the view
gl.LoadIdentity()
}
// handle key press events
func handleKeyPress(keysym sdl.Keysym) {
switch keysym.Sym {
case sdl.K_ESCAPE:
Quit(0)
case sdl.K_F1:
sdl.WM_ToggleFullScreen(surface)
}
}
// general OpenGL initialization
func initGL() {
// enable smooth shading
gl.ShadeModel(gl.SMOOTH)
// Set the background to black
gl.ClearColor(0.0, 0.0, 0.0, 0.0)
// Depth buffer setup
gl.ClearDepth(1.0)
// Enable depth testing
gl.Enable(gl.DEPTH_TEST)
// The type of test
gl.DepthFunc(gl.LEQUAL)
// Nicest perspective correction
gl.Hint(gl.PERSPECTIVE_CORRECTION_HINT, gl.NICEST)
}
// used to calculate fps
var t0 uint32
var frames uint32
// Here goes our drawing code
func drawGLScene() {
// Clear the screen and depth buffer
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
// reset the view
gl.LoadIdentity()
// Draw to the screen
sdl.GL_SwapBuffers()
// Gather our frames per second
frames++
t := sdl.GetTicks()
if t-t0 >= 5000 {
seconds := (t - t0) / 1000.0
fps := frames / seconds
fmt.Println(frames, "frames in", seconds, "seconds =", fps, "FPS")
t0 = t
frames = 0
}
}
func main() {
// Initialize SDL
if sdl.Init(sdl.INIT_VIDEO) < 0 {
panic("Video initialization failed: " + sdl.GetError())
}
// flags to pass to sdl.SetVideoMode
videoFlags := sdl.OPENGL // Enable OpenGL in SDL
videoFlags |= sdl.DOUBLEBUF // Enable double buffering
videoFlags |= sdl.HWPALETTE // Store the palette in hardware
videoFlags |= sdl.RESIZABLE // Enable window resizing
// get a SDL surface
surface = sdl.SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, uint32(videoFlags))
// verify there is a surface
if surface == nil {
panic("Video mode set failed: " + sdl.GetError())
Quit(1)
}
// When this function is finished, clean up and exit.
defer Quit(0)
// Sets up OpenGL double buffering
sdl.GL_SetAttribute(sdl.GL_DOUBLEBUFFER, 1)
// Execute everything needed for OpenGL
initGL()
// Resize the initial window
resizeWindow(SCREEN_WIDTH, SCREEN_HEIGHT)
// wait for events
running := true
isActive := true
for running {
for ev := sdl.PollEvent(); ev != nil; ev = sdl.PollEvent() {
switch e := ev.(type) {
case *sdl.ActiveEvent:
isActive = e.Gain != 0
case *sdl.ResizeEvent:
width, height := int(e.W), int(e.H)
surface = sdl.SetVideoMode(width, height, SCREEN_BPP, uint32(videoFlags))
if surface == nil {
fmt.Println("Could not get a surface after resize:", sdl.GetError())
Quit(1)
}
resizeWindow(width, height)
case *sdl.KeyboardEvent:
if e.Type == sdl.KEYDOWN {
handleKeyPress(e.Keysym)
}
case *sdl.QuitEvent:
running = false
}
}
// draw the scene
if isActive {
drawGLScene()
}
}
}