forked from Thinkofname/steven-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
texture.go
202 lines (178 loc) · 5.83 KB
/
texture.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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
// Copyright 2015 Matthew Collins
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package gl
import (
"unsafe"
"github.com/thinkofdeath/gl/v3.2-core/gl"
)
// TextureTarget is a target were a texture can be bound to.
type TextureTarget uint32
// Valid texture targets.
const (
Texture2D TextureTarget = gl.TEXTURE_2D
Texture2DMultisample TextureTarget = gl.TEXTURE_2D_MULTISAMPLE
Texture2DArray TextureTarget = gl.TEXTURE_2D_ARRAY
Texture3D TextureTarget = gl.TEXTURE_3D
)
// TextureFormat is the format of a texture either internally or
// to be uploaded.
type TextureFormat uint32
// Valid texture formats.
const (
Red TextureFormat = gl.RED
RGB TextureFormat = gl.RGB
RGBA TextureFormat = gl.RGBA
RGBA8 TextureFormat = gl.RGBA8
RGBA16F TextureFormat = gl.RGBA16F
R16F TextureFormat = gl.R16F
DepthComponent24 TextureFormat = gl.DEPTH_COMPONENT24
DepthComponent TextureFormat = gl.DEPTH_COMPONENT
)
// TextureParameter is a parameter that can be read or set on a texture.
type TextureParameter uint32
// Valid texture parameters.
const (
TextureMinFilter TextureParameter = gl.TEXTURE_MIN_FILTER
TextureMagFilter TextureParameter = gl.TEXTURE_MAG_FILTER
TextureWrapS TextureParameter = gl.TEXTURE_WRAP_S
TextureWrapT TextureParameter = gl.TEXTURE_WRAP_T
TextureMaxLevel TextureParameter = gl.TEXTURE_MAX_LEVEL
)
// TextureValue is a value that be set on a texture's parameter.
type TextureValue int32
// Valid texture values.
const (
Nearest TextureValue = gl.NEAREST
Linear TextureValue = gl.LINEAR
LinearMipmapLinear TextureValue = gl.LINEAR_MIPMAP_LINEAR
LinearMipmapNearest TextureValue = gl.LINEAR_MIPMAP_NEAREST
NearestMipmapNearest TextureValue = gl.NEAREST_MIPMAP_NEAREST
NearestMipmapLinear TextureValue = gl.NEAREST_MIPMAP_LINEAR
ClampToEdge TextureValue = gl.CLAMP_TO_EDGE
)
// State tracking
var (
currentTexture Texture
currentTextureTarget TextureTarget
)
// Texture is a buffer of data used by fragment shaders to produce color.
type Texture struct {
internal uint32
}
// CreateTexture allocates a new texture.
func CreateTexture() Texture {
var texture Texture
gl.GenTextures(1, &texture.internal)
return texture
}
// Bind binds the texture to the passed target, if the texture is already bound
// then this does nothing.
func (t Texture) Bind(target TextureTarget) {
if currentTexture == t && currentTextureTarget == target {
return
}
gl.BindTexture(uint32(target), t.internal)
currentTexture = t
currentTextureTarget = target
}
func (t Texture) Get(level int, format TextureFormat, ty Type, pixels []byte) {
if t != currentTexture {
panic("texture not bound")
}
gl.GetTexImage(uint32(currentTextureTarget), int32(level), uint32(format), uint32(ty), gl.Ptr(pixels))
}
// Image3D uploads a 3D texture to the GPU.
func (t Texture) Image3D(level, width, height, depth int, format TextureFormat, ty Type, pix []byte) {
if t != currentTexture {
panic("texture not bound")
}
var ptr unsafe.Pointer
if len(pix) != 0 {
ptr = gl.Ptr(pix)
}
gl.TexImage3D(uint32(currentTextureTarget), int32(level), int32(format), int32(width), int32(height), int32(depth), int32(0), uint32(format), uint32(ty), ptr)
}
// SubImage3D updates a region of a 3D texture.
func (t Texture) SubImage3D(level, x, y, z, width, height, depth int, format TextureFormat, ty Type, pix []byte) {
if t != currentTexture {
panic("texture not bound")
}
gl.TexSubImage3D(uint32(currentTextureTarget), int32(level), int32(x), int32(y), int32(z), int32(width), int32(height), int32(depth), uint32(format), uint32(ty), gl.Ptr(pix))
}
// Image2D uploads a 2D texture to the GPU.
func (t Texture) Image2D(level, width, height int, format TextureFormat, ty Type, pix []byte) {
t.Image2DEx(level, width, height, format, format, ty, pix)
}
// Image2DEx uploads a 2D texture to the GPU.
func (t Texture) Image2DEx(level, width, height int, internalFormat, format TextureFormat, ty Type, pix []byte) {
if t != currentTexture {
panic("texture not bound")
}
var ptr unsafe.Pointer
if pix != nil {
ptr = gl.Ptr(pix)
}
gl.TexImage2D(
uint32(currentTextureTarget),
int32(level),
int32(internalFormat),
int32(width),
int32(height),
0,
uint32(format),
uint32(ty),
ptr,
)
}
// Image2DEx uploads a 2D texture to the GPU.
func (t Texture) Image2DSample(samples, width, height int, format TextureFormat, fixed bool) {
if t != currentTexture {
panic("texture not bound")
}
gl.TexImage2DMultisample(
uint32(currentTextureTarget),
int32(samples),
uint32(format),
int32(width),
int32(height),
fixed,
)
}
// SubImage2D updates a region of a 2D texture.
func (t Texture) SubImage2D(level int, x, y, width, height int, format TextureFormat, ty Type, pix []byte) {
if t != currentTexture {
panic("texture not bound")
}
gl.TexSubImage2D(
uint32(currentTextureTarget),
int32(level),
int32(x),
int32(y),
int32(width),
int32(height),
uint32(format),
uint32(ty),
gl.Ptr(pix),
)
}
// Parameter sets a parameter on the texture to passed value.
func (t Texture) Parameter(param TextureParameter, val TextureValue) {
if t != currentTexture {
panic("texture not bound")
}
gl.TexParameteri(uint32(currentTextureTarget), uint32(param), int32(val))
}
func (t Texture) Delete() {
gl.DeleteTextures(1, &t.internal)
}