1 module gfx.gl3.conv; 2 3 package: 4 5 import gfx.bindings.opengl.gl; 6 import gfx.graal.buffer : BufferUsage, IndexType; 7 import gfx.graal.format : Format; 8 import gfx.graal.image : CompSwizzle, Filter, ImageType, Swizzle, WrapMode; 9 import gfx.graal.pipeline : BlendOp, BlendFactor, CompareOp, FrontFace, 10 PolygonMode, Primitive, ShaderStage, StencilOp; 11 12 GLenum toGl(in BufferUsage usage) pure { 13 switch (usage) { 14 case BufferUsage.transferSrc: return GL_COPY_READ_BUFFER; 15 case BufferUsage.transferDst: return GL_COPY_WRITE_BUFFER; 16 case BufferUsage.uniform: return GL_UNIFORM_BUFFER; 17 case BufferUsage.index: return GL_ELEMENT_ARRAY_BUFFER; 18 case BufferUsage.vertex: return GL_ARRAY_BUFFER; 19 case BufferUsage.indirect: return GL_DRAW_INDIRECT_BUFFER; 20 default: return 0; 21 } 22 } 23 24 GLenum toGlTexTarget(in ImageType type, in bool ms) pure { 25 final switch (type) { 26 case ImageType.d1: return GL_TEXTURE_1D; 27 case ImageType.d1Array: return GL_TEXTURE_1D_ARRAY; 28 case ImageType.d2: 29 return ms ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D; 30 case ImageType.d2Array: 31 return ms ? GL_TEXTURE_2D_MULTISAMPLE_ARRAY : GL_TEXTURE_2D_ARRAY; 32 case ImageType.d3: return GL_TEXTURE_3D; 33 case ImageType.cube: return GL_TEXTURE_CUBE_MAP; 34 case ImageType.cubeArray: return GL_TEXTURE_CUBE_MAP_ARRAY; 35 } 36 } 37 38 GLenum toGlImgFmt(in Format graalFormat) pure { 39 switch (graalFormat) { 40 case Format.r8_uNorm: return GL_R8; 41 case Format.rg8_uNorm: return GL_RG8; 42 case Format.rgba8_uNorm: return GL_RGBA8; 43 case Format.r8_sInt: return GL_R8I; 44 case Format.rg8_sInt: return GL_RG8I; 45 case Format.rgba8_sInt: return GL_RGBA8I; 46 case Format.r8_uInt: return GL_R8UI; 47 case Format.rg8_uInt: return GL_RG8UI; 48 case Format.rgba8_uInt: return GL_RGBA8UI; 49 case Format.r16_uNorm: return GL_R16; 50 case Format.rg16_uNorm: return GL_RG16; 51 case Format.rgba16_uNorm: return GL_RGBA16; 52 case Format.r16_sInt: return GL_R16I; 53 case Format.rg16_sInt: return GL_RG16I; 54 case Format.rgba16_sInt: return GL_RGBA16I; 55 case Format.r16_uInt: return GL_R16UI; 56 case Format.rg16_uInt: return GL_RG16UI; 57 case Format.rgba16_uInt: return GL_RGBA16UI; 58 case Format.d16_uNorm: return GL_DEPTH_COMPONENT16; 59 case Format.x8d24_uNorm: return GL_DEPTH_COMPONENT24; 60 case Format.d32_sFloat: return GL_DEPTH_COMPONENT32F; 61 case Format.d24s8_uNorm: return GL_DEPTH24_STENCIL8; 62 case Format.s8_uInt: return GL_STENCIL_INDEX8; 63 default: 64 import std.format : format; 65 throw new Exception(format("Gfx-GL3: Format.%s is not supported.", graalFormat)); 66 } 67 } 68 69 GLenum toSubImgFmt(in Format graalFormat) pure { 70 switch(graalFormat) { 71 case Format.r8_uNorm: return GL_RED; 72 case Format.rg8_uNorm: return GL_RG; 73 case Format.rgba8_uNorm: return GL_RGBA; 74 case Format.r8_sInt: return GL_RED; 75 case Format.rg8_sInt: return GL_RG; 76 case Format.rgba8_sInt: return GL_RGBA; 77 case Format.r8_uInt: return GL_RED; 78 case Format.rg8_uInt: return GL_RG; 79 case Format.rgba8_uInt: return GL_RGBA; 80 case Format.r16_uNorm: return GL_RED; 81 case Format.rg16_uNorm: return GL_RG; 82 case Format.rgba16_uNorm: return GL_RGBA; 83 case Format.r16_sInt: return GL_RED; 84 case Format.rg16_sInt: return GL_RG; 85 case Format.rgba16_sInt: return GL_RGBA; 86 case Format.r16_uInt: return GL_RED; 87 case Format.rg16_uInt: return GL_RG; 88 case Format.rgba16_uInt: return GL_RGBA; 89 case Format.d16_uNorm: return GL_DEPTH_COMPONENT; 90 case Format.x8d24_uNorm: return GL_DEPTH_COMPONENT; 91 case Format.d32_sFloat: return GL_DEPTH_COMPONENT; 92 case Format.d24s8_uNorm: return GL_DEPTH_COMPONENT; 93 case Format.s8_uInt: return GL_STENCIL_INDEX; 94 default: 95 import std.format : format; 96 throw new Exception(format("Gfx-GL3: Format.%s is not supported.", graalFormat)); 97 } 98 } 99 100 GLenum toSubImgType(in Format graalFormat) pure { 101 switch(graalFormat) { 102 case Format.r8_uNorm: 103 case Format.rg8_uNorm: 104 case Format.rgba8_uNorm: 105 case Format.r8_sInt: 106 case Format.rg8_sInt: 107 case Format.rgba8_sInt: 108 case Format.r8_uInt: 109 case Format.rg8_uInt: 110 case Format.rgba8_uInt: 111 return GL_UNSIGNED_BYTE; 112 case Format.r16_uNorm: 113 case Format.rg16_uNorm: 114 case Format.rgba16_uNorm: 115 case Format.r16_sInt: 116 case Format.rg16_sInt: 117 case Format.rgba16_sInt: 118 case Format.r16_uInt: 119 case Format.rg16_uInt: 120 case Format.rgba16_uInt: 121 case Format.d16_uNorm: 122 return GL_UNSIGNED_SHORT; 123 case Format.x8d24_uNorm: 124 return GL_UNSIGNED_INT; 125 case Format.d32_sFloat: 126 return GL_FLOAT; 127 case Format.d24s8_uNorm: 128 return GL_UNSIGNED_INT; 129 case Format.s8_uInt: 130 return GL_UNSIGNED_BYTE; 131 default: 132 import std.format : format; 133 throw new Exception(format("Gfx-GL3: Format.%s is not supported.", graalFormat)); 134 } 135 } 136 137 GLenum toGlMag(in Filter filter) pure { 138 final switch(filter) { 139 case Filter.nearest: return GL_NEAREST; 140 case Filter.linear: return GL_LINEAR; 141 } 142 } 143 GLenum toGlMin(in Filter filter, in Filter mipmap) pure { 144 final switch(filter) { 145 case Filter.nearest: 146 final switch (mipmap) { 147 case Filter.nearest: return GL_NEAREST_MIPMAP_NEAREST; 148 case Filter.linear: return GL_NEAREST_MIPMAP_LINEAR; 149 } 150 case Filter.linear: 151 final switch (mipmap) { 152 case Filter.nearest: return GL_LINEAR_MIPMAP_NEAREST; 153 case Filter.linear: return GL_LINEAR_MIPMAP_LINEAR; 154 } 155 } 156 } 157 GLenum toGl(in WrapMode mode) pure { 158 final switch (mode) { 159 case WrapMode.repeat: return GL_REPEAT; 160 case WrapMode.mirrorRepeat: return GL_MIRRORED_REPEAT; 161 case WrapMode.clamp: return GL_CLAMP_TO_EDGE; 162 case WrapMode.border: return GL_CLAMP_TO_BORDER; 163 } 164 } 165 166 GLenum toGl(in CompareOp op) pure { 167 final switch (op) { 168 case CompareOp.never: return GL_NEVER; 169 case CompareOp.less: return GL_LESS; 170 case CompareOp.equal: return GL_EQUAL; 171 case CompareOp.lessOrEqual: return GL_LEQUAL; 172 case CompareOp.greater: return GL_GREATER; 173 case CompareOp.notEqual: return GL_NOTEQUAL; 174 case CompareOp.greaterOrEqual: return GL_GEQUAL; 175 case CompareOp.always: return GL_ALWAYS; 176 } 177 } 178 179 GLenum toGl(in StencilOp op) pure { 180 final switch (op) { 181 case StencilOp.keep: return GL_KEEP; 182 case StencilOp.zero: return GL_ZERO; 183 case StencilOp.replace: return GL_REPLACE; 184 case StencilOp.incrementAndClamp: return GL_INCR; 185 case StencilOp.decrementAndClamp: return GL_DECR; 186 case StencilOp.invert: return GL_INVERT; 187 case StencilOp.incrementAndWrap: return GL_INCR_WRAP; 188 case StencilOp.decrementAndWrap: return GL_DECR_WRAP; 189 } 190 } 191 192 GLenum toGl(in ShaderStage stage) pure { 193 switch (stage) { 194 case ShaderStage.vertex: return GL_VERTEX_SHADER; 195 case ShaderStage.tessellationControl: return GL_TESS_CONTROL_SHADER; 196 case ShaderStage.tessellationEvaluation: return GL_TESS_EVALUATION_SHADER; 197 case ShaderStage.geometry: return GL_GEOMETRY_SHADER; 198 case ShaderStage.fragment: return GL_FRAGMENT_SHADER; 199 case ShaderStage.compute: return GL_COMPUTE_SHADER; 200 default: assert(false); 201 } 202 } 203 204 GLenum toGl(in IndexType type) pure { 205 final switch (type) { 206 case IndexType.u16: return GL_UNSIGNED_SHORT; 207 case IndexType.u32: return GL_UNSIGNED_INT; 208 } 209 } 210 211 GLenum toGl(in Primitive primitive) pure { 212 final switch (primitive) { 213 case Primitive.pointList: return GL_POINTS; 214 case Primitive.lineList: return GL_LINES; 215 case Primitive.lineStrip: return GL_LINE_STRIP; 216 case Primitive.triangleList: return GL_TRIANGLES; 217 case Primitive.triangleStrip: return GL_TRIANGLE_STRIP; 218 case Primitive.triangleFan: return GL_TRIANGLE_FAN; 219 case Primitive.lineListAdjacency: return GL_LINES_ADJACENCY; 220 case Primitive.lineStripAdjacency: return GL_LINE_STRIP_ADJACENCY; 221 case Primitive.triangleListAdjacency: return GL_TRIANGLES_ADJACENCY; 222 case Primitive.triangleStripAdjacency: return GL_TRIANGLE_STRIP_ADJACENCY; 223 case Primitive.patchList: return GL_PATCHES; 224 } 225 } 226 227 GLenum toGl(in FrontFace ff) pure { 228 final switch (ff) { 229 case FrontFace.ccw: return GL_CCW; 230 case FrontFace.cw: return GL_CW; 231 } 232 } 233 234 GLenum toGl(in PolygonMode pm) pure { 235 final switch (pm) { 236 case PolygonMode.point: return GL_POINT; 237 case PolygonMode.line: return GL_LINE; 238 case PolygonMode.fill: return GL_FILL; 239 } 240 } 241 242 GLenum toGl(in BlendOp op) { 243 final switch(op) { 244 case BlendOp.add: return GL_FUNC_ADD; 245 case BlendOp.subtract: return GL_FUNC_SUBTRACT; 246 case BlendOp.reverseSubtract: return GL_FUNC_REVERSE_SUBTRACT; 247 case BlendOp.min: return GL_MIN; 248 case BlendOp.max: return GL_MAX; 249 } 250 } 251 252 GLenum toGl(in BlendFactor f) { 253 final switch (f) { 254 case BlendFactor.zero: return GL_ZERO; 255 case BlendFactor.one: return GL_ONE; 256 case BlendFactor.srcColor: return GL_SRC_COLOR; 257 case BlendFactor.oneMinusSrcColor: return GL_ONE_MINUS_SRC_COLOR; 258 case BlendFactor.dstColor: return GL_DST_COLOR; 259 case BlendFactor.oneMinusDstColor: return GL_ONE_MINUS_DST_COLOR; 260 case BlendFactor.srcAlpha: return GL_SRC_ALPHA; 261 case BlendFactor.oneMinusSrcAlpha: return GL_ONE_MINUS_SRC_ALPHA; 262 case BlendFactor.dstAlpha: return GL_DST_ALPHA; 263 case BlendFactor.oneMinusDstAlpha: return GL_ONE_MINUS_DST_ALPHA; 264 case BlendFactor.constantColor: return GL_CONSTANT_COLOR; 265 case BlendFactor.oneMinusConstantColor: return GL_ONE_MINUS_CONSTANT_COLOR; 266 case BlendFactor.constantAlpha: return GL_CONSTANT_ALPHA; 267 case BlendFactor.oneMinusConstantAlpha: return GL_ONE_MINUS_CONSTANT_ALPHA; 268 case BlendFactor.srcAlphaSaturate: return GL_SRC_ALPHA_SATURATE; 269 case BlendFactor.src1Color: return GL_SRC1_COLOR; 270 case BlendFactor.oneMinusSrc1Color: return GL_ONE_MINUS_SRC1_COLOR; 271 case BlendFactor.src1Alpha: return GL_SRC1_ALPHA; 272 case BlendFactor.oneMinusSrc1Alpha: return GL_ONE_MINUS_SRC1_ALPHA; 273 } 274 } 275 276 GLint toGl(in CompSwizzle cs) 277 { 278 switch (cs) 279 { 280 case CompSwizzle.zero: return GL_ZERO; 281 case CompSwizzle.one: return GL_ONE; 282 case CompSwizzle.r: return GL_RED; 283 case CompSwizzle.g: return GL_GREEN; 284 case CompSwizzle.b: return GL_BLUE; 285 case CompSwizzle.a: return GL_ALPHA; 286 default: assert(false); 287 } 288 } 289 290 GLint[4] toGl(in Swizzle swizzle) 291 { 292 const GLint[4] glSw = [ 293 swizzle[0] == CompSwizzle.identity ? GL_RED : toGl(swizzle[0]), 294 swizzle[1] == CompSwizzle.identity ? GL_GREEN : toGl(swizzle[1]), 295 swizzle[2] == CompSwizzle.identity ? GL_BLUE : toGl(swizzle[2]), 296 swizzle[3] == CompSwizzle.identity ? GL_ALPHA : toGl(swizzle[3]), 297 ]; 298 return glSw; 299 } 300 301 bool vertexFormatSupported(in Format f) pure { 302 import std.algorithm : canFind; 303 return supportedVertexFormats.canFind(f); 304 } 305 306 /// Specifies the function to define the VAO vertex attribs 307 enum VAOAttribFun { 308 /// glVertexAttribPointer 309 f, 310 /// glVertexAttribIPointer 311 i, 312 /// glVertexAttribLPointer 313 d 314 } 315 316 struct GlVertexFormat { 317 VAOAttribFun fun; 318 GLint size; 319 GLenum type; 320 GLboolean normalized; 321 } 322 323 GlVertexFormat glVertexFormat(in Format f) 324 in { 325 assert(vertexFormatSupported(f)); 326 } 327 body { 328 return glVertexFormats[cast(size_t)f]; 329 } 330 331 private: 332 333 // TODO: support more formats (unorms, integer...) 334 335 immutable(GlVertexFormat[]) glVertexFormats; 336 337 immutable(Format[]) supportedVertexFormats = [ 338 Format.r32_sFloat, 339 Format.rg32_sFloat, 340 Format.rgb32_sFloat, 341 Format.rgba32_sFloat, 342 ]; 343 344 shared static this() { 345 import gfx.graal.format : formatDesc, numComponents; 346 import std.algorithm : map, maxElement; 347 import std.exception : assumeUnique; 348 349 const len = 1 + supportedVertexFormats 350 .map!(f => cast(int)f) 351 .maxElement; 352 auto vertexFormats = new GlVertexFormat[len]; 353 foreach (f; supportedVertexFormats) { 354 const fd = formatDesc(f); 355 const size = numComponents(fd.surfaceType); 356 vertexFormats[cast(int)f] = GlVertexFormat( 357 VAOAttribFun.f, size, GL_FLOAT, GL_FALSE 358 ); 359 } 360 361 glVertexFormats = assumeUnique(vertexFormats); 362 }