Beispiel #1
0
func main() {
	if err := glfw.Init(); err != nil {
		fmt.Fprintf(os.Stderr, "[e] %v\n", err)
		return
	}
	defer glfw.Terminate()

	if err := glfw.OpenWindow(appWidth, appHeight, 8, 8, 8, 8, 24, 8, glfw.Windowed); err != nil {
		fmt.Fprintf(os.Stderr, "[e] %v\n", err)
		return
	}
	defer glfw.CloseWindow()

	if err := gl.Init(); err != 0 {
		fmt.Fprintf(os.Stderr, "[e] %v\n", err)
		return
	}
	glfw.SetWindowTitle(title)

	fps := fps.NewFPS(glfw.Time())

	blocks.Init(appWidth, appHeight)
	for glfw.WindowParam(glfw.Opened) == 1 {
		blocks.Tick()
		fps.Tick(glfw.Time())
		if glfw.WindowParam(glfw.Active) == 1 {
			glfw.Sleep(0.001)
		} else {
			glfw.Sleep(0.05)
		}
	}
}
Beispiel #2
0
func StartEngine() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	runtime.LockOSThread()
	fmt.Println("Enginge started!")
	var err error
	if err = glfw.Init(); err != nil {
		panic(err)
	}
	fmt.Println("GLFW Initialized!")

	glfw.OpenWindowHint(glfw.Accelerated, 1)

	if err = glfw.OpenWindow(Width, Height, 8, 8, 8, 8, 8, 8, glfw.Windowed); err != nil {
		panic(err)
	}

	glfw.SetSwapInterval(1) //0 to disable vsync, 1 to enable it
	glfw.SetWindowTitle(windowTitle)
	glfw.SetWindowSizeCallback(onResize)
	glfw.SetKeyCallback(input.OnKey)
	glfw.SetCharCallback(input.OnChar)
	glfw.SetMouseButtonCallback(input.ButtonPress)
	glfw.SetMouseWheel(0)
	glfw.SetMouseWheelCallback(input.MouseWheelCallback)

	input.MouseWheelPosition = glfw.MouseWheel
	input.MousePosition = glfw.MousePos

	if err = initGL(); err != nil {
		panic(err)
	}
	fmt.Println("Opengl Initialized!")

	TextureMaterial = NewBasicMaterial(spriteVertexShader, spriteFragmentShader)
	err = TextureMaterial.Load()
	if err != nil {
		fmt.Println(err)
	}

	SDFMaterial = NewBasicMaterial(sdfVertexShader, sdfFragmentShader)
	err = SDFMaterial.Load()
	if err != nil {
		fmt.Println(err)
	}

	internalMaterial = NewBasicMaterial(spriteVertexShader, spriteFragmentShader)
	err = internalMaterial.Load()
	if err != nil {
		fmt.Println(err)
	}

	initDefaultPlane()
	glfw.SwapBuffers()

	gameTime = time.Time{}
	lastTime = time.Now()
	dl = glfw.Time()
}
Beispiel #3
0
func (me *TimingStats) end() {
	if Stats.enabled {
		if me.thisTime = glfw.Time() - me.measureStartTime; me.thisTime > me.max {
			me.max = me.thisTime
		}
		me.measuredCounter++
		me.totalAccum += me.thisTime
	}
}
Beispiel #4
0
func main() {
	var err error
	if err = glfw.Init(); err != nil {
		log.Fatalf("%v\n", err)
		return
	}

	defer glfw.Terminate()

	// Open window with FSAA samples (if possible).
	glfw.OpenWindowHint(glfw.FsaaSamples, 4)

	if err = glfw.OpenWindow(400, 400, 0, 0, 0, 0, 0, 0, glfw.Windowed); err != nil {
		log.Fatalf("%v\n", err)
		return
	}

	defer glfw.CloseWindow()

	glfw.SetWindowTitle("Aliasing Detector")
	glfw.SetSwapInterval(1)

	if samples := glfw.WindowParam(glfw.FsaaSamples); samples != 0 {
		fmt.Printf("Context reports FSAA is supported with %d samples\n", samples)
	} else {
		fmt.Printf("Context reports FSAA is unsupported\n")
	}

	gl.MatrixMode(gl.PROJECTION)
	glu.Perspective(0, 1, 0, 1)

	for glfw.WindowParam(glfw.Opened) == 1 {
		time := float32(glfw.Time())

		gl.Clear(gl.COLOR_BUFFER_BIT)

		gl.LoadIdentity()
		gl.Translatef(0.5, 0, 0)
		gl.Rotatef(time, 0, 0, 1)

		gl.Enable(GL_MULTISAMPLE_ARB)
		gl.Color3f(1, 1, 1)
		gl.Rectf(-0.25, -0.25, 0.25, 0.25)

		gl.LoadIdentity()
		gl.Translatef(-0.5, 0, 0)
		gl.Rotatef(time, 0, 0, 1)

		gl.Disable(GL_MULTISAMPLE_ARB)
		gl.Color3f(1, 1, 1)
		gl.Rectf(-0.25, -0.25, 0.25, 0.25)
		glfw.SwapBuffers()
	}
}
Beispiel #5
0
func Tick() {
	timer = float32(glfw.Time())

	gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

	program.Use()

	camera.Tick()

	modelViewMatrixUniform.UniformMatrix4fv(camera.modelViewMatrix[:])
	projectionMatrixUniform.UniformMatrix4fv(camera.projectionMatrix[:])
	timerUniform.Uniform1f(timer)

	positionAttrib.EnableArray()
	texcoordAttrib.EnableArray()

	gl.ActiveTexture(gl.TEXTURE0)
	textures[0].Bind(gl.TEXTURE_2D)
	textureUniforms[0].Uniform1i(0)

	gl.ActiveTexture(gl.TEXTURE1)
	textures[1].Bind(gl.TEXTURE_2D)
	textureUniforms[1].Uniform1i(1)

	sizeOfVertex := int(unsafe.Sizeof(Vertex{}))
	posoffset := uintptr(0)
	texoffset := unsafe.Offsetof(Vertex{}.texcoord)
	for _, renderObject := range renderObjects {
		renderObject.vertexBuffer.Bind(gl.ARRAY_BUFFER)
		positionAttrib.AttribPointer(3, gl.FLOAT, false, sizeOfVertex, posoffset)
		texcoordAttrib.AttribPointer(2, gl.FLOAT, false, sizeOfVertex, texoffset)

		gl.DrawArrays(gl.TRIANGLES, 0, renderObject.numVerticies)
	}

	positionAttrib.DisableArray()
	texcoordAttrib.DisableArray()
	gl.ProgramUnuse()

	glfw.SwapBuffers()
}
Beispiel #6
0
// Since go has multiple return values, I just went ahead and made it return the view and perspective matrices (in that order) rather than messing with getter methods
func (c *Camera) ComputeViewPerspective() (mathgl.Mat4f, mathgl.Mat4f) {
	if mathgl.FloatEqual(-1.0, c.time) {
		c.time = glfw.Time()
	}

	currTime := glfw.Time()
	deltaT := currTime - c.time

	xPos, yPos := glfw.MousePos()
	glfw.SetMousePos(width/2.0, height/2.0)

	c.hAngle += mouseSpeed * ((width / 2.0) - float64(xPos))
	c.vAngle += mouseSpeed * ((height / 2.0) - float64(yPos))

	dir := mathgl.Vec3f{
		float32(math.Cos(c.vAngle) * math.Sin(c.hAngle)),
		float32(math.Sin(c.vAngle)),
		float32(math.Cos(c.vAngle) * math.Cos(c.hAngle))}

	right := mathgl.Vec3f{
		float32(math.Sin(c.hAngle - math.Pi/2.0)),
		0.0,
		float32(math.Cos(c.hAngle - math.Pi/2.0))}

	up := right.Cross(dir)

	if glfw.Key(glfw.KeyUp) == glfw.KeyPress || glfw.Key('W') == glfw.KeyPress {
		c.pos = c.pos.Add(dir.Mul(float32(deltaT * speed)))
	}

	if glfw.Key(glfw.KeyDown) == glfw.KeyPress || glfw.Key('S') == glfw.KeyPress {
		c.pos = c.pos.Sub(dir.Mul(float32(deltaT * speed)))
	}

	if glfw.Key(glfw.KeyRight) == glfw.KeyPress || glfw.Key('D') == glfw.KeyPress {
		c.pos = c.pos.Add(right.Mul(float32(deltaT * speed)))
	}

	if glfw.Key(glfw.KeyLeft) == glfw.KeyPress || glfw.Key('A') == glfw.KeyPress {
		c.pos = c.pos.Sub(right.Mul(float32(deltaT * speed)))
	}

	// Adding to the original tutorial, Space goes up
	if glfw.Key(glfw.KeySpace) == glfw.KeyPress {
		c.pos = c.pos.Add(up.Mul(float32(deltaT * speed)))
	}

	// Adding to the original tutorial, left control goes down
	if glfw.Key(glfw.KeyLctrl) == glfw.KeyPress {
		c.pos = c.pos.Sub(up.Mul(float32(deltaT * speed)))
	}

	fov := initialFOV - 5.0*float64(glfw.MouseWheel())

	proj := mathgl.Perspective(fov, 4.0/3.0, 0.1, 100.0)
	view := mathgl.LookAtV(c.pos, c.pos.Add(dir), up)

	c.time = currTime

	return view, proj
}
Beispiel #7
0
func main() {
	sys := Make()
	sys.Startup()
	defer sys.Shutdown()
	// InitQueue()

	sys.CreateWindow(1024, 768, "Gexic")
	gl.ClearColor(1, 1, 1, 0.)
	initGL()

	prevSelectPos = []int{0, 0, 0}

	// PurgeQueue()
	// genHexMap()
	hexMap2 = GenHexMap()
	// for matches := checkHexMap(); len(matches) > 0; matches = checkHexMap() {
	// 	removeHexAndGenNew(matches)
	// }
	glfw.SetMouseButtonCallback(MouseButtonCallback)
	glfw.SetCharCallback(charCallback)
	glfw.SetMousePosCallback(MousePosCallback)
	currExX = -1
	currExY = -1

	for sys.CheckExitMainLoop() {
		start := glfw.Time()
		wait := float64(1) / float64(30)
		gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
		gl.Enable(gl.TEXTURE_2D)
		gl.Enable(gl.BLEND)
		gl.Disable(gl.DEPTH_TEST)
		// renderHexMap()
		wallpaper.Bind(gl.TEXTURE_2D)
		gl.TexEnvf(gl.TEXTURE_ENV, gl.TEXTURE_ENV_MODE, gl.REPLACE)
		gl.Begin(gl.QUADS)
		gl.TexCoord2f(0, 0)
		gl.Vertex2i(0, 0)
		gl.TexCoord2f(0, 1)
		gl.Vertex2i(0, 768)
		gl.TexCoord2f(1, 1)
		gl.Vertex2i(1024, 768)
		gl.TexCoord2f(1, 0)
		gl.Vertex2i(1024, 0)
		gl.End()
		hexMap2.Render()
		hexRotate.AnimateAndExecute()
		hexShrink.AnimateAndExecute()
		hexFall.AnimateAndExecute()
		if !mouse.locked {
			x, y := mouse.GetXY()
			hexMap2.CalcClosestCenter(x, y)
		}
		gl.Flush()
		gl.Disable(gl.TEXTURE_2D)
		gl.Disable(gl.BLEND)
		sys.Refresh()
		diff := glfw.Time() - start
		if diff < wait {
			glfw.Sleep(wait - diff)
		}
	}
}
Beispiel #8
0
//	Returns the number of seconds expired ever since Loop.Run() was last called.
func (_ *NgLoop) Time() float64 {
	return glfw.Time()
}
Beispiel #9
0
//	Initiates a rendering loop. This method returns only when the loop is stopped for whatever reason.
//
//	(Before entering the loop, this method performs a one-off GC invokation.)
func (_ *NgLoop) Run() {
	var (
		secTick int
		runGc   = Options.Loop.GcEvery.Frame
	)
	if !Loop.Running {
		Loop.Running = true
		glfw.SetTime(0)
		Loop.Tick.Now = glfw.Time()
		Core.copyAppToPrep()
		Core.copyPrepToRend()
		Loop.Tick.Prev = Loop.Tick.Now
		Loop.Tick.Now = glfw.Time()
		Loop.Tick.PrevSec, Loop.Tick.Delta = int(Loop.Tick.Now), Loop.Tick.Now-Loop.Tick.Prev
		Stats.reset()
		runtime.GC()
		Diag.LogMisc("Enter loop...")
		Loop.Running = glfw.WindowParam(glfw.Opened) == 1
		for Loop.Running {
			//	STEP 0. Fire off the prep thread (for next frame) and app thread (for next-after-next frame).
			thrPrep.Lock()
			go Loop.onThreadPrep()
			thrApp.Lock()
			go Loop.onThreadApp()

			//	STEP 1. Fill the GPU command queue with rendering commands (batched together by the previous prep thread)
			Stats.FrameRenderCpu.begin()
			Core.onRender()
			Stats.FrameRenderCpu.end()

			//	STEP 2. While the GL driver processes its command queue and other CPU cores work on
			//	app and prep threads, this CPU core can now perform some other minor duties
			Stats.fpsCounter++
			Stats.fpsAll++
			//	This branch runs at most and at least 1x per second
			if secTick = int(Loop.Tick.Now); secTick != Loop.Tick.PrevSec {
				Stats.FrameOnSec.begin()
				Stats.FpsLastSec, Loop.Tick.PrevSec = Stats.fpsCounter, secTick
				Stats.fpsCounter = 0
				if Diag.LogGLErrorsInLoopOnSec {
					Diag.LogIfGlErr("onSec")
				}
				Loop.On.EverySec()
				runGc = Options.Loop.GcEvery.Sec
				Stats.FrameOnSec.end()
				Stats.enable() // the first few frames were warm-ups that don't count towards the stats
			}
			//	Wait for threads -- waits until both app and prep threads are done and copies stage states around
			Loop.onWaitForThreads()
			//	Call On.WinThread() -- for main-thread user code (mostly input polling) without affecting On.AppThread
			Loop.onThreadWin()

			//	Must do this here so that current-tick won't change half-way through OnAppTread(),
			//	and then we'd also like this frame's On.WinThread() to have the same current-tick.
			Loop.Tick.Prev, Loop.Tick.Now = Loop.Tick.Now, glfw.Time()
			Stats.Frame.measureStartTime, Loop.Tick.Delta = Loop.Tick.Prev, Loop.Tick.Now-Loop.Tick.Prev
			Stats.Frame.end()
			//	GC stops-the-world so do it after go-routines have finished. Now is a good time, as the GPU
			//	is likely still busy processing commands from step 1 and won't be interrupted by Go's GC --
			//	the subsequent buffer-swap step block-waits for the GPU anyway.
			if runGc {
				runGc = Options.Loop.GcEvery.Frame
				Loop.onGC()
			}
			//	STEP 3. Swap buffers -- this waits for the GPU/GL to finish processing its command
			//	queue filled in Step 1, swap buffers and for V-sync (if any)
			Loop.onSwap()

			//	Check for resize before next render
			if (UserIO.Window.lastResize > 0) && ((Loop.Tick.Now - UserIO.Window.lastResize) > UserIO.Window.ResizeMinDelay) {
				UserIO.Window.lastResize = 0
				Core.onResizeWindow(UserIO.Window.width, UserIO.Window.height)
			}
			Stats.FrameRenderBoth.combine(&Stats.FrameRenderCpu, &Stats.FrameRenderGpu)
			if Loop.Delay > 0 {
				time.Sleep(Loop.Delay)
			}
			if Loop.MaxIterations > 0 && Stats.fpsAll >= Loop.MaxIterations {
				Loop.Running = false
			}
		}
		Loop.Running = false
		Diag.LogMisc("Exited loop.")
		Diag.LogIfGlErr("ngine.PostLoop")
		if false {
			for rbi, rbe := range Core.Render.Canvases[1].Views[0].Technique_Scene().thrRend.batch.all {
				println(strf("%d\t==>\tP:%v\tT:%v\tB:%v\tD:%v", rbi, rbe.prog, rbe.texes, Core.Libs.Meshes[rbe.mesh].meshBuffer.glIbo.GlHandle, rbe.dist))
			}
		}
	}
}
Beispiel #10
0
func Run() {
	timeNow := time.Now()
	gameTime = gameTime.Add(timeNow.Sub(lastTime))
	//deltaTime = float64(timeNow.Sub(lastTime).Nanoseconds()) / float64(time.Second)
	lastTime = timeNow
	before := timeNow

	dn := glfw.Time()
	dd = dn - dl
	dl = dn
	deltaTime = dd

	timer := NewTimer()
	timer.Start()

	CurrentCamera().Clear()

	var destroyDelta,
		startDelta,
		fixedUpdateDelta,
		physicsDelta,
		updateDelta,
		lateUpdateDelta,
		drawDelta,
		coroutinesDelta,
		stepDelta,
		behaviorDelta,
		startPhysicsDelta,
		endPhysicsDelta time.Duration

	if mainScene != nil {
		d := deltaTime
		if d > maxPhysicsTime {
			d = maxPhysicsTime
		}
		fixedTime += d
		sd := mainScene.SceneBase()

		arr := &sd.gameObjects

		timer.StartCustom("Destory routines")
		iter(arr, destoyGameObject)
		destroyDelta = timer.StopCustom("Destory routines")

		//Better to not do it every frame.
		mainScene.SceneBase().cleanNil()

		timer.StartCustom("Start routines")
		iter(arr, startGameObject)
		startDelta = timer.StopCustom("Start routines")

		//

		timer.StartCustom("Physics time")
		if EnablePhysics {
			timer.StartCustom("Physics step time")

			for fixedTime >= stepTime {
				timer.StartCustom("FixedUpdate routines")
				iter(arr, fixedUdpateGameObject)
				fixedUpdateDelta = timer.StopCustom("FixedUpdate routines")

				timer.StartCustom("PreStep Physics Delta")
				iter(arr, preStepGameObject)
				startPhysicsDelta = timer.StopCustom("PreStep Physics Delta")

				Space.Step(vect.Float(stepTime))
				fixedTime -= stepTime

				_ = timer.StopCustom("Physics step time")

				timer.StartCustom("PostStep Physics Delta")
				iter(arr, postStepGameObject)
				endPhysicsDelta = timer.StopCustom("PostStep Physics Delta")
			}
			if fixedTime > 0 && fixedTime < stepTime {
				iter(arr, interpolateGameObject)
			}
		}
		physicsDelta = timer.StopCustom("Physics time")

		timer.StartCustom("Update routines")
		internalFPSObject.Update()
		iter(arr, udpateGameObject)
		updateDelta = timer.StopCustom("Update routines")

		timer.StartCustom("LateUpdate routines")
		iter(arr, lateudpateGameObject)
		lateUpdateDelta = timer.StopCustom("LateUpdate routines")

		timer.StartCustom("Draw routines")
		depthMap.Iter(drawGameObject)
		drawDelta = timer.StopCustom("Draw routines")

		timer.StartCustom("coroutines")
		cr.Run()
		coroutinesDelta = timer.StopCustom("coroutines")

		timer.StartCustom("BehaviorTree")
		bt.Run(BehaviorTicks)
		behaviorDelta = timer.StopCustom("BehaviorTree")

		input.UpdateInput()

		stepDelta = timer.Stop()
	}
	timer.StartCustom("SwapBuffers")
	glfw.SwapBuffers()
	swapBuffersDelta := timer.StopCustom("SwapBuffers")

	now := time.Now()
	deltaDur := now.Sub(before)

	if Debug {
		fmt.Println()
		fmt.Println("##################")
		if InternalFPS < 20 {
			fmt.Println("FPS is lower than 20. FPS:", InternalFPS)
		} else if InternalFPS < 30 {
			fmt.Println("FPS is lower than 30. FPS:", InternalFPS)
		} else if InternalFPS < 40 {
			fmt.Println("FPS is lower than 40. FPS:", InternalFPS)
		}
		if stepDelta > 17*time.Millisecond {
			fmt.Println("StepDelta time is lower than normal")
		}
		fmt.Println("Debugging Times:")
		if (deltaDur.Nanoseconds() / int64(time.Millisecond)) != 0 {
			fmt.Println("Expected FPS", 1000/(deltaDur.Nanoseconds()/int64(time.Millisecond)))
		}
		fmt.Println("Step time", stepDelta)
		fmt.Println("Destroy time", destroyDelta)
		fmt.Println("Start time", startDelta)
		fmt.Println("FixedUpdate time", fixedUpdateDelta)
		fmt.Println("Update time", updateDelta)
		fmt.Println("LateUpdate time", lateUpdateDelta)
		fmt.Println("Draw time", drawDelta)
		fmt.Println("Delta time", deltaDur, deltaTime)
		fmt.Println("SwapBuffers time", swapBuffersDelta)
		fmt.Println("Coroutines time", coroutinesDelta)
		fmt.Println("BehaviorTree time", behaviorDelta)
		fmt.Println("------------------")
		fmt.Println("Physics time:", physicsDelta)
		fmt.Println("PreStepDelta time", startPhysicsDelta)
		fmt.Println("PostStepDelta time", endPhysicsDelta)
		fmt.Println("StepTime time", Space.StepTime)
		fmt.Println("ApplyImpulse time", Space.ApplyImpulsesTime)
		fmt.Println("ReindexQueryTime time", Space.ReindexQueryTime)
		fmt.Println("Arbiters", len(Space.Arbiters))
		fmt.Println("##################")
		fmt.Println()
	}
}
Beispiel #11
0
//	Returns the average number of frames-per-second since Loop.Loop() was last called.
func (_ *NgStats) AverageFps() float64 {
	return Stats.fpsAll / glfw.Time()
}
Beispiel #12
0
func (me *TimingStats) begin() {
	if Stats.enabled {
		me.measureStartTime = glfw.Time()
	}
}
Beispiel #13
0
func main() {
	if err := glfw.Init(); err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", err.Error())
		return
	}

	defer glfw.Terminate()

	glfw.OpenWindowHint(glfw.FsaaSamples, 4)
	glfw.OpenWindowHint(glfw.OpenGLVersionMajor, 3)
	glfw.OpenWindowHint(glfw.OpenGLVersionMinor, 3)
	glfw.OpenWindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)

	if err := glfw.OpenWindow(1024, 768, 0, 0, 0, 0, 32, 0, glfw.Windowed); err != nil {
		fmt.Fprintf(os.Stderr, "%s\n", err.Error())
		return
	}

	glfw.SetSwapInterval(0)

	//gl.GlewExperimental(true)
	gl.Init()     // Can't find gl.GLEW_OK or any variation, not sure how to check if this worked
	gl.GetError() // ignore error, since we're telling it to use CoreProfile above, we get "invalid enumerant" (GLError 1280) which freaks the OpenGLSentinel out

	glfw.SetWindowTitle("Tutorial 09")

	glfw.Enable(glfw.StickyKeys)
	glfw.Disable(glfw.MouseCursor) // Not in the original tutorial, but IMO it SHOULD be there
	glfw.SetMousePos(1024.0/2.0, 768.0/2.0)

	gl.ClearColor(0., 0., 0.4, 0.)

	gl.Enable(gl.DEPTH_TEST)
	gl.DepthFunc(gl.LESS)

	gl.Enable(gl.CULL_FACE)

	camera := input.NewCamera()

	vertexArray := gl.GenVertexArray()
	defer vertexArray.Delete()
	vertexArray.Bind()

	prog := helper.MakeProgram("StandardShading.vertexshader", "StandardShading.fragmentshader")
	defer prog.Delete()

	matrixID := prog.GetUniformLocation("MVP")
	viewMatrixID := prog.GetUniformLocation("V")
	modelMatrixID := prog.GetUniformLocation("M")

	texture := helper.MakeTextureFromTGA("uvmap.tga") // Had to convert to tga, go-gl is missing the texture method for DDS right now
	defer texture.Delete()
	texSampler := prog.GetUniformLocation("myTextureSampler")

	meshObj := objloader.LoadObject("suzanne.obj")

	indices, indexedVertices, indexedUVs, indexedNormals := indexer.IndexVBO(meshObj.Vertices, meshObj.UVs, meshObj.Normals)

	vertexBuffer := gl.GenBuffer()
	defer vertexBuffer.Delete()
	vertexBuffer.Bind(gl.ARRAY_BUFFER)
	gl.BufferData(gl.ARRAY_BUFFER, len(indexedVertices)*3*4, indexedVertices, gl.STATIC_DRAW)

	uvBuffer := gl.GenBuffer()
	defer uvBuffer.Delete()
	uvBuffer.Bind(gl.ARRAY_BUFFER)
	// And yet, the weird length stuff doesn't seem to matter for UV or normal
	gl.BufferData(gl.ARRAY_BUFFER, len(indexedUVs)*2*4, indexedUVs, gl.STATIC_DRAW)

	normBuffer := gl.GenBuffer()
	defer normBuffer.Delete()
	normBuffer.Bind(gl.ARRAY_BUFFER)
	gl.BufferData(gl.ARRAY_BUFFER, len(indexedNormals)*3*4, indexedNormals, gl.STATIC_DRAW)

	elementBuffer := gl.GenBuffer()
	defer elementBuffer.Delete()
	elementBuffer.Bind(gl.ELEMENT_ARRAY_BUFFER)
	gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indices)*2, indices, gl.STATIC_DRAW) // NOTE: a GL_UNSIGNED_SHORT is 16-bits

	lightID := prog.GetUniformLocation("LightPosition_worldspace")
	lastTime := glfw.Time()
	nbFrames := 0
	// Equivalent to a do... while
	for ok := true; ok; ok = (glfw.Key(glfw.KeyEsc) != glfw.KeyPress && glfw.WindowParam(glfw.Opened) == gl.TRUE && glfw.Key('Q') != glfw.KeyPress) {

		currTime := glfw.Time()
		nbFrames++
		if currTime-lastTime >= 1.0 {
			fmt.Printf("%f ms/frame\n", 1000.0/float64(nbFrames))
			nbFrames = 0
			lastTime += 1.0
		}

		func() {
			gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

			prog.Use()
			defer gl.ProgramUnuse()

			view, proj := camera.ComputeViewPerspective()
			model := mathgl.Ident4f()

			MVP := proj.Mul4(view).Mul4(model)
			//mvpArray := mvp.AsCMOArray(mathgl.FLOAT32).([16]float32)
			//vArray := view.AsCMOArray(mathgl.FLOAT32).([16]float32)
			//mArray := model.AsCMOArray(mathgl.FLOAT32).([16]float32)

			matrixID.UniformMatrix4fv(false, MVP)
			viewMatrixID.UniformMatrix4fv(false, view)
			modelMatrixID.UniformMatrix4fv(false, model)

			lightID.Uniform3f(4., 4., 4.)

			gl.ActiveTexture(gl.TEXTURE0)
			texture.Bind(gl.TEXTURE_2D)
			defer texture.Unbind(gl.TEXTURE_2D)
			texSampler.Uniform1i(0)

			vertexAttrib := gl.AttribLocation(0)
			vertexAttrib.EnableArray()
			defer vertexAttrib.DisableArray()
			vertexBuffer.Bind(gl.ARRAY_BUFFER)
			defer vertexBuffer.Unbind(gl.ARRAY_BUFFER)
			vertexAttrib.AttribPointer(3, gl.FLOAT, false, 0, nil)

			uvAttrib := gl.AttribLocation(1)
			uvAttrib.EnableArray()
			defer uvAttrib.DisableArray()
			uvBuffer.Bind(gl.ARRAY_BUFFER)
			defer uvBuffer.Unbind(gl.ARRAY_BUFFER)
			uvAttrib.AttribPointer(2, gl.FLOAT, false, 0, nil)

			normAttrib := gl.AttribLocation(2)
			normAttrib.EnableArray()
			defer normAttrib.DisableArray()
			normBuffer.Bind(gl.ARRAY_BUFFER)
			defer normBuffer.Unbind(gl.ARRAY_BUFFER)
			normAttrib.AttribPointer(3, gl.FLOAT, false, 0, nil)

			elementBuffer.Bind(gl.ELEMENT_ARRAY_BUFFER)
			defer elementBuffer.Unbind(gl.ELEMENT_ARRAY_BUFFER)

			gl.DrawElements(gl.TRIANGLES, len(indices), gl.UNSIGNED_SHORT, nil)

			glfw.SwapBuffers()
		}() // Defers unbinds and disables to here, end of the loop
	}

}
Beispiel #14
0
func (me *context) Time() float64 {
	return glfw.Time()
}