forked from go-gl-legacy/glu
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtesselator.go
More file actions
129 lines (104 loc) · 3.44 KB
/
tesselator.go
File metadata and controls
129 lines (104 loc) · 3.44 KB
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// 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__
// #define GL_SILENCE_DEPRECATION
// #include <OpenGL/glu.h>
// #else
// #include <GL/glu.h>
// #endif
// #include <stdlib.h>
import "C"
import (
"unsafe"
)
// Opaque object used for book keeping on the go side.
type Tesselator struct {
tess *C.GLUtesselator
polyData interface{}
cData []unsafe.Pointer
// 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)
for _, ptr := range tess.cData {
C.free(ptr)
}
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])
// Convert Go pointer to C pointer which is a requirement for cgo.
dataBytes := (*[unsafe.Sizeof(*_data)]byte)(unsafe.Pointer(_data))
dataSlice := dataBytes[:]
_dataC := C.CBytes(dataSlice)
// Keep track of C pointer so we can free it later.
tess.cData = append(tess.cData, _dataC)
C.gluTessVertex(tess.tess, (*C.GLdouble)(_location), _dataC)
}
// 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 uint32, data float64) {
C.gluTessProperty(tess.tess, C.GLenum(which), C.GLdouble(data))
}