forked from go-gl-legacy/glu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tesselator.go
113 lines (91 loc) · 3.06 KB
/
tesselator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Copyright 2012 The go-gl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package glu
// #ifdef __APPLE__
// #include <OpenGL/glu.h>
// #else
// #include <GL/glu.h>
// #endif
import "C"
import "github.com/go-gl/gl"
import "unsafe"
// Opaque object used for book keeping on the go side.
type Tesselator struct {
tess *C.GLUtesselator
polyData interface{}
// vertData keeps references to the vertices specifed by TessVertex
// so that the garbage collector does not invalidate them.
vertData []*vertexDataWrapper
// vertLocs stores a copy of the vertices' locations as specified
// to TessVertex. Again, so the garbage collector doesn't get them.
vertLocs [][3]float64
beginData TessBeginHandler
vertexData TessVertexHandler
endData TessEndHandler
errorData TessErrorHandler
edgeFlagData TessEdgeFlagHandler
combineData TessCombineHandler
}
// Wrapper around an interface. Does go not support (*interface{})(ptr)?
type vertexDataWrapper struct {
data interface{}
}
// Create a new tesselator.
func NewTess() (tess *Tesselator) {
tess = new(Tesselator)
tess.tess = C.gluNewTess()
if tess.tess == nil {
panic("Out of memory.")
}
return
}
// Clean up resources held by the tesselator. Go's garbage collector cannot
// do this automatically.
func (tess *Tesselator) Delete() {
C.gluDeleteTess(tess.tess)
tess.tess = nil
}
// Begin the drawing of the polygon, with the data parameter that will
// be provided to callbacks.
func (tess *Tesselator) BeginPolygon(data interface{}) {
tess.polyData = data
C.gluTessBeginPolygon(tess.tess, unsafe.Pointer(tess))
}
// End the drawing of the polygon.
func (tess *Tesselator) EndPolygon() {
C.gluTessEndPolygon(tess.tess)
// Free memory that we were safeguarding on the go side.
tess.vertData = []*vertexDataWrapper{}
tess.vertLocs = [][3]float64{}
}
// Begin a contour within the polygon.
func (tess *Tesselator) BeginContour() {
C.gluTessBeginContour(tess.tess)
}
// End a contour within the polygon.
func (tess *Tesselator) EndContour() {
C.gluTessEndContour(tess.tess)
}
// Add a vertex to the polygon, with the data parameter that will be
// provided to callbacks.
func (tess *Tesselator) Vertex(location [3]float64, data interface{}) {
// Wrap and safeguard data pointer.
_data := &vertexDataWrapper{data}
tess.vertData = append(tess.vertData, _data)
// Copy location to a safe memory location.
tess.vertLocs = append(tess.vertLocs, location)
_location := unsafe.Pointer(&tess.vertLocs[len(tess.vertLocs)-1])
C.gluTessVertex(tess.tess, (*C.GLdouble)(_location), unsafe.Pointer(_data))
}
// Set the normal of the plane onto which points are projected onto before tesselation.
func (tess *Tesselator) Normal(valueX, valueY, valueZ float64) {
cx := C.GLdouble(valueX)
cy := C.GLdouble(valueY)
cz := C.GLdouble(valueZ)
C.gluTessNormal(tess.tess, cx, cy, cz)
}
// Set a property of the tesselator.
func (tess *Tesselator) Property(which gl.GLenum, data float64) {
C.gluTessProperty(tess.tess, C.GLenum(which), C.GLdouble(data))
}