func (objectLoader *WavefrontObject) DrawObject(shaderProgram uint32) {
	for _, object := range objectLoader.Objects {
		// Reads the uniform Locations
		modelUniform := gl.GetUniformLocation(shaderProgram, gl.Str("model\x00"))
		ambientUniform := gl.GetUniformLocation(shaderProgram, gl.Str("ambient\x00"))
		diffuseUniform := gl.GetUniformLocation(shaderProgram, gl.Str("diffuse\x00"))
		specularUniform := gl.GetUniformLocation(shaderProgram, gl.Str("specular\x00"))
		emissiveUniform := gl.GetUniformLocation(shaderProgram, gl.Str("emissive\x00"))

		// Send our uniforms variables to the currently bound shader
		if object.Material != nil {
			gl.Uniform4f(ambientUniform, object.Material.KaR, object.Material.KaG, object.Material.KaB, object.Material.Tr)  // Ambient colour.
			gl.Uniform4f(diffuseUniform, object.Material.KdR, object.Material.KdG, object.Material.KdB, object.Material.Tr)  // Diffuse colour.
			gl.Uniform4f(specularUniform, object.Material.KsR, object.Material.KsG, object.Material.KsB, object.Material.Tr) // Specular colour.
			gl.Uniform4f(emissiveUniform, object.Material.KeR, object.Material.KeG, object.Material.KeB, object.Material.Tr) // Emissive colour.

			if object.Material.Texture != 0 {
				textureUniform := gl.GetUniformLocation(shaderProgram, gl.Str("DiffuseTextureSampler\x00"))
				gl.Uniform1i(textureUniform, 0)

				normalTextureUniform := gl.GetUniformLocation(shaderProgram, gl.Str("NormalTextureSampler\x00"))
				gl.Uniform1i(normalTextureUniform, 1)

				specularTextureUniform := gl.GetUniformLocation(shaderProgram, gl.Str("SpecularTextureSampler\x00"))
				gl.Uniform1i(specularTextureUniform, 2)

				gl.ActiveTexture(gl.TEXTURE0)
				gl.BindTexture(gl.TEXTURE_2D, object.Material.Texture)

				gl.ActiveTexture(gl.TEXTURE1)
				gl.BindTexture(gl.TEXTURE_2D, object.Material.NormalMap)

				gl.ActiveTexture(gl.TEXTURE2)
				gl.BindTexture(gl.TEXTURE_2D, object.Material.SpecularMap)
			}

			if object.Material.Tr < 1.0 {
				// Enables Transparencies
				gl.Enable(gl.BLEND)
				//				gl.BlendFunc(gl.SRC_COLOR, gl.ONE)
				//				gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
				gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
			}
		}

		// Geometry
		var size int32 // Used to get the byte size of the element (vertex index) array

		gl.UniformMatrix4fv(modelUniform, 1, false, &object.Model[0])

		// Get the vertices uniform position
		verticesUniform := uint32(gl.GetAttribLocation(shaderProgram, gl.Str("position\x00")))
		normalsUniform := uint32(gl.GetAttribLocation(shaderProgram, gl.Str("normal\x00")))
		textureCoordinatesUniform := uint32(gl.GetAttribLocation(shaderProgram, gl.Str("texcoord\x00")))

		// Describe our vertices array to OpenGL (it can't guess its format automatically)

		gl.BindBuffer(gl.ARRAY_BUFFER, object.VertexBufferObjectVertices)
		gl.VertexAttribPointer(
			verticesUniform, // attribute index
			3,               // number of elements per vertex, here (x,y,z)
			gl.FLOAT,        // the type of each element
			false,           // take our values as-is
			0,               // no extra data between each position
			nil,             // offset of first element
		)

		gl.EnableVertexAttribArray(normalsUniform)
		gl.BindBuffer(gl.ARRAY_BUFFER, object.VertexBufferObjectNormals)
		gl.VertexAttribPointer(
			normalsUniform, // attribute
			3,              // number of elements per vertex, here (x,y,z)
			gl.FLOAT,       // the type of each element
			false,          // take our values as-is
			0,              // no extra data between each position
			nil,            // offset of first element
		)

		gl.EnableVertexAttribArray(textureCoordinatesUniform)
		gl.BindBuffer(gl.ARRAY_BUFFER, object.VertexBufferObjectTextureCoords)
		gl.VertexAttribPointer(
			textureCoordinatesUniform, // attribute
			2,        // number of elements per vertex, here (u,v)
			gl.FLOAT, // the type of each element
			false,    // take our values as-is
			0,        // no extra data between each position
			nil,      // offset of first element
		)

		size = int32(len(object.Vertex))

		gl.PointSize(3.0)

		// Enable this line to show model in wireframe
		switch objectLoader.DrawMode {
		case 1:
			gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE)
		default:
			gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL)
		}

		gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, object.VertexBufferObjectFaces)
		gl.GetBufferParameteriv(gl.ELEMENT_ARRAY_BUFFER, gl.BUFFER_SIZE, &size)
		gl.DrawElements(gl.TRIANGLES, int32(len(object.Faces)), gl.UNSIGNED_SHORT, nil)
		//		gl.DrawElements(gl.POINTS, int32(len(object.Faces)), gl.UNSIGNED_SHORT, nil)

		// Disables transparencies
		gl.Disable(gl.BLEND)
	}
}
Ejemplo n.º 2
0
/* Enable vertex attributes and draw object
Could improve efficiency by moving the vertex attribute pointer functions to the
create object but this method is more general
This code is almost untouched fomr the tutorial code except that I changed the
number of elements per vertex from 4 to 3*/
func (terrain *Terrain) DrawObject(shaderProgram uint32) {
	toneUniform := gl.GetAttribLocation(shaderProgram, gl.Str("tone\x00"))
	gl.Uniform4f(toneUniform, terrain.ColorTone.X(), terrain.ColorTone.Y(), terrain.ColorTone.Z(), terrain.ColorTone.W())
	//	gl.Uniform4f(toneUniform, 0.0, 1.0, 0.5, 1.0)
	//	gl.Uniform4fv(toneUniform, 1, &terrain.ColorTone[0])

	// Reads the uniform Locations
	modelUniform := gl.GetUniformLocation(shaderProgram, gl.Str("model\x00"))

	// Send our uniforms variables to the currently bound shader
	gl.UniformMatrix4fv(modelUniform, 1, false, &terrain.Model[0])

	// Get the vertices uniform position
	verticesUniform := uint32(gl.GetAttribLocation(shaderProgram, gl.Str("position\x00")))
	normalsUniform := uint32(gl.GetAttribLocation(shaderProgram, gl.Str("normal\x00")))
	colorsUniform := uint32(gl.GetAttribLocation(shaderProgram, gl.Str("colour\x00")))

	// Describe our vertices array to OpenGL (it can't guess its format automatically)
	gl.EnableVertexAttribArray(verticesUniform)
	gl.BindBuffer(gl.ARRAY_BUFFER, terrain.VBOVertices)
	gl.VertexAttribPointer(
		verticesUniform, // attribute index
		3,               // number of elements per vertex, here (x,y,z)
		gl.FLOAT,        // the type of each element
		false,           // take our values as-is
		0,               // no extra data between each position
		nil,             // offset of first element
	)

	gl.EnableVertexAttribArray(normalsUniform)
	gl.BindBuffer(gl.ARRAY_BUFFER, terrain.VBONormals)
	gl.VertexAttribPointer(
		normalsUniform, // attribute
		3,              // number of elements per vertex, here (x,y,z)
		gl.FLOAT,       // the type of each element
		false,          // take our values as-is
		0,              // no extra data between each position
		nil,            // offset of first element
	)

	gl.EnableVertexAttribArray(colorsUniform)
	gl.BindBuffer(gl.ARRAY_BUFFER, terrain.VBOColors)
	gl.VertexAttribPointer(
		colorsUniform, // attribute
		3,             // number of elements per vertex, here (x,y,z)
		gl.FLOAT,      // the type of each element
		false,         // take our values as-is
		0,             // no extra data between each position
		nil,           // offset of first element
	)

	size := int32(len(terrain.Indices))

	gl.PointSize(3.0)
	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, terrain.VBOIndices)
	gl.GetBufferParameteriv(gl.ELEMENT_ARRAY_BUFFER, gl.BUFFER_SIZE, &size)

	// Enable this line to show model in wireframe
	switch terrain.DrawMode {
	case 1:
		gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE)
	case 2:
		gl.DrawArrays(gl.POINTS, 0, int32(len(terrain.Vertices)))
		//		gl.DrawElements(gl.POINTS, int32(len(terrain.Indices)), gl.UNSIGNED_SHORT, nil)
		return
	default:
		gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL)
	}

	var location int = 0
	/* Draw the triangle strips */
	for i := uint32(0); i < terrain.XSize-1; i++ {
		location = SizeOfUint16 * int(i*terrain.ZSize*2)
		gl.DrawElements(gl.TRIANGLE_STRIP, int32(terrain.ZSize*2), gl.UNSIGNED_SHORT, gl.PtrOffset(location))
	}

	//	gl.DrawElements(
	//		gl.TRIANGLE_STRIP,
	//		len(terrain.Indices),
	//		gl.UNSIGNED_SHORT,
	//		nil,
	//	)
}