Example #1
0
File: tr.go Project: skyview059/vu
// drawScene renders the 3D models consisting of one VAO
func (tag *trtag) drawScene() {
	gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
	tag.checkError("gl.Clear")
	gl.UseProgram(tag.shaders)
	tag.checkError("gl.UseProgram")
	gl.BindVertexArray(tag.vao)
	tag.checkError("gl.BindVertexArray")

	// Use a modelview matrix and quaternion to rotate the 3D object.
	tag.mvp64.SetQ(lin.NewQ().SetAa(0, 1, 0, lin.Rad(-tag.rotateAngle)))
	tag.mvp64.TranslateMT(0, 0, -4)
	tag.mvp.Set(tag.mvp64.Mult(tag.mvp64, tag.persp))
	gl.UniformMatrix4fv(tag.mvpRef, 1, false, tag.mvp.Pointer())
	if err := gl.GetError(); err != 0 {
		fmt.Printf("gl.UniformMatrix error %d\n", err)
	}
	gl.DrawElements(gl.TRIANGLES, int32(len(tag.faces)), gl.UNSIGNED_BYTE, 0)
	if err := gl.GetError(); err != 0 {
		fmt.Printf("gl.DrawElements error %d\n", err)
	}

	// cleanup
	gl.UseProgram(0)
	tag.checkError("gl.UseProgram-0")
	gl.BindVertexArray(0)
	tag.checkError("gl.BindVertexArray-0")

	// rotate based on time... not on how fast the computer runs.
	if time.Now().Sub(tag.lastTime).Seconds() > 0.01 {
		tag.rotateAngle += 1
		tag.lastTime = time.Now()
	}
}
Example #2
0
File: sf.go Project: skyview059/vu
// drawScene renders the shader-only scene.
func (sf *sftag) drawScene() {
	gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
	gl.UseProgram(sf.shaders)
	gl.BindVertexArray(sf.vao)
	timeSinceStart := time.Since(sf.sTime).Seconds()
	gl.Uniform1f(sf.gTime, float32(timeSinceStart))
	gl.Uniform2f(sf.sizes, 500, 500)
	gl.UniformMatrix4fv(sf.mvpref, 1, false, sf.mvp.Pointer())
	gl.DrawElements(gl.TRIANGLES, int32(len(sf.faces)), gl.UNSIGNED_BYTE, 0)

	// cleanup
	gl.UseProgram(0)
	gl.BindVertexArray(0)
}
Example #3
0
File: rt.go Project: skyview059/vu
// drawScene renders the single texture on the quad.
func (rt *rtrace) drawScene() {
	gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
	gl.UseProgram(rt.shaders)
	gl.Uniform1i(rt.tex2D, 0)
	gl.ActiveTexture(gl.TEXTURE0 + 0)
	gl.BindVertexArray(rt.vao)
	gl.UniformMatrix4fv(rt.mvpId, 1, false, rt.mvp.Pointer())
	gl.DrawElements(gl.TRIANGLES, int32(len(rt.faces)), gl.UNSIGNED_BYTE, 0)

	// cleanup
	gl.ActiveTexture(0)
	gl.UseProgram(0)
	gl.BindVertexArray(0)
}
Example #4
0
File: ld.go Project: toophy/vu
// render draws the scene consisting of one VAO
func (ld *ldtag) render() {
	gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
	gl.UseProgram(ld.shaders)
	gl.BindVertexArray(ld.vao)

	// use a model-view-projection matrix
	ld.mvp64.Set(lin.M4I).ScaleSM(0.5, 0.5, 0.5).TranslateMT(0, 0, -2)
	ld.mvp.Set(ld.mvp64.Mult(ld.mvp64, ld.persp))
	gl.UniformMatrix4fv(ld.mvpref, 1, false, ld.mvp.Pointer())
	gl.DrawElements(gl.TRIANGLES, ld.faceCount, gl.UNSIGNED_SHORT, 0)

	// cleanup
	gl.UseProgram(0)
	gl.BindVertexArray(0)
}
Example #5
0
// Renderer implementation.
// BindMesh copies the given mesh data to the GPU
// and initializes the vao and buffer references.
func (gc *opengl) BindMesh(vao *uint32, vdata map[uint32]Data, fdata Data) error {
	if glerr := gl.GetError(); glerr != gl.NO_ERROR {
		return fmt.Errorf("BindMesh needs to find and fix prior error %X", glerr)
	}

	// Reuse existing vao's.
	if *vao == 0 {
		gl.GenVertexArrays(1, vao)
	}
	gl.BindVertexArray(*vao)
	for _, vbuff := range vdata {
		vd, ok := vbuff.(*vertexData)
		if ok && vd.rebind {
			gc.bindVertexBuffer(vd)
			vd.rebind = false
		}
	}
	if glerr := gl.GetError(); glerr != gl.NO_ERROR {
		return fmt.Errorf("BindMesh failed to bind vb %X", glerr)
	}
	if fd, ok := fdata.(*faceData); ok {
		if fd.rebind {
			gc.bindFaceBuffer(fd)
			fd.rebind = false
		}
	}
	if glerr := gl.GetError(); glerr != gl.NO_ERROR {
		return fmt.Errorf("BindMesh failed to bind fb %X", glerr)
	}
	return nil
}
Example #6
0
File: opengl.go Project: toophy/vu
// Render implementation.
// FUTURE: all kinds of possible optimizations that would need to be
//         profiled before implementing.
//           • group by vao to avoid switching vao's.
//           • group by texture to avoid switching textures.
//           • use interleaved vertex data.
//           • uniform buffers http://www.opengl.org/wiki/Uniform_Buffer_Object.
//           • ... lots more possiblities... leave your fav here.
func (gc *opengl) Render(dr Draw) {
	d, ok := dr.(*draw)
	if !ok || d == nil {
		return
	}

	// switch state only if necessary.
	if gc.depthTest != d.depth {
		if d.depth {
			gl.Enable(gl.DEPTH_TEST)
		} else {
			gl.Disable(gl.DEPTH_TEST)
		}
		gc.depthTest = d.depth
	}

	// switch shaders only if necessary.
	if gc.shader != d.shader {
		gl.UseProgram(d.shader)
		gc.shader = d.shader
	}

	// Ask the model to bind its provisioned uniforms.
	// FUTURE: only need to bind uniforms that have changed.
	gc.bindUniforms(d)

	// bind the data buffers and render.
	gl.BindVertexArray(d.vao)
	switch d.mode {
	case LINES:
		gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE)
		gl.DrawElements(gl.LINES, d.numFaces, gl.UNSIGNED_SHORT, 0)
		gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL)
	case POINTS:
		gl.Enable(gl.PROGRAM_POINT_SIZE)
		gl.DrawArrays(gl.POINTS, 0, d.numVerts)
		gl.Disable(gl.PROGRAM_POINT_SIZE)
	case TRIANGLES:
		if len(d.texs) > 1 && d.texs[0].fn > 0 {
			// Multiple textures on one model specify which verticies they apply to.
			for _, tex := range d.texs {
				// Use the same texture unit and sampler. Just update which
				// image is being sampled.
				gl.BindTexture(gl.TEXTURE_2D, tex.tid)
				// fn is the number of triangles, 3 indicies per triangle.
				// f0 is the offset in triangles where each triangle has 3 indicies
				//    of 2 bytes (uShort) each.
				gl.DrawElements(gl.TRIANGLES, tex.fn*3, gl.UNSIGNED_SHORT, int64(3*2*tex.f0))
			}
		} else {
			// Single textures are handled with a standard bindUniforms
			gl.DrawElements(gl.TRIANGLES, d.numFaces, gl.UNSIGNED_SHORT, 0)
		}
	}
}
Example #7
0
File: tr.go Project: skyview059/vu
// initScene is one time initialization that creates a single VAO
func (tag *trtag) initScene() {
	tag.mvp64 = lin.NewM4()
	tag.persp = lin.NewM4().Persp(60, float64(600)/float64(600), 0.1, 50)
	tag.mvp = render.NewMvp()
	tag.initData()

	// Bind the OpenGL calls and dump some version info.
	gl.Init()
	fmt.Printf("%s %s", gl.GetString(gl.RENDERER), gl.GetString(gl.VERSION))
	fmt.Printf(" GLSL %s\n", gl.GetString(gl.SHADING_LANGUAGE_VERSION))

	// Gather the one scene into this one vertex array object.
	gl.GenVertexArrays(1, &tag.vao)
	gl.BindVertexArray(tag.vao)

	// create shaders
	tag.initShader()
	gl.UseProgram(tag.shaders)

	// vertex data.
	var vbuff uint32
	gl.GenBuffers(1, &vbuff)
	gl.BindBuffer(gl.ARRAY_BUFFER, vbuff)
	gl.BufferData(gl.ARRAY_BUFFER, int64(len(tag.verticies)*4), gl.Pointer(&(tag.verticies[0])), gl.STATIC_DRAW)
	vattr := uint32(gl.GetAttribLocation(tag.shaders, "in_v"))
	gl.EnableVertexAttribArray(vattr)
	gl.VertexAttribPointer(vattr, 3, gl.FLOAT, false, 0, 0)

	// colour data.
	var cbuff uint32
	gl.GenBuffers(1, &cbuff)
	gl.BindBuffer(gl.ARRAY_BUFFER, cbuff)
	gl.BufferData(gl.ARRAY_BUFFER, int64(len(tag.colour)*4), gl.Pointer(&(tag.colour[0])), gl.STATIC_DRAW)
	cattr := uint32(gl.GetAttribLocation(tag.shaders, "in_c"))
	gl.EnableVertexAttribArray(cattr)
	gl.VertexAttribPointer(cattr, 4, gl.FLOAT, false, 0, 0)

	// faces data.
	var ebuff uint32
	gl.GenBuffers(1, &ebuff)
	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebuff)
	gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, int64(len(tag.faces)), gl.Pointer(&(tag.faces[0])), gl.STATIC_DRAW)

	// set some state that doesn't need to change during drawing.
	gl.ClearColor(0.0, 0.0, 0.0, 1.0)
	gl.Enable(gl.CULL_FACE)
	gl.CullFace(gl.BACK)
}
Example #8
0
File: sf.go Project: toophy/vu
// initScene is one time initialization that creates a single VAO
func (sf *sftag) initScene() {
	sf.sTime = time.Now()
	sf.initData()

	// Bind the OpenGL calls and dump some version info.
	gl.Init()
	fmt.Printf("%s %s", gl.GetString(gl.RENDERER), gl.GetString(gl.VERSION))
	fmt.Printf(" GLSL %s\n", gl.GetString(gl.SHADING_LANGUAGE_VERSION))
	gl.GenVertexArrays(1, &sf.vao)
	gl.BindVertexArray(sf.vao)

	// vertex data.
	var vbuff uint32
	gl.GenBuffers(1, &vbuff)
	gl.BindBuffer(gl.ARRAY_BUFFER, vbuff)
	gl.BufferData(gl.ARRAY_BUFFER, int64(len(sf.verticies)*4), gl.Pointer(&(sf.verticies[0])), gl.STATIC_DRAW)
	gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0)
	gl.EnableVertexAttribArray(0)

	// faces data.
	var ebuff uint32
	gl.GenBuffers(1, &ebuff)
	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebuff)
	gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, int64(len(sf.faces)), gl.Pointer(&(sf.faces[0])), gl.STATIC_DRAW)

	// create texture and shaders after all the data has been set up.
	// renderer := render.New()
	shader := "fire"
	loader := load.NewLoader()
	vsrc, verr := loader.Vsh(shader)
	fsrc, ferr := loader.Fsh(shader)
	if verr == nil && ferr == nil {
		sf.shaders = gl.CreateProgram()
		if err := gl.BindProgram(sf.shaders, vsrc, fsrc); err != nil {
			fmt.Printf("Failed to create program: %s\n", err)
		}
		sf.mvpref = gl.GetUniformLocation(sf.shaders, "mvpm")
		sf.gTime = gl.GetUniformLocation(sf.shaders, "time")
		sf.sizes = gl.GetUniformLocation(sf.shaders, "screen")
		sf.mvp = render.NewMvp().Set(lin.NewM4().Ortho(0, 4, 0, 4, 0, 10))

		// set some state that doesn't need to change during drawing.
		gl.ClearColor(0.0, 0.0, 0.0, 1.0)
	}
}
Example #9
0
File: ld.go Project: toophy/vu
// initScene is called once on startup to load the 3D data.
func (ld *ldtag) initScene() {
	ld.persp = lin.NewM4()
	ld.mvp64 = lin.NewM4()
	ld.mvp = render.NewMvp()
	gl.Init()
	ldr := load.NewLoader()
	meshes, _ := ldr.Obj("monkey")
	mesh := meshes[0]
	ld.faceCount = int32(len(mesh.F))

	// Gather the one scene into this one vertex array object.
	gl.GenVertexArrays(1, &ld.vao)
	gl.BindVertexArray(ld.vao)

	// vertex data.
	var vbuff uint32
	gl.GenBuffers(1, &vbuff)
	gl.BindBuffer(gl.ARRAY_BUFFER, vbuff)
	gl.BufferData(gl.ARRAY_BUFFER, int64(len(mesh.V)*4), gl.Pointer(&(mesh.V[0])), gl.STATIC_DRAW)
	gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0)
	gl.EnableVertexAttribArray(0)

	// normal data.
	var nbuff uint32
	gl.GenBuffers(1, &nbuff)
	gl.BindBuffer(gl.ARRAY_BUFFER, nbuff)
	gl.BufferData(gl.ARRAY_BUFFER, int64(len(mesh.N)*4), gl.Pointer(&(mesh.N[0])), gl.STATIC_DRAW)
	gl.VertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0)
	gl.EnableVertexAttribArray(1)

	// faces data, uint32 in this case, so 4 bytes per element.
	var fbuff uint32
	gl.GenBuffers(1, &fbuff)
	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, fbuff)
	gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, int64(len(mesh.F)*2), gl.Pointer(&(mesh.F[0])), gl.STATIC_DRAW)

	ld.initShader()
	gl.ClearColor(0.2, 0.2, 0.2, 1.0)
	gl.Enable(gl.DEPTH_TEST)
	gl.Enable(gl.CULL_FACE)

	// set the initial perspetive matrix.
	ld.resize(0, 0, 800, 600)
}
Example #10
0
File: rt.go Project: skyview059/vu
// initRender is one time initialization that creates a single VAO
// to display a single ray trace generated texture.
func (rt *rtrace) initRender() {
	rt.verts = []float32{ // four verticies for a quad.
		0, 0, 0,
		4, 0, 0,
		0, 4, 0,
		4, 4, 0,
	}
	rt.faces = []uint8{ // create quad from 2 triangles.
		0, 2, 1,
		1, 2, 3,
	}
	rt.uvs = []float32{ // texture coordinates to sample the image.
		0, 0,
		1, 0,
		0, 1,
		1, 1,
	}

	// Start up OpenGL and create a single vertex array object.
	gl.Init()
	gl.GenVertexArrays(1, &rt.vao)
	gl.BindVertexArray(rt.vao)

	// vertex data.
	var vbuff uint32
	gl.GenBuffers(1, &vbuff)
	gl.BindBuffer(gl.ARRAY_BUFFER, vbuff)
	gl.BufferData(gl.ARRAY_BUFFER, int64(len(rt.verts)*4), gl.Pointer(&(rt.verts[0])), gl.STATIC_DRAW)
	gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0)
	gl.EnableVertexAttribArray(0)

	// faces data.
	var ebuff uint32
	gl.GenBuffers(1, &ebuff)
	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebuff)
	gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, int64(len(rt.faces)), gl.Pointer(&(rt.faces[0])), gl.STATIC_DRAW)

	// texture coordatinates
	var tbuff uint32
	gl.GenBuffers(1, &tbuff)
	gl.BindBuffer(gl.ARRAY_BUFFER, tbuff)
	gl.BufferData(gl.ARRAY_BUFFER, int64(len(rt.uvs)*4), gl.Pointer(&(rt.uvs[0])), gl.STATIC_DRAW)
	var tattr uint32 = 2
	gl.VertexAttribPointer(tattr, 2, gl.FLOAT, false, 0, 0)
	gl.EnableVertexAttribArray(tattr)

	// use ray trace generated texture image.
	bounds := rt.img.Bounds()
	width, height := int32(bounds.Dx()), int32(bounds.Dy())
	ptr := gl.Pointer(&(rt.img.Pix[0]))
	gl.GenTextures(1, &rt.texId)
	gl.BindTexture(gl.TEXTURE_2D, rt.texId)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
	gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, ptr)

	// texture sampling shader.
	loader := load.NewLoader()
	shader := "tuv"
	vsrc, verr := loader.Vsh(shader)
	fsrc, ferr := loader.Fsh(shader)
	if verr != nil || ferr != nil {
		log.Fatalf("Failed to load shaders %s %s\n", verr, ferr)
	}
	rt.shaders = gl.CreateProgram()
	if err := gl.BindProgram(rt.shaders, vsrc, fsrc); err != nil {
		log.Fatalf("Failed to create program: %s\n", err)
	}
	rt.mvpId = gl.GetUniformLocation(rt.shaders, "mvpm")
	rt.tex2D = gl.GetUniformLocation(rt.shaders, "sampler2D")
	rt.mvp = render.NewMvp().Set(lin.NewM4().Ortho(0, 4, 0, 4, 0, 10))

	// set some state that doesn't need to change during drawing.
	gl.ClearColor(0.0, 0.0, 0.0, 1.0)
}