Esempio n. 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()
	}
}
Esempio n. 2
0
File: text.go Progetto: mik3cap/glop
// RenderString must be called on the render thread.  x and y are the initial position of the pen,
// in screen coordinates, and height is the height of a full line of text, in screen coordinates.
func (d *Dictionary) RenderString(str string, x, y, height float64) {
	if str == "" {
		return
	}
	// No synchronization necessary because everything is run serially on the render thread anyway.
	if d.strs == nil {
		d.strs = make(map[string]strData)
	}
	data, ok := d.strs[str]
	if !ok {
		data = d.bindString(str)
		d.strs[str] = data
	}

	render.EnableShader("glop.font")
	defer render.EnableShader("")

	gl.ActiveTexture(gl.TEXTURE0)
	gl.BindTexture(gl.TEXTURE_2D, d.atlas.texture)
	location, _ := render.GetUniformLocation("glop.font", "tex")
	gl.Uniform1i(location, 0)
	gl.BindSampler(0, d.atlas.sampler)

	location, _ = render.GetUniformLocation("glop.font", "height")
	gl.Uniform1f(location, float32(height))

	var viewport [4]int32
	gl.GetIntegerv(gl.VIEWPORT, &viewport[0])
	location, _ = render.GetUniformLocation("glop.font", "screen")
	gl.Uniform2f(location, float32(viewport[2]), float32(viewport[3]))

	location, _ = render.GetUniformLocation("glop.font", "pen")
	gl.Uniform2f(location, float32(x)+float32(viewport[0]), float32(y)+float32(viewport[1]))

	location, _ = render.GetUniformLocation("glop.font", "textColor")
	gl.Uniform3f(location, d.color[0], d.color[1], d.color[2])

	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
	gl.BindVertexArray(data.varrays[0])
	gl.DrawArrays(gl.TRIANGLES, 0, data.count)
}
Esempio n. 3
0
File: text.go Progetto: mik3cap/glop
// bindString generates all of the vertex buffers and vertex arrays for a single constant line of
// text.  No error checking is done.
func (d *Dictionary) bindString(str string) strData {
	var data strData
	gl.GenVertexArrays(1, &data.varrays[0])
	gl.BindVertexArray(data.varrays[0])
	gl.GenBuffers(2, &data.vbuffers[0])

	var positions, texcoords []float32

	var pen pos
	var prev rune
	for _, r := range str {
		ri := d.Runes[r]

		var scale float32 = 1.0 / float32(d.GlyphMax.Dy())

		var posMin, posMax pos
		posMin.x = pen.x + float32(ri.GlyphBounds.Min.X)*scale
		posMin.y = pen.y + float32(ri.GlyphBounds.Min.Y)*scale
		posMax.x = pen.x + float32(ri.GlyphBounds.Max.X)*scale
		posMax.y = pen.y + float32(ri.GlyphBounds.Max.Y)*scale

		var texMin, texMax pos
		texMin.x = float32(ri.PixBounds.Min.X) / float32(d.Dx)
		texMin.y = float32(ri.PixBounds.Min.Y) / float32(d.Dy)
		texMax.x = float32(ri.PixBounds.Max.X) / float32(d.Dx)
		texMax.y = float32(ri.PixBounds.Max.Y) / float32(d.Dy)
		pen.x += float32(ri.AdvanceWidth) * scale
		pen.x += float32(d.Kerning[RunePair{prev, r}]) * scale
		// pen.x -= float32(d.Kerning[RunePair{prev, r}]) * scale

		positions = append(positions, posMin.x) // lower left
		positions = append(positions, posMin.y)
		positions = append(positions, posMin.x) // upper left
		positions = append(positions, posMax.y)
		positions = append(positions, posMax.x) // upper right
		positions = append(positions, posMax.y)
		positions = append(positions, posMin.x) // lower left
		positions = append(positions, posMin.y)
		positions = append(positions, posMax.x) // upper right
		positions = append(positions, posMax.y)
		positions = append(positions, posMax.x) // lower right
		positions = append(positions, posMin.y)
		texcoords = append(texcoords, texMin.x) // lower left
		texcoords = append(texcoords, texMax.y)
		texcoords = append(texcoords, texMin.x) // upper left
		texcoords = append(texcoords, texMin.y)
		texcoords = append(texcoords, texMax.x) // upper right
		texcoords = append(texcoords, texMin.y)
		texcoords = append(texcoords, texMin.x) // lower left
		texcoords = append(texcoords, texMax.y)
		texcoords = append(texcoords, texMax.x) // upper right
		texcoords = append(texcoords, texMin.y)
		texcoords = append(texcoords, texMax.x) // lower right
		texcoords = append(texcoords, texMax.y)

		prev = r
	}
	data.count = int32(len(positions))
	gl.BindBuffer(gl.ARRAY_BUFFER, data.vbuffers[0])
	gl.BufferData(gl.ARRAY_BUFFER, len(positions)*int(unsafe.Sizeof(positions[0])), gl.Ptr(&positions[0]), gl.STATIC_DRAW)
	location, _ := render.GetAttribLocation("glop.font", "position")
	gl.EnableVertexAttribArray(uint32(location))
	gl.VertexAttribPointer(uint32(location), 2, gl.FLOAT, false, 0, gl.PtrOffset(0))

	gl.BindBuffer(gl.ARRAY_BUFFER, data.vbuffers[1])
	gl.BufferData(gl.ARRAY_BUFFER, len(texcoords)*int(unsafe.Sizeof(texcoords[0])), gl.Ptr(&texcoords[0]), gl.STATIC_DRAW)
	location, _ = render.GetAttribLocation("glop.font", "texCoord")
	gl.EnableVertexAttribArray(uint32(location))
	gl.VertexAttribPointer(uint32(location), 2, gl.FLOAT, false, 0, gl.PtrOffset(0))

	return data
}