Bläddra i källkod

standard app dev...

leonsal 8 år sedan
förälder
incheckning
8b2378045f
1 ändrade filer med 205 tillägg och 0 borttagningar
  1. 205 0
      util/app/app.go

+ 205 - 0
util/app/app.go

@@ -0,0 +1,205 @@
+package app
+
+import (
+	"flag"
+	"fmt"
+	"runtime"
+
+	"github.com/g3n/engine/audio/al"
+	"github.com/g3n/engine/audio/ov"
+	"github.com/g3n/engine/audio/vorbis"
+	"github.com/g3n/engine/camera"
+	"github.com/g3n/engine/gls"
+	"github.com/g3n/engine/math32"
+	"github.com/g3n/engine/renderer"
+	"github.com/g3n/engine/util/logger"
+	"github.com/g3n/engine/window"
+)
+
+type App struct {
+	win         window.IWindow       // Application window
+	gl          *gls.GLS             // Application OpenGL state
+	log         *logger.Logger       // Application logger
+	renderer    *renderer.Renderer   // Renderer object
+	camPersp    *camera.Perspective  // Perspective camera
+	camOrtho    *camera.Orthographic // Orthographic camera
+	audio       bool                 // Audio available
+	vorbis      bool                 // Vorbis decoder available
+	audioEFX    bool                 // Audio effect extension support available
+	audioDev    *al.Device           // Audio player device
+	captureDev  *al.Device           // Audio capture device
+	oCpuProfile *string
+}
+
+type Options struct {
+	WinHeight    int  // Initial window height. Uses screen width if 0
+	WinWidth     int  // Initial window width. Uses screen height if 0
+	VersionMajor int  // Application version major
+	VersionMinor int  // Application version minor
+	LogLevel     int  // Initial log level
+	EnableFlags  bool // Enable command line flags
+}
+
+// appInstance points to the single Application instance
+var appInstance *App
+
+// Creates creates and returns the application object using the specified name for
+// the window title and log messages
+// This functions must be called only once.
+func Create(name string, ops Options) (*App, error) {
+
+	if appInstance != nil {
+		return nil, fmt.Errorf("Application already created")
+	}
+	app := new(App)
+
+	if ops.EnableFlags {
+		app.oCpuProfile = flag.String("cpuprofile", "", "Activate cpu profiling writing profile to the specified file")
+		flag.Parse()
+	}
+
+	// Creates application logger
+	log := logger.New(name, nil)
+	log.AddWriter(logger.NewConsole(false))
+	log.SetFormat(logger.FTIME | logger.FMICROS)
+	log.SetLevel(ops.LogLevel)
+	log.Info("%s v%d.%d starting", name, ops.VersionMajor, ops.VersionMinor)
+
+	// Window event handling must run on the main OS thread
+	runtime.LockOSThread()
+
+	// Creates window and sets it as the current context
+	win, err := window.New("glfw", 10, 10, name, false)
+	if err != nil {
+		return nil, err
+	}
+	// Sets the window size
+	swidth, sheight := win.GetScreenResolution(nil)
+	if ops.WinWidth != 0 {
+		swidth = ops.WinWidth
+	}
+	if ops.WinHeight != 0 {
+		sheight = ops.WinHeight
+	}
+	win.SetSize(swidth, sheight)
+
+	// Create OpenGL state
+	gl, err := gls.New()
+	if err != nil {
+		return nil, err
+	}
+
+	// Creates application object
+	app.win = win
+	app.gl = gl
+
+	// Creates perspective camera
+	width, height := app.win.GetSize()
+	aspect := float32(width) / float32(height)
+	app.camPersp = camera.NewPerspective(65, aspect, 0.01, 1000)
+
+	// Creates orthographic camera
+	app.camOrtho = camera.NewOrthographic(-2, 2, 2, -2, 0.01, 100)
+	app.camOrtho.SetPosition(0, 0, 3)
+	app.camOrtho.LookAt(&math32.Vector3{0, 0, 0})
+	app.camOrtho.SetZoom(1.0)
+
+	// Creates renderer
+	app.renderer = renderer.NewRenderer(gl)
+	err = app.renderer.AddDefaultShaders()
+	if err != nil {
+		return nil, fmt.Errorf("Erro from AddDefaulShaders:%v", err)
+	}
+
+	// Subscribe to window resize events
+	app.win.Subscribe(window.OnWindowSize, func(evname string, ev interface{}) {
+		app.OnWindowResize()
+	})
+
+	return app, nil
+
+}
+
+// Returns the single application instance
+func Get() *App {
+
+	return appInstance
+}
+
+// Window returns the application window
+func (a *App) Window() window.IWindow {
+
+	return a.win
+}
+
+func (a *App) Run() {
+
+	for !a.win.ShouldClose() {
+		// Poll input events and process them
+		a.win.PollEvents()
+
+		a.win.SwapBuffers()
+	}
+}
+
+// OnWindowResize is called when the window resize event is received
+func (app *App) OnWindowResize() {
+
+	// Sets view port
+	width, height := app.win.GetSize()
+	app.gl.Viewport(0, 0, int32(width), int32(height))
+	aspect := float32(width) / float32(height)
+
+	// Sets camera aspect ratio
+	app.camPersp.SetAspect(aspect)
+
+	// Sets GUI root panel size
+	//ctx.root.SetSize(float32(width), float32(height))
+}
+
+// LoadAudioLibs try to load audio libraries
+func (a *App) LoadAudioLibs() error {
+
+	// Try to load OpenAL
+	err := al.Load()
+	if err != nil {
+		return err
+	}
+
+	// Opens default audio device
+	a.audioDev, err = al.OpenDevice("")
+	if a.audioDev == nil {
+		return fmt.Errorf("Error: %s opening OpenAL default device", err)
+	}
+
+	// Checks for OpenAL effects extension support
+	if al.IsExtensionPresent("ALC_EXT_EFX") {
+		a.audioEFX = true
+	}
+
+	// Creates audio context with auxiliary sends
+	var attribs []int
+	if a.audioEFX {
+		attribs = []int{al.MAX_AUXILIARY_SENDS, 4}
+	}
+	acx, err := al.CreateContext(a.audioDev, attribs)
+	if err != nil {
+		return fmt.Errorf("Error creating audio context:%s", err)
+	}
+
+	// Makes the context the current one
+	err = al.MakeContextCurrent(acx)
+	if err != nil {
+		return fmt.Errorf("Error setting audio context current:%s", err)
+	}
+	//log.Info("%s version: %s", al.GetString(al.Vendor), al.GetString(al.Version))
+	a.audio = true
+
+	// Ogg Vorbis support
+	err = ov.Load()
+	if err == nil {
+		a.vorbis = true
+		vorbis.Load()
+	}
+	return nil
+}