| 1 |
module dglut.opengl; |
|---|
| 2 |
import dglut.vector; |
|---|
| 3 |
import std.stdio; |
|---|
| 4 |
|
|---|
| 5 |
extern(System) { |
|---|
| 6 |
typedef uint GLenum; |
|---|
| 7 |
typedef uint GLbitfield; |
|---|
| 8 |
typedef uint GLuint; // different on 64-bit? |
|---|
| 9 |
typedef GLenum glPrimitive; |
|---|
| 10 |
const glPrimitive GL_POINTS=0, GL_LINES=1, GL_LINE_LOOP=2, GL_LINE_STRIP=3, GL_TRIANGLES=4, |
|---|
| 11 |
GL_TRIANGLE_STRIP=5, GL_TRIANGLE_FAN=6, GL_QUADS=7, GL_QUAD_STRIP=8, GL_POLYGON=9; |
|---|
| 12 |
void glBegin(glPrimitive mode); |
|---|
| 13 |
void glEnd(); |
|---|
| 14 |
} |
|---|
| 15 |
|
|---|
| 16 |
template Prepend (string S, T...) { |
|---|
| 17 |
static if (!T.length) alias Tuple!() Prepend; |
|---|
| 18 |
else { |
|---|
| 19 |
static if (is(typeof(T[0]): string)) alias Tuple!(S~T[0], Prepend!(S, T[1..$])) Prepend; |
|---|
| 20 |
else alias Tuple!(T[0], Prepend!(S, T[1..$])) Prepend; |
|---|
| 21 |
} |
|---|
| 22 |
} |
|---|
| 23 |
|
|---|
| 24 |
template Append(string S, T...) { |
|---|
| 25 |
static if (!T.length) alias Tuple!() Append; |
|---|
| 26 |
else { |
|---|
| 27 |
static if (is(typeof(T[0]): string)) alias Tuple!(T[0]~S, Append!(S, T[1..$])) Append; |
|---|
| 28 |
else alias Tuple!(T[0], Append!(S, T[1..$])) Append; |
|---|
| 29 |
} |
|---|
| 30 |
} |
|---|
| 31 |
|
|---|
| 32 |
template Find(string S, string T) { |
|---|
| 33 |
static if(S.length<T.length) { const size_t Find=size_t.max; } |
|---|
| 34 |
else { |
|---|
| 35 |
static if (S[0..T.length] == T) const size_t Find=0; |
|---|
| 36 |
else static if (Find!(S[1..$], T)==size_t.max) const size_t Find=size_t.max; |
|---|
| 37 |
else const size_t Find=Find!(S[1..$], T) + 1; |
|---|
| 38 |
} |
|---|
| 39 |
} |
|---|
| 40 |
|
|---|
| 41 |
template Split(string S, string SEP) { |
|---|
| 42 |
static if (Find!(S, SEP)==size_t.max) alias Tuple!(S) Split; |
|---|
| 43 |
else alias Tuple!(S[0..Find!(S, SEP)], Split!(S[Find!(S, SEP)+SEP.length .. $], SEP)) Split; |
|---|
| 44 |
} |
|---|
| 45 |
|
|---|
| 46 |
template StringCross(T, U) { |
|---|
| 47 |
static if (T.Tuple.length==1) alias Prepend!(T.Tuple[0], U.Tuple) StringCross; |
|---|
| 48 |
else alias Tuple!(Prepend!(T.Tuple[0], U.Tuple), StringCross!(TupleWrapper!(T.Tuple[1..$]), U)) StringCross; |
|---|
| 49 |
} |
|---|
| 50 |
|
|---|
| 51 |
template Expand(string E) { |
|---|
| 52 |
static if (!E.length) alias Tuple!("") Expand; |
|---|
| 53 |
else { |
|---|
| 54 |
static if (E[0]=='{') { |
|---|
| 55 |
static if(Find!(E, "}")==size_t.max) { |
|---|
| 56 |
pragma(msg, "You forgot a closing bracket in \""~E~"\""); |
|---|
| 57 |
static assert(false); |
|---|
| 58 |
} |
|---|
| 59 |
alias StringCross!(TupleWrapper!(Split!(E[1..Find!(E, "}")], "|")), TupleWrapper!(Expand!(E[Find!(E, "}")+1 .. $]))) Expand; |
|---|
| 60 |
} else { |
|---|
| 61 |
alias Prepend!(""~E[0], Expand!(E[1..$])) Expand; |
|---|
| 62 |
} |
|---|
| 63 |
} |
|---|
| 64 |
} |
|---|
| 65 |
|
|---|
| 66 |
template ConstEnum(T, string MOD, SYMBOLS...) { |
|---|
| 67 |
static assert(SYMBOLS.length>1); |
|---|
| 68 |
static assert(is(typeof(SYMBOLS[0]): long)); |
|---|
| 69 |
static if (SYMBOLS.length>1) { |
|---|
| 70 |
static if (is(typeof(SYMBOLS[1]): long)) { |
|---|
| 71 |
static if (SYMBOLS.length>2) mixin ConstEnum!(T, MOD, SYMBOLS[1..$]); |
|---|
| 72 |
} else { |
|---|
| 73 |
mixin("T "~SYMBOLS[1]~"=SYMBOLS[0]; "); |
|---|
| 74 |
static if (SYMBOLS.length>2) mixin ConstEnum!(T, MOD, mixin("SYMBOLS[0]"~MOD), SYMBOLS[2..$]); |
|---|
| 75 |
} |
|---|
| 76 |
} |
|---|
| 77 |
} |
|---|
| 78 |
|
|---|
| 79 |
template PrimitiveScope(string NAME, string WHICH) { |
|---|
| 80 |
mixin("void "~NAME~"(void delegate()[] dgs...) { |
|---|
| 81 |
glBegin("~WHICH~"); scope(exit) glEnd(); |
|---|
| 82 |
foreach (dg; dgs) dg(); |
|---|
| 83 |
}"); |
|---|
| 84 |
} |
|---|
| 85 |
|
|---|
| 86 |
template MultiMixin(alias T, int count, U...) { |
|---|
| 87 |
mixin T!(U[0..count]); |
|---|
| 88 |
static if (U.length>count) mixin MultiMixin!(T, count, U[count..$]); |
|---|
| 89 |
} |
|---|
| 90 |
|
|---|
| 91 |
mixin MultiMixin!(PrimitiveScope, 2, |
|---|
| 92 |
"Points", "GL_POINTS", "Lines", "GL_LINES", |
|---|
| 93 |
"LineLoop", "GL_LINE_LOOP", "LineStrip", "GL_LINE_STRIP", |
|---|
| 94 |
"Triangles", "GL_TRIANGLES", "TriangleStrip", "GL_TRIANGLE_STRIP", |
|---|
| 95 |
"TriangleFan", "GL_TRIANGLE_FAN", "Quads", "GL_QUADS", |
|---|
| 96 |
"QuadStrip", "GL_QUAD_STRIP", "Polygon", "GL_POLYGON" |
|---|
| 97 |
); |
|---|
| 98 |
|
|---|
| 99 |
string glTypeDecode(string s) { |
|---|
| 100 |
if (s=="b") return "byte"; |
|---|
| 101 |
if (s=="d") return "double"; |
|---|
| 102 |
if (s=="f") return "float"; |
|---|
| 103 |
if (s=="i") return "int"; |
|---|
| 104 |
if (s=="s") return "short"; |
|---|
| 105 |
if (s=="ub") return "ubyte"; |
|---|
| 106 |
if (s=="ui") return "uint"; |
|---|
| 107 |
if (s=="us") return "ushort"; |
|---|
| 108 |
assert(false); |
|---|
| 109 |
} |
|---|
| 110 |
|
|---|
| 111 |
string glTypeEncode(string s) { |
|---|
| 112 |
if (s[0]=='u') return s[0..2]; |
|---|
| 113 |
return s[0..1]; |
|---|
| 114 |
} |
|---|
| 115 |
|
|---|
| 116 |
template Repeat(int count, T) { |
|---|
| 117 |
static if (!count) alias Tuple!() Repeat; |
|---|
| 118 |
else alias Tuple!(T, Repeat!(count-1, T)) Repeat; |
|---|
| 119 |
} |
|---|
| 120 |
|
|---|
| 121 |
size_t find(string where, string what) { |
|---|
| 122 |
size_t counter=0; |
|---|
| 123 |
while (where.length>=what.length) { |
|---|
| 124 |
if (where[0..what.length]==what) return counter; |
|---|
| 125 |
where=where[1..$]; |
|---|
| 126 |
++counter; |
|---|
| 127 |
} |
|---|
| 128 |
return size_t.max; |
|---|
| 129 |
} |
|---|
| 130 |
|
|---|
| 131 |
string glFunctions(string name, string params, string types) { |
|---|
| 132 |
string res; |
|---|
| 133 |
while (types.length) { |
|---|
| 134 |
string type; |
|---|
| 135 |
if (find(types, "|")==size_t.max) { type=types; types=""; } |
|---|
| 136 |
else { type=types[0..find(types, "|")]; types=types[find(types, "|")+1..$]; } |
|---|
| 137 |
foreach (param; params) { |
|---|
| 138 |
|
|---|
| 139 |
res~="extern(System) void "~name~param~type~"(Repeat!("~param~", "~glTypeDecode(type)~")); "; |
|---|
| 140 |
res~="extern(System) void "~name~param~type~"v("~glTypeDecode(type)~" *); "; |
|---|
| 141 |
res~="void "~name~"(Repeat!("~param~", "~glTypeDecode(type)~") par) { |
|---|
| 142 |
"~name~param~type~"(par); |
|---|
| 143 |
}"; |
|---|
| 144 |
res~="void "~name~"("~glTypeDecode(type)~"["~param~"] par) { |
|---|
| 145 |
"~name~param~type~"v(par.ptr); |
|---|
| 146 |
}"; |
|---|
| 147 |
} |
|---|
| 148 |
} |
|---|
| 149 |
return res; |
|---|
| 150 |
} |
|---|
| 151 |
|
|---|
| 152 |
mixin(glFunctions("glVertex", "234", "d|f|i|s")); |
|---|
| 153 |
mixin(glFunctions("glNormal", "3", "b|d|f|i|s")); |
|---|
| 154 |
mixin(glFunctions("glTexCoord", "1234", "d|f|i|s")); |
|---|
| 155 |
mixin(glFunctions("glColor", "34", "b|d|f|i|s|ub|ui|us")); |
|---|
| 156 |
mixin(glFunctions("glRasterPos", "234", "d|f|i|s")); |
|---|
| 157 |
|
|---|
| 158 |
void Vertex(T...)(T t) { static if (T.length==1) glVertex(t[0].parts); else glVertex(t); } |
|---|
| 159 |
void Normal(T...)(T t) { static if (T.length==1) glNormal(t[0].parts); else glNormal(t); } |
|---|
| 160 |
void TexCoord(T...)(T t) { static if (T.length==1) glTexCoord(t[0].parts); else glTexCoord(t); } |
|---|
| 161 |
void Color(T...)(T t) { static if (T.length==1) glColor(t[0].parts); else glColor(t); } |
|---|
| 162 |
void RasterPos(T...)(T t) { static if (T.length==1) glRasterPos(t[0].parts); else glRasterPos(t); } |
|---|
| 163 |
|
|---|
| 164 |
extern(System) { |
|---|
| 165 |
void glPushMatrix(); |
|---|
| 166 |
void glPopMatrix(); |
|---|
| 167 |
} |
|---|
| 168 |
|
|---|
| 169 |
void MatrixScope(void delegate()[] dgs...) { |
|---|
| 170 |
glPushMatrix(); |
|---|
| 171 |
scope(exit) glPopMatrix; |
|---|
| 172 |
foreach (dg; dgs) dg(); |
|---|
| 173 |
} |
|---|
| 174 |
|
|---|
| 175 |
extern(System) { |
|---|
| 176 |
void glMatrixMode(MatrixModeType); |
|---|
| 177 |
typedef GLenum MatrixModeType; |
|---|
| 178 |
const MatrixModeType GL_MODELVIEW=0x1700, GL_PROJECTION=0x1701, GL_TEXTURE=0x1702; |
|---|
| 179 |
} |
|---|
| 180 |
|
|---|
| 181 |
// so as to prevent conflicts between Texture and class Texture later on |
|---|
| 182 |
struct MatrixMode { |
|---|
| 183 |
static void Modelview() { glMatrixMode(GL_MODELVIEW); } |
|---|
| 184 |
static void Projection() { glMatrixMode(GL_PROJECTION); } |
|---|
| 185 |
static void Texture() { glMatrixMode(GL_TEXTURE); } |
|---|
| 186 |
} |
|---|
| 187 |
|
|---|
| 188 |
extern(System) { |
|---|
| 189 |
const GLenum GL_NONE=0; |
|---|
| 190 |
mixin ConstEnum!(GLenum, "+1", 0x0400, |
|---|
| 191 |
Expand!("GL_{FRONT|BACK}_{LEFT|RIGHT}"), |
|---|
| 192 |
Expand!("GL_{FRONT|BACK|LEFT|RIGHT}"), |
|---|
| 193 |
"GL_FRONT_AND_BACK", |
|---|
| 194 |
Expand!("GL_AUX{0|1|2|3}") |
|---|
| 195 |
); |
|---|
| 196 |
typedef GLenum LightParameter; |
|---|
| 197 |
mixin ConstEnum!(LightParameter, "+1", 0x1200, |
|---|
| 198 |
Prepend!("GL_", |
|---|
| 199 |
Tuple!( |
|---|
| 200 |
"AMBIENT", "DIFFUSE", "SPECULAR", "POSITION", |
|---|
| 201 |
Expand!("SPOT_{DIRECTION|EXPONENT|CUTOFF}"), |
|---|
| 202 |
Expand!("{CONSTANT|LINEAR|QUADRATIC}_ATTENUATION") |
|---|
| 203 |
) |
|---|
| 204 |
) |
|---|
| 205 |
); |
|---|
| 206 |
typedef GLenum MaterialParameter; |
|---|
| 207 |
mixin ConstEnum!(MaterialParameter, "+1", 0x1600, |
|---|
| 208 |
Prepend!("GL_", Tuple!("EMISSION", "SHININESS", "AMBIENT_AND_DIFFUSE", "COLOR_INDEXES")) |
|---|
| 209 |
); |
|---|
| 210 |
void glMaterialf(GLenum face, GLenum pname, float param); |
|---|
| 211 |
void glMaterialfv(GLenum face, GLenum pname, float *param); |
|---|
| 212 |
void glMateriali(GLenum face, GLenum pname, int param); |
|---|
| 213 |
void glMaterialiv(GLenum face, GLenum pname, int *param); |
|---|
| 214 |
} |
|---|
| 215 |
|
|---|
| 216 |
template MaterialNestedStruct(string NAME, string GLNAME) { |
|---|
| 217 |
mixin("struct "~NAME~" { |
|---|
| 218 |
static void ambient(float[4] col) { glMaterialfv("~GLNAME~", GL_AMBIENT, col.ptr); } |
|---|
| 219 |
static void diffuse(float[4] col) { glMaterialfv("~GLNAME~", GL_DIFFUSE, col.ptr); } |
|---|
| 220 |
static void ambient_and_diffuse(float[4] col) { glMaterialfv("~GLNAME~", GL_AMBIENT_AND_DIFFUSE, col.ptr); } |
|---|
| 221 |
static void specular(float[4] col) { glMaterialfv("~GLNAME~", GL_SPECULAR, col.ptr); } |
|---|
| 222 |
static void shininess(float s) { glMaterialf("~GLNAME~", GL_SHININESS, s); } |
|---|
| 223 |
static void emission(float[4] e) { glMaterialfv("~GLNAME~", GL_EMISSION, e.ptr); } |
|---|
| 224 |
static void emission(int[4] i) { glMaterialiv("~GLNAME~", GL_COLOR_INDEXES, i.ptr); } |
|---|
| 225 |
}"); |
|---|
| 226 |
} |
|---|
| 227 |
|
|---|
| 228 |
struct Material { |
|---|
| 229 |
mixin MultiMixin!(MaterialNestedStruct, 2, "Front", "GL_FRONT", "Back", "GL_BACK", "FrontAndBack", "GL_FRONT_AND_BACK"); |
|---|
| 230 |
} |
|---|
| 231 |
|
|---|
| 232 |
extern(System) { |
|---|
| 233 |
void glTranslated(Repeat!(3, double) xyz); |
|---|
| 234 |
void glTranslatef(Repeat!(3, float) xyz); |
|---|
| 235 |
} |
|---|
| 236 |
void Translate(T...)(T what) { |
|---|
| 237 |
static if (is(T[0]==double) || is(T[0]==real)) glTranslated(what); |
|---|
| 238 |
else glTranslatef(what); |
|---|
| 239 |
} |
|---|
| 240 |
|
|---|
| 241 |
extern(System) { |
|---|
| 242 |
void glRotated(double angle, Repeat!(3, double) xyz); |
|---|
| 243 |
void glRotatef(float angle, Repeat!(3, float) xyz); |
|---|
| 244 |
} |
|---|
| 245 |
|
|---|
| 246 |
void Rotate(T...)(T what) { |
|---|
| 247 |
static if (is(T[0]==double) || is(T[0]==real)) glRotated(what); |
|---|
| 248 |
else glRotatef(what); |
|---|
| 249 |
} |
|---|
| 250 |
|
|---|
| 251 |
extern(System) { |
|---|
| 252 |
void glClear(GLbitfield mask); |
|---|
| 253 |
typedef GLbitfield AttribMask; |
|---|
| 254 |
mixin ConstEnum!(AttribMask, "*2", 1, Prepend!("GL_", |
|---|
| 255 |
Append!("_BIT", |
|---|
| 256 |
Expand!("{CURRENT|POINT|LINE|POLYGON|POLYGON_STIPPLE|PIXEL_MODE|LIGHTING|FOG|DEPTH_BUFFER|ACCUM_BUFFER|STENCIL_BUFFER"~ |
|---|
| 257 |
"|VIEWPORT|TRANSFORM|ENABLE|COLOR_BUFFER|HINT|EVAL|LIST|TEXTURE|SCISSOR}" |
|---|
| 258 |
) |
|---|
| 259 |
) |
|---|
| 260 |
)); |
|---|
| 261 |
const AttribMask GL_ALL_ATTRIB_BITS=0xFFFFFFFF; |
|---|
| 262 |
void glClearColor(Repeat!(4, float) rgb); |
|---|
| 263 |
void glFlush(); |
|---|
| 264 |
void glPushAttrib(GLbitfield); |
|---|
| 265 |
void glPopAttrib(); |
|---|
| 266 |
} |
|---|
| 267 |
|
|---|
| 268 |
extern(System) { |
|---|
| 269 |
void glEnable(GLenum); |
|---|
| 270 |
void glDisable(GLenum); |
|---|
| 271 |
// sorry, but using templates would have been too much to ask from the compiler |
|---|
| 272 |
// (I tried; the resulting binary was 40M big) |
|---|
| 273 |
// yay for sed! |
|---|
| 274 |
// cat gl.h |sed -e "s@#define@const GLenum@" -e "s@ *0x\(.*\)@ = 0x\1;@" |less |
|---|
| 275 |
const GLenum GL_CURRENT_COLOR = 0x0B00; |
|---|
| 276 |
const GLenum GL_CURRENT_INDEX = 0x0B01; |
|---|
| 277 |
const GLenum GL_CURRENT_NORMAL = 0x0B02; |
|---|
| 278 |
const GLenum GL_CURRENT_TEXTURE_COORDS = 0x0B03; |
|---|
| 279 |
const GLenum GL_CURRENT_RASTER_COLOR = 0x0B04; |
|---|
| 280 |
const GLenum GL_CURRENT_RASTER_INDEX = 0x0B05; |
|---|
| 281 |
const GLenum GL_CURRENT_RASTER_TEXTURE_COORDS = 0x0B06; |
|---|
| 282 |
const GLenum GL_CURRENT_RASTER_POSITION = 0x0B07; |
|---|
| 283 |
const GLenum GL_CURRENT_RASTER_POSITION_VALID = 0x0B08; |
|---|
| 284 |
const GLenum GL_CURRENT_RASTER_DISTANCE = 0x0B09; |
|---|
| 285 |
const GLenum GL_POINT_SMOOTH = 0x0B10; |
|---|
| 286 |
const GLenum GL_POINT_SIZE = 0x0B11; |
|---|
| 287 |
const GLenum GL_SMOOTH_POINT_SIZE_RANGE = 0x0B12; |
|---|
| 288 |
const GLenum GL_SMOOTH_POINT_SIZE_GRANULARITY = 0x0B13; |
|---|
| 289 |
const GLenum GL_POINT_SIZE_RANGE = GL_SMOOTH_POINT_SIZE_RANGE; |
|---|
| 290 |
const GLenum GL_POINT_SIZE_GRANULARITY = GL_SMOOTH_POINT_SIZE_GRANULARITY; |
|---|
| 291 |
const GLenum GL_LINE_SMOOTH = 0x0B20; |
|---|
| 292 |
const GLenum GL_LINE_WIDTH = 0x0B21; |
|---|
| 293 |
const GLenum GL_SMOOTH_LINE_WIDTH_RANGE = 0x0B22; |
|---|
| 294 |
const GLenum GL_SMOOTH_LINE_WIDTH_GRANULARITY = 0x0B23; |
|---|
| 295 |
const GLenum GL_LINE_WIDTH_RANGE = GL_SMOOTH_LINE_WIDTH_RANGE; |
|---|
| 296 |
const GLenum GL_LINE_WIDTH_GRANULARITY = GL_SMOOTH_LINE_WIDTH_GRANULARITY; |
|---|
| 297 |
const GLenum GL_LINE_STIPPLE = 0x0B24; |
|---|
| 298 |
const GLenum GL_LINE_STIPPLE_PATTERN = 0x0B25; |
|---|
| 299 |
const GLenum GL_LINE_STIPPLE_REPEAT = 0x0B26; |
|---|
| 300 |
const GLenum GL_LIST_MODE = 0x0B30; |
|---|
| 301 |
const GLenum GL_MAX_LIST_NESTING = 0x0B31; |
|---|
| 302 |
const GLenum GL_LIST_BASE = 0x0B32; |
|---|
| 303 |
const GLenum GL_LIST_INDEX = 0x0B33; |
|---|
| 304 |
const GLenum GL_POLYGON_MODE = 0x0B40; |
|---|
| 305 |
const GLenum GL_POLYGON_SMOOTH = 0x0B41; |
|---|
| 306 |
const GLenum GL_POLYGON_STIPPLE = 0x0B42; |
|---|
| 307 |
const GLenum GL_EDGE_FLAG = 0x0B43; |
|---|
| 308 |
const GLenum GL_CULL_FACE = 0x0B44; |
|---|
| 309 |
const GLenum GL_CULL_FACE_MODE = 0x0B45; |
|---|
| 310 |
const GLenum GL_FRONT_FACE = 0x0B46; |
|---|
| 311 |
const GLenum GL_LIGHTING = 0x0B50; |
|---|
| 312 |
const GLenum GL_LIGHT_MODEL_LOCAL_VIEWER = 0x0B51; |
|---|
| 313 |
const GLenum GL_LIGHT_MODEL_TWO_SIDE = 0x0B52; |
|---|
| 314 |
const GLenum GL_LIGHT_MODEL_AMBIENT = 0x0B53; |
|---|
| 315 |
const GLenum GL_SHADE_MODEL = 0x0B54; |
|---|
| 316 |
const GLenum GL_COLOR_MATERIAL_FACE = 0x0B55; |
|---|
| 317 |
const GLenum GL_COLOR_MATERIAL_PARAMETER = 0x0B56; |
|---|
| 318 |
const GLenum GL_COLOR_MATERIAL = 0x0B57; |
|---|
| 319 |
const GLenum GL_FOG = 0x0B60; |
|---|
| 320 |
const GLenum GL_FOG_INDEX = 0x0B61; |
|---|
| 321 |
const GLenum GL_FOG_DENSITY = 0x0B62; |
|---|
| 322 |
const GLenum GL_FOG_START = 0x0B63; |
|---|
| 323 |
const GLenum GL_FOG_END = 0x0B64; |
|---|
| 324 |
const GLenum GL_FOG_MODE = 0x0B65; |
|---|
| 325 |
const GLenum GL_FOG_COLOR = 0x0B66; |
|---|
| 326 |
const GLenum GL_DEPTH_RANGE = 0x0B70; |
|---|
| 327 |
const GLenum GL_DEPTH_TEST = 0x0B71; |
|---|
| 328 |
const GLenum GL_DEPTH_WRITEMASK = 0x0B72; |
|---|
| 329 |
const GLenum GL_DEPTH_CLEAR_VALUE = 0x0B73; |
|---|
| 330 |
const GLenum GL_DEPTH_FUNC = 0x0B74; |
|---|
| 331 |
const GLenum GL_ACCUM_CLEAR_VALUE = 0x0B80; |
|---|
| 332 |
const GLenum GL_STENCIL_TEST = 0x0B90; |
|---|
| 333 |
const GLenum GL_STENCIL_CLEAR_VALUE = 0x0B91; |
|---|
| 334 |
const GLenum GL_STENCIL_FUNC = 0x0B92; |
|---|
| 335 |
const GLenum GL_STENCIL_VALUE_MASK = 0x0B93; |
|---|
| 336 |
const GLenum GL_STENCIL_FAIL = 0x0B94; |
|---|
| 337 |
const GLenum GL_STENCIL_PASS_DEPTH_FAIL = 0x0B95; |
|---|
| 338 |
const GLenum GL_STENCIL_PASS_DEPTH_PASS = 0x0B96; |
|---|
| 339 |
const GLenum GL_STENCIL_REF = 0x0B97; |
|---|
| 340 |
const GLenum GL_STENCIL_WRITEMASK = 0x0B98; |
|---|
| 341 |
const GLenum GL_MATRIX_MODE = 0x0BA0; |
|---|
| 342 |
const GLenum GL_NORMALIZE = 0x0BA1; |
|---|
| 343 |
const GLenum GL_VIEWPORT = 0x0BA2; |
|---|
| 344 |
const GLenum GL_MODELVIEW_STACK_DEPTH = 0x0BA3; |
|---|
| 345 |
const GLenum GL_PROJECTION_STACK_DEPTH = 0x0BA4; |
|---|
| 346 |
const GLenum GL_TEXTURE_STACK_DEPTH = 0x0BA5; |
|---|
| 347 |
const GLenum GL_MODELVIEW_MATRIX = 0x0BA6; |
|---|
| 348 |
const GLenum GL_PROJECTION_MATRIX = 0x0BA7; |
|---|
| 349 |
const GLenum GL_TEXTURE_MATRIX = 0x0BA8; |
|---|
| 350 |
const GLenum GL_ATTRIB_STACK_DEPTH = 0x0BB0; |
|---|
| 351 |
const GLenum GL_CLIENT_ATTRIB_STACK_DEPTH = 0x0BB1; |
|---|
| 352 |
const GLenum GL_ALPHA_TEST = 0x0BC0; |
|---|
| 353 |
const GLenum GL_ALPHA_TEST_FUNC = 0x0BC1; |
|---|
| 354 |
const GLenum GL_ALPHA_TEST_REF = 0x0BC2; |
|---|
| 355 |
const GLenum GL_DITHER = 0x0BD0; |
|---|
| 356 |
const GLenum GL_BLEND_DST = 0x0BE0; |
|---|
| 357 |
const GLenum GL_BLEND_SRC = 0x0BE1; |
|---|
| 358 |
const GLenum GL_BLEND = 0x0BE2; |
|---|
| 359 |
const GLenum GL_LOGIC_OP_MODE = 0x0BF0; |
|---|
| 360 |
const GLenum GL_INDEX_LOGIC_OP = 0x0BF1; |
|---|
| 361 |
const GLenum GL_LOGIC_OP = GL_INDEX_LOGIC_OP; |
|---|
| 362 |
const GLenum GL_COLOR_LOGIC_OP = 0x0BF2; |
|---|
| 363 |
const GLenum GL_AUX_BUFFERS = 0x0C00; |
|---|
| 364 |
const GLenum GL_DRAW_BUFFER = 0x0C01; |
|---|
| 365 |
const GLenum GL_READ_BUFFER = 0x0C02; |
|---|
| 366 |
const GLenum GL_SCISSOR_BOX = 0x0C10; |
|---|
| 367 |
const GLenum GL_SCISSOR_TEST = 0x0C11; |
|---|
| 368 |
const GLenum GL_INDEX_CLEAR_VALUE = 0x0C20; |
|---|
| 369 |
const GLenum GL_INDEX_WRITEMASK = 0x0C21; |
|---|
| 370 |
const GLenum GL_COLOR_CLEAR_VALUE = 0x0C22; |
|---|
| 371 |
const GLenum GL_COLOR_WRITEMASK = 0x0C23; |
|---|
| 372 |
const GLenum GL_INDEX_MODE = 0x0C30; |
|---|
| 373 |
const GLenum GL_RGBA_MODE = 0x0C31; |
|---|
| 374 |
const GLenum GL_DOUBLEBUFFER = 0x0C32; |
|---|
| 375 |
const GLenum GL_STEREO = 0x0C33; |
|---|
| 376 |
const GLenum GL_RENDER_MODE = 0x0C40; |
|---|
| 377 |
const GLenum GL_PERSPECTIVE_CORRECTION_HINT = 0x0C50; |
|---|
| 378 |
const GLenum GL_POINT_SMOOTH_HINT = 0x0C51; |
|---|
| 379 |
const GLenum GL_LINE_SMOOTH_HINT = 0x0C52; |
|---|
| 380 |
const GLenum GL_POLYGON_SMOOTH_HINT = 0x0C53; |
|---|
| 381 |
const GLenum GL_FOG_HINT = 0x0C54; |
|---|
| 382 |
const GLenum GL_TEXTURE_GEN_S = 0x0C60; |
|---|
| 383 |
const GLenum GL_TEXTURE_GEN_T = 0x0C61; |
|---|
| 384 |
const GLenum GL_TEXTURE_GEN_R = 0x0C62; |
|---|
| 385 |
const GLenum GL_TEXTURE_GEN_Q = 0x0C63; |
|---|
| 386 |
const GLenum GL_PIXEL_MAP_I_TO_I_SIZE = 0x0CB0; |
|---|
| 387 |
const GLenum GL_PIXEL_MAP_S_TO_S_SIZE = 0x0CB1; |
|---|
| 388 |
const GLenum GL_PIXEL_MAP_I_TO_R_SIZE = 0x0CB2; |
|---|
| 389 |
const GLenum GL_PIXEL_MAP_I_TO_G_SIZE = 0x0CB3; |
|---|
| 390 |
const GLenum GL_PIXEL_MAP_I_TO_B_SIZE = 0x0CB4; |
|---|
| 391 |
const GLenum GL_PIXEL_MAP_I_TO_A_SIZE = 0x0CB5; |
|---|
| 392 |
const GLenum GL_PIXEL_MAP_R_TO_R_SIZE = 0x0CB6; |
|---|
| 393 |
const GLenum GL_PIXEL_MAP_G_TO_G_SIZE = 0x0CB7; |
|---|
| 394 |
const GLenum GL_PIXEL_MAP_B_TO_B_SIZE = 0x0CB8; |
|---|
| 395 |
const GLenum GL_PIXEL_MAP_A_TO_A_SIZE = 0x0CB9; |
|---|
| 396 |
const GLenum GL_UNPACK_SWAP_BYTES = 0x0CF0; |
|---|
| 397 |
const GLenum GL_UNPACK_LSB_FIRST = 0x0CF1; |
|---|
| 398 |
const GLenum GL_UNPACK_ROW_LENGTH = 0x0CF2; |
|---|
| 399 |
const GLenum GL_UNPACK_SKIP_ROWS = 0x0CF3; |
|---|
| 400 |
const GLenum GL_UNPACK_SKIP_PIXELS = 0x0CF4; |
|---|
| 401 |
const GLenum GL_UNPACK_ALIGNMENT = 0x0CF5; |
|---|
| 402 |
const GLenum GL_PACK_SWAP_BYTES = 0x0D00; |
|---|
| 403 |
const GLenum GL_PACK_LSB_FIRST = 0x0D01; |
|---|
| 404 |
const GLenum GL_PACK_ROW_LENGTH = 0x0D02; |
|---|
| 405 |
const GLenum GL_PACK_SKIP_ROWS = 0x0D03; |
|---|
| 406 |
const GLenum GL_PACK_SKIP_PIXELS = 0x0D04; |
|---|
| 407 |
const GLenum GL_PACK_ALIGNMENT = 0x0D05; |
|---|
| 408 |
const GLenum GL_MAP_COLOR = 0x0D10; |
|---|
| 409 |
const GLenum GL_MAP_STENCIL = 0x0D11; |
|---|
| 410 |
const GLenum GL_INDEX_SHIFT = 0x0D12; |
|---|
| 411 |
const GLenum GL_INDEX_OFFSET = 0x0D13; |
|---|
| 412 |
const GLenum GL_RED_SCALE = 0x0D14; |
|---|
| 413 |
const GLenum GL_RED_BIAS = 0x0D15; |
|---|
| 414 |
const GLenum GL_ZOOM_X = 0x0D16; |
|---|
| 415 |
const GLenum GL_ZOOM_Y = 0x0D17; |
|---|
| 416 |
const GLenum GL_GREEN_SCALE = 0x0D18; |
|---|
| 417 |
const GLenum GL_GREEN_BIAS = 0x0D19; |
|---|
| 418 |
const GLenum GL_BLUE_SCALE = 0x0D1A; |
|---|
| 419 |
const GLenum GL_BLUE_BIAS = 0x0D1B; |
|---|
| 420 |
const GLenum GL_ALPHA_SCALE = 0x0D1C; |
|---|
| 421 |
const GLenum GL_ALPHA_BIAS = 0x0D1D; |
|---|
| 422 |
const GLenum GL_DEPTH_SCALE = 0x0D1E; |
|---|
| 423 |
const GLenum GL_DEPTH_BIAS = 0x0D1F; |
|---|
| 424 |
const GLenum GL_MAX_EVAL_ORDER = 0x0D30; |
|---|
| 425 |
const GLenum GL_MAX_LIGHTS = 0x0D31; |
|---|
| 426 |
const GLenum GL_MAX_CLIP_PLANES = 0x0D32; |
|---|
| 427 |
const GLenum GL_MAX_TEXTURE_SIZE = 0x0D33; |
|---|
| 428 |
const GLenum GL_MAX_PIXEL_MAP_TABLE = 0x0D34; |
|---|
| 429 |
const GLenum GL_MAX_ATTRIB_STACK_DEPTH = 0x0D35; |
|---|
| 430 |
const GLenum GL_MAX_MODELVIEW_STACK_DEPTH = 0x0D36; |
|---|
| 431 |
const GLenum GL_MAX_NAME_STACK_DEPTH = 0x0D37; |
|---|
| 432 |
const GLenum GL_MAX_PROJECTION_STACK_DEPTH = 0x0D38; |
|---|
| 433 |
const GLenum GL_MAX_TEXTURE_STACK_DEPTH = 0x0D39; |
|---|
| 434 |
const GLenum GL_MAX_VIEWPORT_DIMS = 0x0D3A; |
|---|
| 435 |
const GLenum GL_MAX_CLIENT_ATTRIB_STACK_DEPTH = 0x0D3B; |
|---|
| 436 |
const GLenum GL_SUBPIXEL_BITS = 0x0D50; |
|---|
| 437 |
const GLenum GL_INDEX_BITS = 0x0D51; |
|---|
| 438 |
const GLenum GL_RED_BITS = 0x0D52; |
|---|
| 439 |
const GLenum GL_GREEN_BITS = 0x0D53; |
|---|
| 440 |
const GLenum GL_BLUE_BITS = 0x0D54; |
|---|
| 441 |
const GLenum GL_ALPHA_BITS = 0x0D55; |
|---|
| 442 |
const GLenum GL_DEPTH_BITS = 0x0D56; |
|---|
| 443 |
const GLenum GL_STENCIL_BITS = 0x0D57; |
|---|
| 444 |
const GLenum GL_ACCUM_RED_BITS = 0x0D58; |
|---|
| 445 |
const GLenum GL_ACCUM_GREEN_BITS = 0x0D59; |
|---|
| 446 |
const GLenum GL_ACCUM_BLUE_BITS = 0x0D5A; |
|---|
| 447 |
const GLenum GL_ACCUM_ALPHA_BITS = 0x0D5B; |
|---|
| 448 |
const GLenum GL_NAME_STACK_DEPTH = 0x0D70; |
|---|
| 449 |
const GLenum GL_AUTO_NORMAL = 0x0D80; |
|---|
| 450 |
const GLenum GL_MAP1_COLOR_4 = 0x0D90; |
|---|
| 451 |
const GLenum GL_MAP1_INDEX = 0x0D91; |
|---|
| 452 |
const GLenum GL_MAP1_NORMAL = 0x0D92; |
|---|
| 453 |
const GLenum GL_MAP1_TEXTURE_COORD_1 = 0x0D93; |
|---|
| 454 |
const GLenum GL_MAP1_TEXTURE_COORD_2 = 0x0D94; |
|---|
| 455 |
const GLenum GL_MAP1_TEXTURE_COORD_3 = 0x0D95; |
|---|
| 456 |
const GLenum GL_MAP1_TEXTURE_COORD_4 = 0x0D96; |
|---|
| 457 |
const GLenum GL_MAP1_VERTEX_3 = 0x0D97; |
|---|
| 458 |
const GLenum GL_MAP1_VERTEX_4 = 0x0D98; |
|---|
| 459 |
const GLenum GL_MAP2_COLOR_4 = 0x0DB0; |
|---|
| 460 |
const GLenum GL_MAP2_INDEX = 0x0DB1; |
|---|
| 461 |
const GLenum GL_MAP2_NORMAL = 0x0DB2; |
|---|
| 462 |
const GLenum GL_MAP2_TEXTURE_COORD_1 = 0x0DB3; |
|---|
| 463 |
const GLenum GL_MAP2_TEXTURE_COORD_2 = 0x0DB4; |
|---|
| 464 |
const GLenum GL_MAP2_TEXTURE_COORD_3 = 0x0DB5; |
|---|
| 465 |
const GLenum GL_MAP2_TEXTURE_COORD_4 = 0x0DB6; |
|---|
| 466 |
const GLenum GL_MAP2_VERTEX_3 = 0x0DB7; |
|---|
| 467 |
const GLenum GL_MAP2_VERTEX_4 = 0x0DB8; |
|---|
| 468 |
const GLenum GL_MAP1_GRID_DOMAIN = 0x0DD0; |
|---|
| 469 |
const GLenum GL_MAP1_GRID_SEGMENTS = 0x0DD1; |
|---|
| 470 |
const GLenum GL_MAP2_GRID_DOMAIN = 0x0DD2; |
|---|
| 471 |
const GLenum GL_MAP2_GRID_SEGMENTS = 0x0DD3; |
|---|
| 472 |
const GLenum GL_TEXTURE_1D = 0x0DE0; |
|---|
| 473 |
const GLenum GL_TEXTURE_2D = 0x0DE1; |
|---|
| 474 |
const GLenum GL_FEEDBACK_BUFFER_POINTER = 0x0DF0; |
|---|
| 475 |
const GLenum GL_FEEDBACK_BUFFER_SIZE = 0x0DF1; |
|---|
| 476 |
const GLenum GL_FEEDBACK_BUFFER_TYPE = 0x0DF2; |
|---|
| 477 |
const GLenum GL_SELECTION_BUFFER_POINTER = 0x0DF3; |
|---|
| 478 |
const GLenum GL_SELECTION_BUFFER_SIZE = 0x0DF4; |
|---|
| 479 |
const GLenum GL_POLYGON_OFFSET_UNITS = 0x2A00; |
|---|
| 480 |
const GLenum GL_POLYGON_OFFSET_POINT = 0x2A01; |
|---|
| 481 |
const GLenum GL_POLYGON_OFFSET_LINE = 0x2A02; |
|---|
| 482 |
const GLenum GL_POLYGON_OFFSET_FILL = 0x8037; |
|---|
| 483 |
const GLenum GL_POLYGON_OFFSET_FACTOR = 0x8038; |
|---|
| 484 |
const GLenum GL_TEXTURE_BINDING_1D = 0x8068; |
|---|
| 485 |
const GLenum GL_TEXTURE_BINDING_2D = 0x8069; |
|---|
| 486 |
const GLenum GL_TEXTURE_BINDING_3D = 0x806A; |
|---|
| 487 |
const GLenum GL_VERTEX_ARRAY = 0x8074; |
|---|
| 488 |
const GLenum GL_NORMAL_ARRAY = 0x8075; |
|---|
| 489 |
const GLenum GL_COLOR_ARRAY = 0x8076; |
|---|
| 490 |
const GLenum GL_INDEX_ARRAY = 0x8077; |
|---|
| 491 |
const GLenum GL_TEXTURE_COORD_ARRAY = 0x8078; |
|---|
| 492 |
const GLenum GL_EDGE_FLAG_ARRAY = 0x8079; |
|---|
| 493 |
const GLenum GL_VERTEX_ARRAY_SIZE = 0x807A; |
|---|
| 494 |
const GLenum GL_VERTEX_ARRAY_TYPE = 0x807B; |
|---|
| 495 |
const GLenum GL_VERTEX_ARRAY_STRIDE = 0x807C; |
|---|
| 496 |
const GLenum GL_NORMAL_ARRAY_TYPE = 0x807E; |
|---|
| 497 |
const GLenum GL_NORMAL_ARRAY_STRIDE = 0x807F; |
|---|
| 498 |
const GLenum GL_COLOR_ARRAY_SIZE = 0x8081; |
|---|
| 499 |
const GLenum GL_COLOR_ARRAY_TYPE = 0x8082; |
|---|
| 500 |
const GLenum GL_COLOR_ARRAY_STRIDE = 0x8083; |
|---|
| 501 |
const GLenum GL_INDEX_ARRAY_TYPE = 0x8085; |
|---|
| 502 |
const GLenum GL_INDEX_ARRAY_STRIDE = 0x8086; |
|---|
| 503 |
const GLenum GL_TEXTURE_COORD_ARRAY_SIZE = 0x8088; |
|---|
| 504 |
const GLenum GL_TEXTURE_COORD_ARRAY_TYPE = 0x8089; |
|---|
| 505 |
const GLenum GL_TEXTURE_COORD_ARRAY_STRIDE = 0x808A; |
|---|
| 506 |
const GLenum GL_EDGE_FLAG_ARRAY_STRIDE = 0x808C; |
|---|
| 507 |
const GLenum GL_TEXTURE_WIDTH = 0x1000; |
|---|
| 508 |
const GLenum GL_TEXTURE_HEIGHT = 0x1001; |
|---|
| 509 |
const GLenum GL_TEXTURE_INTERNAL_FORMAT = 0x1003; |
|---|
| 510 |
const GLenum GL_TEXTURE_COMPONENTS = GL_TEXTURE_INTERNAL_FORMAT; |
|---|
| 511 |
const GLenum GL_TEXTURE_BORDER_COLOR = 0x1004; |
|---|
| 512 |
const GLenum GL_TEXTURE_BORDER = 0x1005; |
|---|
| 513 |
const GLenum GL_TEXTURE_RED_SIZE = 0x805C; |
|---|
| 514 |
const GLenum GL_TEXTURE_GREEN_SIZE = 0x805D; |
|---|
| 515 |
const GLenum GL_TEXTURE_BLUE_SIZE = 0x805E; |
|---|
| 516 |
const GLenum GL_TEXTURE_ALPHA_SIZE = 0x805F; |
|---|
| 517 |
const GLenum GL_TEXTURE_LUMINANCE_SIZE = 0x8060; |
|---|
| 518 |
const GLenum GL_TEXTURE_INTENSITY_SIZE = 0x8061; |
|---|
| 519 |
const GLenum GL_TEXTURE_PRIORITY = 0x8066; |
|---|
| 520 |
const GLenum GL_TEXTURE_RESIDENT = 0x8067; |
|---|
| 521 |
const GLenum GL_DONT_CARE = 0x1100; |
|---|
| 522 |
const GLenum GL_FASTEST = 0x1101; |
|---|
| 523 |
const GLenum GL_NICEST = 0x1102; |
|---|
| 524 |
typedef GLenum LightSource; |
|---|
| 525 |
const LightSource GL_LIGHT0=0x4000, |
|---|
| 526 |
GL_LIGHT1=GL_LIGHT0+1, GL_LIGHT2=GL_LIGHT1+1, |
|---|
| 527 |
GL_LIGHT3=GL_LIGHT2+1, GL_LIGHT4=GL_LIGHT3+1, |
|---|
| 528 |
GL_LIGHT5=GL_LIGHT4+1, GL_LIGHT6=GL_LIGHT5+1, |
|---|
| 529 |
GL_LIGHT7=GL_LIGHT6+1; |
|---|
| 530 |
} |
|---|
| 531 |
|
|---|
| 532 |
extern(System) { |
|---|
| 533 |
void glLightf(LightSource, GLenum pname, float); |
|---|
| 534 |
void glLightfv(LightSource, GLenum pname, float *); |
|---|
| 535 |
void glLighti(LightSource, GLenum pname, int); |
|---|
| 536 |
void glLightiv(LightSource, GLenum pname, int *); |
|---|
| 537 |
} |
|---|
| 538 |
template LightProperty(string name, GLenum GL, int params) { |
|---|
| 539 |
mixin("void "~name~"("~(params?"float["~params.stringof~"]":"float")~" par) { |
|---|
| 540 |
glLightf"~(params?"v":"")~"(index, GL, par"~(params?".ptr":"")~"); |
|---|
| 541 |
}"); |
|---|
| 542 |
} |
|---|
| 543 |
struct Light { |
|---|
| 544 |
LightSource index; |
|---|
| 545 |
void position(float[3] par, bool point=true) { |
|---|
| 546 |
float[4] fullpar; fullpar[0..3]=par; |
|---|
| 547 |
if (point) fullpar[3]=1f; else fullpar[3]=0f; |
|---|
| 548 |
glLightfv(index, GL_POSITION, fullpar.ptr); |
|---|
| 549 |
} |
|---|
| 550 |
void enable() { glEnable(index); } |
|---|
| 551 |
mixin MultiMixin!(LightProperty, 3, |
|---|
| 552 |
"ambient", GL_AMBIENT, 4, "diffuse", GL_DIFFUSE, 4, |
|---|
| 553 |
"specular", GL_SPECULAR, 4, "spot_direction", GL_SPOT_DIRECTION, 3, |
|---|
| 554 |
"spot_exponent", GL_SPOT_EXPONENT, 0, "spot_cutoff", GL_SPOT_CUTOFF, 0, |
|---|
| 555 |
"constant_attenuation", GL_CONSTANT_ATTENUATION, 0, |
|---|
| 556 |
"linear_attenuation", GL_LINEAR_ATTENUATION, 0, |
|---|
| 557 |
"quadratic_attenuation", GL_QUADRATIC_ATTENUATION, 0 |
|---|
| 558 |
); |
|---|
| 559 |
static Light opIndex(size_t which) { |
|---|
| 560 |
assert(which<8, "Allowed number of light sources exceeded!"); |
|---|
| 561 |
return Light(cast(LightSource)(GL_LIGHT0+which)); |
|---|
| 562 |
} |
|---|
| 563 |
} |
|---|
| 564 |
|
|---|
| 565 |
extern(System) { |
|---|
| 566 |
typedef GLenum ErrorCode; |
|---|
| 567 |
mixin ConstEnum!(ErrorCode, "+1", Prepend!( |
|---|
| 568 |
"GL_", 0, "NO_ERROR", 0x0500, Expand!("INVALID_{ENUM|VALUE|OPERATION}"), |
|---|
| 569 |
Expand!("STACK_{OVER|UNDER}FLOW"), "OUT_OF_MEMORY", |
|---|
| 570 |
0x8031, "TABLE_TOO_LARGE" |
|---|
| 571 |
) |
|---|
| 572 |
); |
|---|
| 573 |
char *gluErrorString(ErrorCode); |
|---|
| 574 |
ErrorCode glGetError(); |
|---|
| 575 |
} |
|---|
| 576 |
|
|---|
| 577 |
string glErrorToString(ErrorCode err) { |
|---|
| 578 |
auto res=gluErrorString(err), cur=res; |
|---|
| 579 |
while (*cur) cur++; |
|---|
| 580 |
return res[0..(cur-res)]; |
|---|
| 581 |
} |
|---|
| 582 |
|
|---|
| 583 |
import std.string: toString; |
|---|
| 584 |
void glChecked(string label, void delegate()[] dgs...) { |
|---|
| 585 |
foreach (idx, dg; dgs) { |
|---|
| 586 |
if (auto err=glGetError()) |
|---|
| 587 |
if (!idx) throw new Exception("OpenGL error before checked section"~(label.length?" \""~label~"\"":"")~": "~glErrorToString(err)); |
|---|
| 588 |
else throw new Exception("OpenGL error in "~(label.length?"\""~label~"\", ":"")~"command "~toString(idx)~": "~glErrorToString(err)); |
|---|
| 589 |
dg(); |
|---|
| 590 |
} |
|---|
| 591 |
if (auto err=glGetError()) { |
|---|
| 592 |
if (label.length) throw new Exception("OpenGL error in \""~label~"\""~(dgs.length>1?", last command":"")~": "~glErrorToString(err)); |
|---|
| 593 |
else throw new Exception("OpenGL error in"~(dgs.length>1?" last":"")~" command: "~glErrorToString(err)); |
|---|
| 594 |
} |
|---|
| 595 |
} |
|---|
| 596 |
|
|---|
| 597 |
extern(System) { |
|---|
| 598 |
void glGenTextures(int n, uint *textures); |
|---|
| 599 |
bool glIsTexture(uint texture); |
|---|
| 600 |
void glBindTexture(GLenum target, uint texture); |
|---|
| 601 |
void glDeleteTextures(int n, uint *textures); |
|---|
| 602 |
|
|---|
| 603 |
void glTexImage2D(GLenum target, int level, PixelFormat internalFormat, int width, int height, int border, PixelFormat, DataType, void *pixels); |
|---|
| 604 |
void gluBuild2DMipmaps(GLenum target, PixelFormat internalFormat, int width, int height, PixelFormat, DataType, void *pixels); |
|---|
| 605 |
void glTexParameterf(GLenum target, GLenum pname, float param); |
|---|
| 606 |
void glTexParameterfv(GLenum target, GLenum pname, float *param); |
|---|
| 607 |
void glTexParameteri(GLenum target, GLenum pname, int param); |
|---|
| 608 |
void glTexParameteriv(GLenum target, GLenum pname, int *param); |
|---|
| 609 |
typedef GLenum PixelFormat; |
|---|
| 610 |
mixin ConstEnum!(PixelFormat, "+1", 0x1900, Prepend!("GL_", |
|---|
| 611 |
"COLOR_INDEX", "STENCIL_INDEX", "DEPTH_COMPONENT", |
|---|
| 612 |
"RED", "GREEN", "BLUE", "ALPHA", |
|---|
| 613 |
"RGB", "RGBA", "LUMINANCE", "LUMINANCE_ALPHA" |
|---|
| 614 |
) |
|---|
| 615 |
); |
|---|
| 616 |
typedef GLenum DataType; |
|---|
| 617 |
mixin ConstEnum!(DataType, "+1", 0x1400, Prepend!("GL_", |
|---|
| 618 |
"BYTE", "UNSIGNED_BYTE", "SHORT", "UNSIGNED_SHORT", |
|---|
| 619 |
"INT", "UNSIGNED_INT", "FLOAT", Expand!("{2|3|4}_BYTES"), |
|---|
| 620 |
"DOUBLE" |
|---|
| 621 |
) |
|---|
| 622 |
); |
|---|
| 623 |
typedef GLenum TextureParameterName; |
|---|
| 624 |
mixin ConstEnum!(TextureParameterName, "+1", 0x2800, Prepend!("GL_TEXTURE_", "MAG_FILTER", "MIN_FILTER", "WRAP_S", "WRAP_T")); |
|---|
| 625 |
const GLenum GL_NEAREST=0x2600, GL_LINEAR=0x2601, GL_CLAMP=0x2900, GL_REPEAT=0x2901; |
|---|
| 626 |
mixin ConstEnum!(GLenum, "+1", 0x2700, Prepend!("GL_", |
|---|
| 627 |
Append!("_NEAREST", Expand!("{NEAREST|LINEAR}_MIPMAP")), |
|---|
| 628 |
Append!("_LINEAR", Expand!("{NEAREST|LINEAR}_MIPMAP")) |
|---|
| 629 |
)); |
|---|
| 630 |
|
|---|
| 631 |
} |
|---|
| 632 |
|
|---|
| 633 |
extern(System) { |
|---|
| 634 |
typedef GLenum StringName; |
|---|
| 635 |
void glGetDoublev(GLenum, double *); |
|---|
| 636 |
char *glGetString(StringName); |
|---|
| 637 |
void glGetFloatv(GLenum, float *); |
|---|
| 638 |
void glGetIntegerv(GLenum, int *); |
|---|
| 639 |
|
|---|
| 640 |
const StringName GL_VENDOR=0x1F00, GL_RENDERER=0x1F01, GL_VERSION=0x1F02, GL_EXTENSIONS=0x1F03; |
|---|
| 641 |
} |
|---|
| 642 |
|
|---|
| 643 |
class Texture { |
|---|
| 644 |
uint me; |
|---|
| 645 |
int width, height; |
|---|
| 646 |
this(size_t w, size_t h, bool mipmap, ubyte[] data) { |
|---|
| 647 |
width=w; height=h; |
|---|
| 648 |
glChecked("GenTextures", glGenTextures(1, &me)); |
|---|
| 649 |
bind; |
|---|
| 650 |
if (mipmap) glChecked("TexMinFilterMipmap", glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST)); |
|---|
| 651 |
else glChecked("TexMinFilter", glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); |
|---|
| 652 |
glChecked("TexParams", glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR), |
|---|
| 653 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT), |
|---|
| 654 |
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) |
|---|
| 655 |
); |
|---|
| 656 |
if (mipmap) { |
|---|
| 657 |
glChecked("TexBuildMipmaps", gluBuild2DMipmaps(GL_TEXTURE_2D, 4, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data.length?data.ptr:null)); |
|---|
| 658 |
} else { |
|---|
| 659 |
glChecked("TexGenImage", glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data.length?data.ptr:null)); |
|---|
| 660 |
} |
|---|
| 661 |
} |
|---|
| 662 |
this(size_t w, size_t h, bool mipmap=false) { ubyte[] empty; this(w, h, mipmap, empty); } |
|---|
| 663 |
this(size_t w, size_t h, bool mipmap, vec3f delegate(float u, float v) dg) { |
|---|
| 664 |
width=w; height=h; |
|---|
| 665 |
ubyte[] data; |
|---|
| 666 |
if (dg) { |
|---|
| 667 |
data=new ubyte[width*height*4]; |
|---|
| 668 |
size_t idx=0; |
|---|
| 669 |
for (int y=0; y<height; ++y) { |
|---|
| 670 |
for (int x=0; x<width; ++x) { |
|---|
| 671 |
auto col=dg(x/(1f*width), y/(1f/height)); |
|---|
| 672 |
data[idx+0]=cast(ubyte)(col.x*255); |
|---|
| 673 |
data[idx+1]=cast(ubyte)(col.y*255); |
|---|
| 674 |
data[idx+2]=cast(ubyte)(col.z*255); |
|---|
| 675 |
data[idx+3]=0; |
|---|
| 676 |
idx += 4; |
|---|
| 677 |
} |
|---|
| 678 |
} |
|---|
| 679 |
} |
|---|
| 680 |
this(width, height, mipmap, data); |
|---|
| 681 |
} |
|---|
| 682 |
static void enable() { glEnable(GL_TEXTURE_2D); } |
|---|
| 683 |
static void disable() { glDisable(GL_TEXTURE_2D); } |
|---|
| 684 |
void free() { glDeleteTextures(1, &me); me=0; } |
|---|
| 685 |
~this() { free; } |
|---|
| 686 |
|
|---|
| 687 |
static void bind(uint what) { glBindTexture(GL_TEXTURE_2D, what); } |
|---|
| 688 |
static uint bound() { uint res; glGetIntegerv(GL_TEXTURE_BINDING_2D, cast(int*)&res); return res; } |
|---|
| 689 |
void bind() { bind(me); } |
|---|
| 690 |
void With(void delegate()[] dgs...) { |
|---|
| 691 |
auto old=bound(); scope(exit) bind(old); |
|---|
| 692 |
bind; |
|---|
| 693 |
foreach (dg; dgs) dg(); |
|---|
| 694 |
} |
|---|
| 695 |
} |
|---|
| 696 |
|
|---|
| 697 |
extern(System) { |
|---|
| 698 |
void glViewport(int x, int y, int width, int height); |
|---|
| 699 |
} |
|---|