Пример #1
5
func main() {
	// Initialize GLFW for window management
	glfw.SetErrorCallback(glfwErrorCallback)
	if !glfw.Init() {
		panic("failed to initialize glfw")
	}
	defer glfw.Terminate()

	glfw.WindowHint(glfw.Resizable, glfw.False)
	glfw.WindowHint(glfw.ContextVersionMajor, 3)
	glfw.WindowHint(glfw.ContextVersionMinor, 3)
	glfw.WindowHint(glfw.OpenglForwardCompatible, glfw.True)    // Necessary for OS X
	glfw.WindowHint(glfw.OpenglProfile, glfw.OpenglCoreProfile) // Necessary for OS X
	glfw.WindowHint(glfw.OpenglDebugContext, glfw.True)
	window, err := glfw.CreateWindow(WindowWidth, WindowHeight, "Cube", nil, nil)
	if err != nil {
		panic(err)
	}
	window.MakeContextCurrent()

	// Initialize Glow
	if err := gl.Init(); err != nil {
		panic(err)
	}

	// Note that it is possible to use GL functions spanning multiple versions
	if err := gl4.Init(); err != nil {
		fmt.Printf("Could not initialize GL 4.4 (non-fatal)")
	}

	if gl.ARB_debug_output {
		gl.Enable(gl.DEBUG_OUTPUT_SYNCHRONOUS_ARB)
		gl.DebugMessageCallbackARB(gl.DebugProc(glDebugCallback), gl.Ptr(nil))
		// Trigger an error to demonstrate debug output
		gl.Enable(gl.CONTEXT_FLAGS)
	}

	version := gl.GoStr(gl.GetString(gl.VERSION))
	fmt.Println("OpenGL version", version)

	// Configure the vertex and fragment shaders
	program, err := newProgram(vertexShader, fragmentShader)
	if err != nil {
		panic(err)
	}
	gl.UseProgram(program)

	projection := mgl32.Perspective(70.0, float32(WindowWidth)/WindowHeight, 0.1, 10.0)
	projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00"))
	gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0])

	camera := mgl32.LookAtV(mgl32.Vec3{3, 3, 3}, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0})
	cameraUniform := gl.GetUniformLocation(program, gl.Str("camera\x00"))
	gl.UniformMatrix4fv(cameraUniform, 1, false, &camera[0])

	model := mgl32.Ident4()
	modelUniform := gl.GetUniformLocation(program, gl.Str("model\x00"))
	gl.UniformMatrix4fv(modelUniform, 1, false, &model[0])

	textureUniform := gl.GetUniformLocation(program, gl.Str("tex\x00"))
	gl.Uniform1i(textureUniform, 0)

	gl.BindFragDataLocation(program, 0, gl.Str("outputColor\x00"))

	// Load the texture
	texture, err := newTexture("square.png")
	if err != nil {
		panic(err)
	}

	// Configure the vertex data
	var vao uint32
	gl.GenVertexArrays(1, &vao)
	gl.BindVertexArray(vao)

	var vbo uint32
	gl.GenBuffers(1, &vbo)
	gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
	gl.BufferData(gl.ARRAY_BUFFER, len(cubeVertices)*4, gl.Ptr(cubeVertices), gl.STATIC_DRAW)

	vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vert\x00")))
	gl.EnableVertexAttribArray(vertAttrib)
	gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, 5*4, gl.PtrOffset(0))

	texCoordAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vertTexCoord\x00")))
	gl.EnableVertexAttribArray(texCoordAttrib)
	gl.VertexAttribPointer(texCoordAttrib, 2, gl.FLOAT, false, 5*4, gl.PtrOffset(3*4))

	// Configure global settings
	gl.Enable(gl.DEPTH_TEST)
	gl.DepthFunc(gl.LESS)
	gl.ClearColor(1.0, 1.0, 1.0, 1.0)

	angle := 0.0
	previousTime := glfw.GetTime()

	for !window.ShouldClose() {
		gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

		// Update
		time := glfw.GetTime()
		elapsed := time - previousTime
		previousTime = time

		angle += elapsed
		model = mgl32.HomogRotate3D(float32(angle), mgl32.Vec3{0, 1, 0})

		// Render
		gl.UseProgram(program)
		gl.UniformMatrix4fv(modelUniform, 1, false, &model[0])

		gl.BindVertexArray(vao)

		gl.ActiveTexture(gl.TEXTURE0)
		gl.BindTexture(gl.TEXTURE_2D, texture)

		gl.DrawArrays(gl.TRIANGLES, 0, 6*2*3)

		// Maintenance
		window.SwapBuffers()
		glfw.PollEvents()
	}
}
Пример #2
0
func (self *OpenGLWindow) TimeSinceLast() float32 {
	if self.timeLastCall == 0 {
		self.timeLastCall = glfw.GetTime()
	}

	now := glfw.GetTime()
	diff := now - self.timeLastCall
	self.timeLastCall = now

	return float32(diff)
}
Пример #3
0
func (ship *Ship) shoot() {
	if ship.shooting && glfw.GetTime() > ship.lastBulletFired+(1/ship.bulletsPerSecond) && ship.IsAlive() {
		var rad float64 = ((ship.Angle) * math.Pi) / 180
		x, y := RotateVector(&Vector{0, 5}, ship.Angle)

		bullet := NewBullet(
			ship.PosX+x,
			ship.PosY+y,
			ship.MaxVelocity*math.Sin(rad)*2,
			ship.MaxVelocity*math.Cos(rad)*2,
		)
		bullets = append(bullets, bullet)
		ship.lastBulletFired = glfw.GetTime()
	}
}
Пример #4
0
func main() {
	glfw.SetErrorCallback(errorCallback)

	if !glfw.Init() {
		panic("Can't init glfw!")
	}
	defer glfw.Terminate()

	window, err := glfw.CreateWindow(800, 640, "MyGui", nil, nil)
	if err != nil {
		panic(err)
	}
	window.MakeContextCurrent()

	glfw.SwapInterval(1)
	gl.Init()

	mvp := prepareModelViewProjection(800, 640)

	prepareScene()
	dt := float64(0)
	glfw.SetTime(dt)

	for !window.ShouldClose() {
		dt = glfw.GetTime()
		glfw.SetTime(0)
		updateScene(dt)
		drawScene(mvp, dt)
		window.SwapBuffers()
		glfw.PollEvents()
	}
}
Пример #5
0
func (torpedo *Torpedo) Update() {
	if paused {
		timediff := (glfw.GetTime() - torpedo.Entity.lastUpdatedTime)
		torpedo.MaxLifetime = torpedo.MaxLifetime + timediff
	}
	torpedo.Entity.Update()
}
Пример #6
0
func (bullet *Bullet) Update() {
	if paused {
		timediff := (glfw.GetTime() - bullet.Entity.lastUpdatedTime)
		bullet.MaxLifetime = bullet.MaxLifetime + timediff
	}
	bullet.Entity.Update()
}
Пример #7
0
func (explosion *Explosion) Update() {
	if paused {
		timediff := (glfw.GetTime() - explosion.Entity.lastUpdatedTime)
		explosion.MaxLifetime = explosion.MaxLifetime + timediff
	}
	explosion.Entity.Update()
	for l, _ := range explosion.Lines {
		explosion.Lines[l].Update()
	}
}
Пример #8
0
func NewEntity(shape Polygon, x, y, angle, turnrate, vX, vY, accel, maxvel float64) *Entity {
	return &Entity{
		Shape:            shape,
		PosX:             x,
		PosY:             y,
		Angle:            angle,
		TurnRate:         turnrate,
		VelocityX:        vX,
		VelocityY:        vY,
		AccelerationRate: accel,
		MaxVelocity:      maxvel,
		rotateLeft:       false,
		rotateRight:      false,
		accelerate:       false,
		decelerate:       false,
		isAlive:          true,
		createdTime:      glfw.GetTime(),
		lastUpdatedTime:  glfw.GetTime(),
	}
}
Пример #9
0
func main() {
	initGlfw()
	defer terminateGlfw()
	window := createWindow(int(width), int(height))
	game := NewGame(window)
	profiler := NewProfiler(game.text)
	defer game.delete()

	previousFrameTime := glfw.GetTime()
	profiler.start()
	for !window.ShouldClose() {
		now := glfw.GetTime()
		elapsed := now - previousFrameTime
		previousFrameTime = now
		game.update(elapsed)
		game.render()
		profiler.update()
		profiler.render()
		window.SwapBuffers()
		glfw.PollEvents()
	}
}
Пример #10
0
func (explosion *BigExplosion) Update() {
	timediff := (glfw.GetTime() - explosion.Entity.lastUpdatedTime)
	if paused {
		explosion.MaxLifetime = explosion.MaxLifetime + timediff
	} else {
		addSize := 50 * timediff
		for v := range explosion.Entity.Shape.Vectors {
			explosion.Entity.Shape.Vectors[v].X = explosion.Entity.Shape.Vectors[v].X / explosion.Size * (explosion.Size + addSize)
			explosion.Entity.Shape.Vectors[v].Y = explosion.Entity.Shape.Vectors[v].Y / explosion.Size * (explosion.Size + addSize)
		}
		explosion.Size += addSize
	}
	explosion.Entity.Update()
}
Пример #11
0
func (this *Profiler) update() {
	frameCount := len(this.frameTimes)
	now := glfw.GetTime()
	this.frameTimes[this.frame%frameCount] = now - this.lastTime
	movingAverage := 0.0
	for _, f := range this.frameTimes {
		movingAverage += f
	}
	movingAverage /= float64(frameCount)
	if this.frame%frameCount == 0 {
		this.frameSpeed = movingAverage
	}
	this.lastTime = now
	this.frame++
}
Пример #12
0
func (me *context) Time() float64 {
	return glfw.GetTime()
}
Пример #13
0
func (this *Profiler) start() {
	this.lastTime = glfw.GetTime()
}
Пример #14
0
func (explosion *BigExplosion) IsAlive() bool {
	if glfw.GetTime() > explosion.createdTime+explosion.MaxLifetime {
		return false
	}
	return explosion.Entity.IsAlive()
}
Пример #15
0
func (ent *Entity) Update() {
	if paused {
		ent.lastUpdatedTime = glfw.GetTime()
	} else {
		timediff := (glfw.GetTime() - ent.lastUpdatedTime) * 500
		ent.lastUpdatedTime = glfw.GetTime()
		var rad float64 = ((ent.Angle) * math.Pi) / 180

		// rotation
		if ent.rotateLeft {
			ent.Angle = ent.Angle - (ent.TurnRate * timediff)
			if ent.Angle < 0 {
				ent.Angle += 360
			}
		} else if ent.rotateRight {
			ent.Angle = ent.Angle + (ent.TurnRate * timediff)
			if ent.Angle > 360 {
				ent.Angle -= 360
			}
		}

		/*
			0°		Sin(0), Cos(1)
			90°		Sin(1), Cos(0)
			180°	Sin(0), Cos(-1)
			270°	Sin(-1), Cos(0)
		*/
		if ent.accelerate {
			ent.VelocityX = ent.VelocityX + (ent.AccelerationRate * math.Sin(rad))
			ent.VelocityY = ent.VelocityY + (ent.AccelerationRate * math.Cos(rad))
		} else if ent.decelerate {
			ent.VelocityX = ent.VelocityX - (ent.AccelerationRate * math.Sin(rad))
			ent.VelocityY = ent.VelocityY - (ent.AccelerationRate * math.Cos(rad))
		}

		// max velocity
		totalVelocity := math.Sqrt(ent.VelocityX*ent.VelocityX + ent.VelocityY*ent.VelocityY)
		if totalVelocity > ent.MaxVelocity {
			ent.VelocityX = ent.VelocityX / totalVelocity
			ent.VelocityY = ent.VelocityY / totalVelocity
			ent.VelocityX = ent.VelocityX * ent.MaxVelocity
			ent.VelocityY = ent.VelocityY * ent.MaxVelocity
		}

		// move
		ent.PosX = ent.VelocityX*timediff + ent.PosX
		ent.PosY = ent.VelocityY*timediff + ent.PosY

		// crude zone clipping
		// TODO: for now it works, but needs to be updated for seamless clipping..
		if ent.PosX > gameWidth {
			ent.PosX -= gameWidth
		} else if ent.PosX < 0 {
			ent.PosX += gameWidth
		}
		if ent.PosY > gameHeight {
			ent.PosY -= gameHeight
		} else if ent.PosY < 0 {
			ent.PosY += gameHeight
		}
	}
}
Пример #16
0
func (a *Application) update() {
	a.Width, a.Height = a.window.GetSize()
	now := float32(glfw.GetTime())
	a.DeltaTime = now - a.Time
	a.Time = now
}
Пример #17
0
// GetTime returns the number of seconds since the timer was started.
//
// Please refer to http://www.glfw.org/docs/latest/input.html#time for more
// information.
func GetTime() float64 {
	return glfw.GetTime()
}
Пример #18
0
func (torpedo *Torpedo) IsAlive() bool {
	if glfw.GetTime() > torpedo.createdTime+torpedo.MaxLifetime {
		torpedo.Destroy()
	}
	return torpedo.Entity.IsAlive()
}
Пример #19
0
// update animation parameters
func animate() {
	angle = 100.0 * glfw.GetTime()
}
Пример #20
0
func main() {
	runtime.LockOSThread()

	if !glfw.Init() {
		fmt.Fprintf(os.Stderr, "Can't open GLFW")
		return
	}
	defer glfw.Terminate()

	glfw.WindowHint(glfw.Samples, 4)
	glfw.WindowHint(glfw.ContextVersionMajor, 3)
	glfw.WindowHint(glfw.ContextVersionMinor, 3)
	glfw.WindowHint(glfw.OpenglProfile, glfw.OpenglCoreProfile)
	glfw.WindowHint(glfw.OpenglForwardCompatible, glfw.True) // needed for macs

	window, err := glfw.CreateWindow(1024, 768, "Tutorial 8", nil, nil)
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v\n", err)
		return
	}

	window.MakeContextCurrent()

	gl.Init()
	gl.GetError() // Ignore error
	window.SetInputMode(glfw.StickyKeys, 1)
	window.SetCursorPosition(1024/2, 768/2)
	window.SetInputMode(glfw.Cursor, glfw.CursorHidden)

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

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

	gl.Enable(gl.CULL_FACE)

	camera := input.NewCamera(window)

	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, err := helper.TextureFromDDS("uvmap.DDS")
	if err != nil {
		fmt.Printf("Could not load texture: %v\n", err)
	}
	defer texture.Delete()
	texSampler := prog.GetUniformLocation("myTextureSampler")

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

	indices, indexedVertices, indexedUVs, indexedNormals := indexer.IndexVBOSlow(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.GetTime()
	nbFrames := 0
	// Equivalent to a do... while
	for ok := true; ok; ok = (window.GetKey(glfw.KeyEscape) != glfw.Press && !window.ShouldClose()) {

		currTime := glfw.GetTime()
		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 := mgl32.Ident4()

			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)

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

}
Пример #21
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() (mgl32.Mat4, mgl32.Mat4) {
	if mgl64.FloatEqual(-1.0, c.time) {
		c.time = glfw.GetTime()
	}

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

	xPos, yPos := c.window.GetCursorPosition()
	c.window.SetCursorPosition(width/2.0, height/2.0)

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

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

	right := mgl32.Vec3{
		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 c.window.GetKey(glfw.KeyUp) == glfw.Press || c.window.GetKey('W') == glfw.Press {
		c.pos = c.pos.Add(dir.Mul(float32(deltaT * speed)))
	}

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

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

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

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

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

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

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

	c.time = currTime

	return view, proj
}
Пример #22
0
func (bullet *Bullet) IsAlive() bool {
	if glfw.GetTime() > bullet.createdTime+bullet.MaxLifetime {
		return false
	}
	return bullet.Entity.IsAlive()
}
Пример #23
0
func (a *Application) HighFreqTime() float64 {
	// TODO: cgo call overhead probably makes this less useful...
	return glfw.GetTime()
}