diff options
| -rw-r--r-- | app.go | 7 | ||||
| -rw-r--r-- | geometry.go | 5 | ||||
| -rw-r--r-- | graphics.go | 71 | ||||
| -rw-r--r-- | main.go | 6 | ||||
| -rw-r--r-- | stl.go | 52 | 
5 files changed, 89 insertions, 52 deletions
| @@ -41,7 +41,8 @@ func newApp(stl *StlModel) App {  	glfw.WindowHint(glfw.Samples, 16)  // anti-aliasing  	log.Println("Creating Window") -	app.window, err = glfw.CreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE, nil, nil) +	app.window, err = glfw.CreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, +		WINDOW_TITLE, nil, nil)  	if err != nil {  		panic(err)  	} @@ -58,7 +59,9 @@ func (application *App) handle() {  	// generate and set transformation  	trafo := application.homeTrafo -	trafo = mgl32.HomogRotate3D(float32(glfw.GetTime()) * 0.4 * 6.282, mgl32.Vec3{0.1, 1, 0}).Mul4(trafo)  // apply time-based rotation +	trafo = mgl32.HomogRotate3D( +		float32(glfw.GetTime()) * 0.4 * 6.282, +		mgl32.Vec3{0.1, 1, 0}).Mul4(trafo)  // apply time-based rotation  	application.graphics.setTrafo(trafo)  } diff --git a/geometry.go b/geometry.go index 1fc516a..80420a6 100644 --- a/geometry.go +++ b/geometry.go @@ -58,7 +58,10 @@ func (s Surface) getHomeView() mgl32.Mat4 {  	// calculate and return transformation  	var trafo mgl32.Mat4 = mgl32.Ident4() -	trafo = mgl32.Translate3D(-center.scalars[0], -center.scalars[1], -center.scalars[2]).Mul4(trafo) +	trafo = mgl32.Translate3D( +		-center.scalars[0], +		-center.scalars[1], +		-center.scalars[2]).Mul4(trafo)  	trafo = mgl32.Scale3D(zoom, zoom, zoom).Mul4(trafo)  	return trafo diff --git a/graphics.go b/graphics.go index fc195eb..a952e40 100644 --- a/graphics.go +++ b/graphics.go @@ -20,37 +20,43 @@ const (  	// vertex shader to draw points  	VERTEX_SHADER = ` -        #version 410 +#version 410 -		in vec3 vp_model;  // vertex position in model coordinate system -		in vec3 vn_model;  // vertex normal in model coordinate system +in vec3 vp_model;  // vertex position in model coordinate system +in vec3 vn_model;  // vertex normal in model coordinate system -		uniform mat4 trafo;  // one single transformation matrix +uniform mat4 trafo;  // one single transformation matrix -		out vec3 vn_eye;  // vertex normal in eye coordinate system +out vec3 vn_eye;  // vertex normal in eye coordinate system -        void main() { -			vn_eye = vec3(trafo * vec4(vn_model, 0.0));  // 0.0 because translation is ignored -            gl_Position = trafo * vec4(vp_model, 1.0); -        } -    ` + "\x00" +void main() { + +	// 0.0 because translation is ignored +	vn_eye = vec3(trafo * vec4(vn_model, 0.0)); + +	gl_Position = trafo * vec4(vp_model, 1.0); + +} +	` + "\x00"  	// fragment shader to draw surfaces  	FRAGMENT_SHADER = ` -        #version 410 +#version 410 -		in vec3 vn_eye;  // vertex normal in eye coordinate system +in vec3 vn_eye;  // vertex normal in eye coordinate system -        out vec4 frag_colour; +out vec4 frag_colour; -        void main() { -			vec3 ambient = vec3(0.3, 0.3, 0.3);  // ambient colour is static -			vec3 light_vector_eye = vec3(1.0, 0.1, -1.0); -			vec3 diffuse = (vec3(1, 1, 1) - ambient) * max(dot(normalize(vn_eye), normalize(light_vector_eye)), 0.0); -			vec3 color = (ambient + diffuse) * vec3(0, 0, 1);  // hard-coded vector is color in RGB format -            frag_colour = vec4(color, 1.0);  // RGBA color format -        } -    ` + "\x00" +void main() { +	vec3 ambient = vec3(0.3, 0.3, 0.3);  // ambient colour is static +	vec3 light_vector_eye = vec3(1.0, 0.1, -1.0); +	vec3 diffuse = (vec3(1, 1, 1) - ambient) * max(dot(normalize(vn_eye), +		normalize(light_vector_eye)), 0.0); +	// hard-coded vector is color in RGB format: +	vec3 color = (ambient + diffuse) * vec3(0, 0, 1); +	frag_colour = vec4(color, 1.0);  // RGBA color format +} +	` + "\x00"  )  type Graphics struct { @@ -83,7 +89,8 @@ func newGraphics() Graphics {  	if err != nil {  		log.Fatal(err)  	} -	graphics.fragmentShader, err = compileShader(FRAGMENT_SHADER, gl.FRAGMENT_SHADER) +	graphics.fragmentShader, err = compileShader(FRAGMENT_SHADER, +		gl.FRAGMENT_SHADER)  	if err != nil {  		log.Fatal(err)  	} @@ -99,8 +106,6 @@ func newGraphics() Graphics {  	graphics.vao = makeVao(vertices, vertex_normals)  	// create transformation matrix -	//graphics.trafo = mgl32.HomogRotate3D(float32(glfw.GetTime()) * OMEGA, mgl32.Vec3{ROT_X, ROT_Y, ROT_Z}) -	//graphics.trafoUniform = gl.GetUniformLocation(graphics.program, gl.Str("trafo\x00"))  	gl.UniformMatrix4fv(graphics.trafoUniform, 1, false, &graphics.trafo[0])  	return graphics @@ -110,11 +115,13 @@ func (graphics Graphics) draw() {  	gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)  	gl.UseProgram(graphics.program) -	//graphics.trafo = mgl32.HomogRotate3D(float32(glfw.GetTime()) * OMEGA, mgl32.Vec3{ROT_X, ROT_Y, ROT_Z})  	gl.UniformMatrix4fv(graphics.trafoUniform, 1, false, &graphics.trafo[0])  	gl.BindVertexArray(graphics.vao) -	gl.DrawArrays(gl.TRIANGLES, 0, int32(len(vertices)/3))  // POINTS, LINES, LINE_STRIP, LINE_LOOP, TRIANGLES, TRIANGLE_STRIP, TRIANGLE_FAN + +	// or alternatively POINTS, LINES, LINE_STRIP, LINE_LOOP, TRIANGLES, +	// TRIANGLE_STRIP, TRIANGLE_FAN +	gl.DrawArrays(gl.TRIANGLES, 0, int32(len(vertices)/3))  }  // makeVao initializes and returns a vertex array from the points provided. @@ -125,13 +132,15 @@ func makeVao(points []float32, normals []float32) uint32 {  	var position_vbo uint32  // VBO ID  	gl.GenBuffers(1, &position_vbo)  	gl.BindBuffer(gl.ARRAY_BUFFER, position_vbo) -	gl.BufferData(gl.ARRAY_BUFFER, 4*len(points), gl.Ptr(points), gl.STATIC_DRAW) +	gl.BufferData(gl.ARRAY_BUFFER, 4*len(points), gl.Ptr(points), +		gl.STATIC_DRAW)  	// vertex buffer object (VBO) for normals:  	var normal_vbo uint32  // VBO ID  	gl.GenBuffers(1, &normal_vbo)  	gl.BindBuffer(gl.ARRAY_BUFFER, normal_vbo) -	gl.BufferData(gl.ARRAY_BUFFER, 4*len(normals), gl.Ptr(normals), gl.STATIC_DRAW) +	gl.BufferData(gl.ARRAY_BUFFER, 4*len(normals), gl.Ptr(normals),  +		gl.STATIC_DRAW)  	// vertex array objects (VAO) to combine VBOs:  	var vao uint32  // VAO ID @@ -140,12 +149,14 @@ func makeVao(points []float32, normals []float32) uint32 {  	// connect position_vbo to vao  	gl.BindBuffer(gl.ARRAY_BUFFER, position_vbo) -	gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 0, nil)  // tell GL to use 3D float vectors +	// tell GL to use 3D float vectors: +	gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 0, nil)  	gl.EnableVertexAttribArray(0)  	// connect normal_vbo to vao  	gl.BindBuffer(gl.ARRAY_BUFFER, normal_vbo) -	gl.VertexAttribPointer(1, 3, gl.FLOAT, false, 0, nil)  // tell GL to use 3D float vectors +	// tell GL to use 3D float vectors: +	gl.VertexAttribPointer(1, 3, gl.FLOAT, false, 0, nil)  	gl.EnableVertexAttribArray(1)  	return vao @@ -30,7 +30,8 @@ func main() {  	}  	vertices,vertex_normals = stl.toVertices() -	// lock this program to one OS thread (details: https://golang.org/pkg/runtime/#LockOSThread) +	// lock this program to one OS thread +	// (details: https://golang.org/pkg/runtime/#LockOSThread)  	log.Println("Locking OS thread")  	runtime.LockOSThread() @@ -50,7 +51,8 @@ func main() {  }  func (args *cliArgs) read() { -	flag.BoolVar(&args.debugOutput, "debug", false, "enable to print log output") +	flag.BoolVar(&args.debugOutput, "debug", false, +		"enable to print log output")  	flag.Parse()  	args.filePath = flag.Arg(0)  } @@ -50,8 +50,11 @@ func ReadBinaryStlFile(filePath string) (StlModel, error) {  	return model,nil  } -// parse the 50 bytes of the STL file representing a triangle (surface normal is ignored) -func ParseBinaryStlTriangle(data []byte) *Triangle {  // FIXME: This function should only accept 50 byte slices/arrays +// parse the 50 bytes of the STL file representing a triangle (surface normal +// is ignored) +func ParseBinaryStlTriangle(data []byte) *Triangle { + +	// FIXME: This function should only accept 50 byte slices/arrays  	// allocate a new triangle and three corner points on the heap  	triangle := new(Triangle) @@ -60,24 +63,34 @@ func ParseBinaryStlTriangle(data []byte) *Triangle {  // FIXME: This function sh  	triangle.points[2] = new(Point)  	// parse x, y and z coordinate for corner point a -	triangle.points[0].scalars[0] = math.Float32frombits(binary.LittleEndian.Uint32(data[12:16])) -	triangle.points[0].scalars[1] = math.Float32frombits(binary.LittleEndian.Uint32(data[16:20])) -	triangle.points[0].scalars[2] = math.Float32frombits(binary.LittleEndian.Uint32(data[20:24])) +	triangle.points[0].scalars[0] = math.Float32frombits( +		binary.LittleEndian.Uint32(data[12:16])) +	triangle.points[0].scalars[1] = math.Float32frombits( +		binary.LittleEndian.Uint32(data[16:20])) +	triangle.points[0].scalars[2] = math.Float32frombits( +		binary.LittleEndian.Uint32(data[20:24]))  	// parse x, y and z coordinate for corner point b -	triangle.points[1].scalars[0] = math.Float32frombits(binary.LittleEndian.Uint32(data[24:28])) -	triangle.points[1].scalars[1] = math.Float32frombits(binary.LittleEndian.Uint32(data[28:32])) -	triangle.points[1].scalars[2] = math.Float32frombits(binary.LittleEndian.Uint32(data[32:36])) +	triangle.points[1].scalars[0] = math.Float32frombits( +		binary.LittleEndian.Uint32(data[24:28])) +	triangle.points[1].scalars[1] = math.Float32frombits( +		binary.LittleEndian.Uint32(data[28:32])) +	triangle.points[1].scalars[2] = math.Float32frombits( +		binary.LittleEndian.Uint32(data[32:36]))  	// parse x, y and z coordinate for corner point c -	triangle.points[2].scalars[0] = math.Float32frombits(binary.LittleEndian.Uint32(data[36:40])) -	triangle.points[2].scalars[1] = math.Float32frombits(binary.LittleEndian.Uint32(data[40:44])) -	triangle.points[2].scalars[2] = math.Float32frombits(binary.LittleEndian.Uint32(data[44:48])) +	triangle.points[2].scalars[0] = math.Float32frombits( +		binary.LittleEndian.Uint32(data[36:40])) +	triangle.points[2].scalars[1] = math.Float32frombits( +		binary.LittleEndian.Uint32(data[40:44])) +	triangle.points[2].scalars[2] = math.Float32frombits( +		binary.LittleEndian.Uint32(data[44:48]))  	return triangle  } -func (stl StlModel) toVertices() (vertex_position []float32, vertex_normal []float32) { +func (stl StlModel) toVertices() (vertex_position []float32, +	vertex_normal []float32) {  	vertex_position = make([]float32, stl.numberOfTriangles * 9)  	vertex_normal = make([]float32, stl.numberOfTriangles * 9) @@ -90,20 +103,25 @@ func (stl StlModel) toVertices() (vertex_position []float32, vertex_normal []flo  			for scalarIndex,scalar := range(point.scalars) { -				vertex_position[triangleIndex*9+pointIndex*3+scalarIndex] = scalar +				i := triangleIndex * 9 + pointIndex * 3 + scalarIndex +				vertex_position[i] = scalar  			}  		}  		// calculate normal -		point0 = Vector3{triangle.points[0].scalars[0], triangle.points[0].scalars[1], triangle.points[0].scalars[2]} -		point1 = Vector3{triangle.points[1].scalars[0], triangle.points[1].scalars[1], triangle.points[1].scalars[2]} -		point2 = Vector3{triangle.points[2].scalars[0], triangle.points[2].scalars[1], triangle.points[2].scalars[2]} +		point0 = Vector3{triangle.points[0].scalars[0], +			triangle.points[0].scalars[1], triangle.points[0].scalars[2]} +		point1 = Vector3{triangle.points[1].scalars[0], +			triangle.points[1].scalars[1], triangle.points[1].scalars[2]} +		point2 = Vector3{triangle.points[2].scalars[0], +			triangle.points[2].scalars[1], triangle.points[2].scalars[2]}  		edge0 = point1.subtract(point0)  		edge1 = point2.subtract(point1)  		normal = edge0.crossProduct(edge1) -		normal.divideScalar(2.0)  // length of normal vector corresponds to triangle area +		normal.divideScalar(2.0)  // length of normal vector corresponds to +		                          // triangle area  		// save normal to each vertex of the triangle  		for i := 0; i<3; i++ { | 
