diff options
author | Araq <rumpf_a@web.de> | 2013-07-24 23:07:28 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2013-07-24 23:07:28 +0200 |
commit | 9acdf94cc04726cb80e3012849d8f56f06615017 (patch) | |
tree | 1f0d2ecabc58bcb0a240000b24d282e4fa5afeb2 /tests/manyloc | |
parent | b1d4dfa6b1dc1b4f28f4634e95346d893f328465 (diff) | |
download | Nim-9acdf94cc04726cb80e3012849d8f56f06615017.tar.gz |
fixes #531
Diffstat (limited to 'tests/manyloc')
13 files changed, 662 insertions, 0 deletions
diff --git a/tests/manyloc/named_argument_bug/gui.nim b/tests/manyloc/named_argument_bug/gui.nim new file mode 100644 index 000000000..1e0bc6ffd --- /dev/null +++ b/tests/manyloc/named_argument_bug/gui.nim @@ -0,0 +1,44 @@ +import + tri_engine/gfx/gl/primitive, + tri_engine/gfx/tex, + tri_engine/gfx/color, + tri_engine/math/rect, + tri_engine/math/vec + +type + TWidgetLayer* = enum + wlBg = 100, + wlOverlap = 200, + wlMain = 300, + wlOverlay = 400, + wlCursor = 500 + TWidgetLayerType = TWidgetLayer|int + TWidgetType* = enum + wtImg + PWidget* = ref object + `type`* : TWidgetType + layer* : TWidgetLayer + rect* : TRect + prim* : PPrimitive + +const + baseZ = 5000 + +proc newWidget*(`type`: TWidgetType, layer: TWidgetLayerType, rect: TRect): PWidget = + new(result) + result.`type` = `type` + result.layer = layer + result.rect = rect + + var verts = newVert(rect) + + # This works because z is accessible at this scope. + #var z = baseZ + layer.int + #result.prim = newPrimitive(verts, z=z) + + # Doesn't work, because the compiler looks for a symbol called z in this scope, + # but it should only check that it is the name of one of the params. + #result.prim = newPrimitive(verts, z=baseZ + layer.int) + + # This doesn't work either. + result.prim = newPrimitive(verts, z=0) diff --git a/tests/manyloc/named_argument_bug/main.nim b/tests/manyloc/named_argument_bug/main.nim new file mode 100644 index 000000000..767674428 --- /dev/null +++ b/tests/manyloc/named_argument_bug/main.nim @@ -0,0 +1,23 @@ +import + tri_engine/config, + tri_engine/math/vec, + tri_engine/math/circle, + tri_engine/gfx/gl/primitive, + tri_engine/gfx/tex, + tri_engine/gfx/color, + tri_engine/tri_engine, + gui + +var isRunning = true + +block: + var renderer = newRenderer(w=10, h=10) + + var primitive = newPrimitiveCircle(0.3.TR, color=white(0.5, 0.8), z=15) + renderer.addPrimitive(primitive) + + var verts = newVert((min: newV2xy(-0.4), size: newV2xy(0.3))) + var primitive2 = newPrimitive(verts, color=red(0.5, 0.8), z=10) + renderer.addPrimitive(primitive2) + + var mainMenuWidget = newWidget(wtImg, wlBg, rect=(newV2xy(-1.0), newV2xy(2.0))) diff --git a/tests/manyloc/named_argument_bug/main.nimrod.cfg b/tests/manyloc/named_argument_bug/main.nimrod.cfg new file mode 100644 index 000000000..27cf8e688 --- /dev/null +++ b/tests/manyloc/named_argument_bug/main.nimrod.cfg @@ -0,0 +1,2 @@ +# this file only exists to mark 'main.nim' as the main file + diff --git a/tests/manyloc/named_argument_bug/tri_engine/config.nim b/tests/manyloc/named_argument_bug/tri_engine/config.nim new file mode 100644 index 000000000..b90dc0b26 --- /dev/null +++ b/tests/manyloc/named_argument_bug/tri_engine/config.nim @@ -0,0 +1,6 @@ +when defined(doublePrecision): + type + TR* = float64 +else: + type + TR* = float32 diff --git a/tests/manyloc/named_argument_bug/tri_engine/gfx/color.nim b/tests/manyloc/named_argument_bug/tri_engine/gfx/color.nim new file mode 100644 index 000000000..8e47c1f2f --- /dev/null +++ b/tests/manyloc/named_argument_bug/tri_engine/gfx/color.nim @@ -0,0 +1,57 @@ +import + tri_engine/config, + tri_engine/math/vec + +from strutils import + formatFloat, + TFloatFormat, + `%` + +from unsigned import + `shr`, + `and` + +type + TColor* = tuple[r, g, b, a: TR] + +converter toColor*(o: uint32): TColor = + ## Convert an integer to a color. This is mostly useful when the integer is specified as a hex + ## literal such as 0xFF00007F, which is 100% red, with 50% alpha. + ## TODO: turn this into a template that can take either 4 or 8 characters? + ((((o and 0xff000000'u32) shr 24).TR / 255.0).TR, + (((o and 0xff0000'u32) shr 16).TR / 255.0).TR, + (((o and 0xff00'u32) shr 8).TR / 255.0).TR, + (((o and 0xff'u32)).TR / 255.0).TR) + +converter toV4*(o: TColor): TV4[TR] = + cast[TV4[TR]](o) + +proc newColor*(r, g, b: TR=0.0, a: TR=1.0): TColor = + (r, g, b, a) + +proc white*(rgb, a: TR=1.0): TColor = + (rgb, rgb, rgb, a) + +proc red*(r, a: TR=1.0): TColor = + newColor(r=r, a=a) + +proc green*(g, a: TR=1.0): TColor = + newColor(g=g, a=a) + +proc yellow*(rg, a: TR=1.0): TColor = + newColor(r=rg, g=rg, a=a) + +proc blue*(b, a: TR=1.0): TColor = + newColor(b=b, a=a) + +proc cyan*(gb, a: TR=1.0): TColor = + newColor(g=gb, b=gb, a=a) + +proc purple*(rb, a: TR=1.0): TColor = + newColor(r=rb, b=rb, a=a) + +proc `$`*(o: TColor): string = + proc f(f: float): string = + f.formatFloat(precision=2, format=ffDecimal) + + "(r: $#, g: $#, b: $#, s: $#)" % [f(o.r), f(o.g), f(o.b), f(o.a)] diff --git a/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/gl.nim b/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/gl.nim new file mode 100644 index 000000000..e731969c1 --- /dev/null +++ b/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/gl.nim @@ -0,0 +1,61 @@ +import + opengl, + tri_engine/math/vec + +export + opengl + +type + EGL* = object of E_Base + EGL_code* = object of EGL + code*: EGL_err + EGL_err {.pure.} = enum + none = GL_NO_ERROR + invalidEnum = GL_INVALID_ENUM + invalidVal = GL_INVALID_VALUE + invalidOp = GL_INVALID_OPERATION + stackOverflow = GL_STACK_OVERFLOW + stackUnderflow = GL_STACK_UNDERFLOW + outOfMem = GL_OUT_OF_MEMORY + invalidFramebufferOp = GL_INVALID_FRAMEBUFFER_OPERATION + unknown + +proc newGL_codeException*(msg: string, code: EGL_err): ref EGL_code = + result = newException(EGL_code, $code) + result.code = code + +proc getErr*(): EGL_err = + result = glGetError().EGL_err + if result notin {EGL_err.none, + EGL_err.invalidEnum, + EGL_err.invalidVal, + EGL_err.invalidOp, + EGL_err.invalidFramebufferOp, + EGL_err.outOfMem, + EGL_err.stackUnderflow, + EGL_err.stackOverflow}: + return EGL_err.unknown + +proc errCheck*() = + let err = getErr() + if err != EGL_err.none: + raise newGL_codeException($err, err) + +macro `?`*(call: expr{nkCall}): expr = + result = call + # Can't yet reference foreign symbols in macros. + #errCheck() + +when defined(doublePrecision): + const + glRealType* = cGLdouble +else: + const + glRealType* = cGLfloat + +proc setUniformV4*[T](loc: GLint, vecs: var openarray[TV4[T]]) = + glUniform4fv(loc, vecs.len.GLsizei, cast[PGLfloat](vecs[0].addr)) + +proc setUniformV4*[T](loc: GLint, vec: TV4[T]) = + var vecs = [vec] + setUniformV4(loc, vecs) diff --git a/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/primitive.nim b/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/primitive.nim new file mode 100644 index 000000000..c67748967 --- /dev/null +++ b/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/primitive.nim @@ -0,0 +1,157 @@ +import + math, + tri_engine/config, + tri_engine/gfx/gl/gl, + tri_engine/gfx/tex, + tri_engine/gfx/color, + tri_engine/math/vec, + tri_engine/math/rect, + tri_engine/math/circle + +import strutils + +type + TVert* = tuple[pos: TV2[TR], texCoord: TV2[TR]] + TVertAttrib* = object + i* : GLuint + size* : GLint + stride* : GLsizei + offset* : PGLvoid + TVertMode* = enum + vmTriStrip = GLtriangleStrip, + vmTriFan = GLtriangleFan + TZ_range* = range[-100_000..100_000] + PPrimitive* = ref object + verts* : seq[TVert] + indices* : seq[GLushort] + arrBufId* : GLuint + elemArrBufId* : GLuint + tex* : TTex + color* : TColor + vertMode* : TVertMode + z* : int + +proc newVert*(pos, texCoord: TV2): TVert = + (pos, texCoord) + +proc newVertQuad*(min, minRight, maxLeft, max: TV2[TR]): seq[TVert] = + @[newVert(min, newV2()), + newVert(minRight, newV2(x=1.0)), + newVert(maxLeft, newV2(y=1.0)), + newVert(max, newV2xy(1.0)) + ] + +proc newVert*(rect: rect.TRect): seq[TVert] = + newVertQuad(rect.min, newV2(rect.max.x, rect.min.y), newV2(rect.min.x, rect.max.y), rect.max) + +proc newVertAttrib(i: GLuint, size: GLint, stride: GLsizei, offset: PGLvoid): TVertAttrib = + TVertAttrib(i: i, size: size, stride: stride, offset: offset) + +proc genBuf*[T](vboTarget, objUsage: GLenum, data: var openarray[T]): GLuint = + result = 0.GLuint + ?glGenBuffers(1, result.addr) + ?glBindBuffer(vboTarget, result) + + let size = (data.len * T.sizeof).GLsizeiptr + ?glBufferData(vboTarget, size, data[0].addr, objUsage) + +proc newPrimitive*(verts: var seq[TVert], + vertMode=vmTriStrip, + tex=whiteTex(), + color=white(), + z: TZ_range=0): PPrimitive = + var indices = newSeq[GLushort](verts.len) + for i in 0 .. <verts.len: + indices[i] = i.GLushort + + new(result) + result.verts = verts + result.indices = indices + + result.arrBufId = genBuf(GLarrayBuffer, GL_STATIC_DRAW, verts) + result.elemArrBufId = genBuf(GLelementArrayBuffer, GL_STATIC_DRAW, indices) + result.tex = tex + result.color = color + result.vertMode = vertMode + result.z = z + +proc bindBufs*(o: PPrimitive) = + ?glBindBuffer(GLarrayBuffer, o.arrBufId) + ?glBindBuffer(GLelementArrayBuffer, o.elemArrBufId) + +proc enableVertAttribArrs*() = + ?glEnableVertexAttribArray(0) + ?glEnableVertexAttribArray(1) + +proc disableVertAttribArrs*() = + ?glDisableVertexAttribArray(1) + ?glDisableVertexAttribArray(0) + +proc setVertAttribPointers*() = + let vertSize {.global.} = TVert.sizeof.GLint + ?glVertexAttribPointer(0, 2, glRealType, false, vertSize, nil) + ?glVertexAttribPointer(1, 2, glRealType, false, vertSize, cast[PGLvoid](TR.sizeof * 2)) + +proc updVerts*(o: PPrimitive, start, `end`: int, f: proc(i: int, vert: var TVert)) = + assert start <= `end` + assert `end` < o.verts.len + for i in start..`end`: + f(i, o.verts[i]) + + ?glBindBuffer(GLarrayBuffer, o.arrBufId) + + let byteLen = `end` - start + 1 * TVert.sizeof + let byteOffset = start * TVert.sizeof + ?glBufferSubData(GLarrayBuffer, + byteOffset.GLintptr, # Offset. Is this right? + byteLen.GLsizeiptr, # Size. + cast[PGLvoid](cast[int](o.verts[0].addr) + byteOffset)) + +proc updAllVerts(o: PPrimitive, f: proc(i: int, vert: var TVert)) = + for i in 0 .. <o.verts.len: + f(i, o.verts[i]) + + ?glBindBuffer(GLarrayBuffer, o.arrBufId) + + # Discard old buffer before creating a new one. + let byteLen = (o.verts.len * TVert.sizeof).GLsizeiptr + ?glBufferData(GLarrayBuffer, byteLen, nil, GLstaticDraw) + ?glBufferData(GLarrayBuffer, byteLen, o.verts[0].addr, GLstaticDraw) + +proc newVertCircle*(circle: TCircle, nSegs: Natural=0): seq[TVert] = + let nSegs = if nSegs == 0: + (circle.r.sqrt() * 400.0).int # TODO: Base this on the window resolution? + else: + max(nSegs, 3) + + let theta: TR = (PI * 2.0) / (nSegs.TR) + let tanFactor = theta.tan() + let radialFactor = theta.cos() + var x = circle.r + var y: TR = 0.0 + + result = newSeq[TVert](nSegs) + #result[0] = newVert(circle.p, newV2xy(0.5)) + for i in 1 .. <nSegs: + let pos = newV2(x + circle.p.x, y + circle.p.y) + let texCoord = pos * newV2xy(1.0 / circle.r) + + result[i] = newVert(pos, texCoord) + + let tx = -y + let ty = x + x += tx * tanFactor + y += ty * tanFactor + + x *= radialFactor + y *= radialFactor + + result.add(result[1]) + +proc newPrimitiveCircle*(circle: TCircle, + nSegs: Natural=0, + tex=whiteTex(), + color=white(), + z: TZ_range=0): PPrimitive = + var verts = newVertCircle(circle, nSegs) + newPrimitive(verts, vmTriFan, tex, color, z) diff --git a/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/shader.nim b/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/shader.nim new file mode 100644 index 000000000..5972aa4fb --- /dev/null +++ b/tests/manyloc/named_argument_bug/tri_engine/gfx/gl/shader.nim @@ -0,0 +1,103 @@ +import + pure/os, + tri_engine/gfx/gl/gl + +type + TShader* = object + id*: GL_handle + TShaderType* {.pure.} = enum + frag = GL_FRAGMENT_SHADER, + vert = GL_VERTEX_SHADER + E_Shader* = object of E_Base + E_UnknownShaderType* = object of E_Shader + +converter pathToShaderType*(s: string): TShaderType = + case s.splitFile().ext: + of ".vs": + return TShaderType.vert + of ".fs": + return TShaderType.frag + else: + raise newException(E_UnknownShaderType, "Can't determine shader type from file extension: " & s) + +proc setSrc*(shader: TShader, src: string) = + var s = src.cstring + ?glShaderSource(shader.id, 1, cast[cstringarray](s.addr), nil) + +proc newShader*(id: GL_handle): TShader = + if id != 0 and not (?glIsShader(id)).bool: + raise newException(E_GL, "Invalid shader ID: " & $id) + + result.id = id + +proc shaderInfoLog*(o: TShader): string = + var log {.global.}: array[0..1024, char] + var logLen: GLsizei + ?glGetShaderInfoLog(o.id, log.len.GLsizei, logLen, cast[PGLchar](log.addr)) + cast[string](log.addr).substr(0, logLen) + +proc compile*(shader: TShader, path="") = + ?glCompileShader(shader.id) + var compileStatus = 0.GLint + ?glGetShaderIv(shader.id, GL_COMPILE_STATUS, compileStatus.addr) + + if compileStatus == 0: + raise newException(E_GL, if path.len == 0: + shaderInfoLog(shader) + else: + path & ":\n" & shaderInfoLog(shader) + ) + +proc newShaderFromSrc*(src: string, `type`: TShaderType): TShader = + result.id = ?glCreateShader(`type`.GLenum) + result.setSrc(src) + result.compile() + +proc newShaderFromFile*(path: string): TShader = + newShaderFromSrc(readFile(path), path) + +type + TProgram* = object + id*: GL_handle + shaders: seq[TShader] + +proc attach*(o: TProgram, shader: TShader) = + ?glAttachShader(o.id, shader.id) + +proc infoLog*(o: TProgram): string = + var log {.global.}: array[0..1024, char] + var logLen: GLsizei + ?glGetProgramInfoLog(o.id, log.len.GLsizei, logLen, cast[PGLchar](log.addr)) + cast[string](log.addr).substr(0, logLen) + +proc link*(o: TProgram) = + ?glLinkProgram(o.id) + var linkStatus = 0.GLint + ?glGetProgramIv(o.id, GL_LINK_STATUS, linkStatus.addr) + if linkStatus == 0: + raise newException(E_GL, o.infoLog()) + +proc validate*(o: TProgram) = + ?glValidateProgram(o.id) + var validateStatus = 0.GLint + ?glGetProgramIv(o.id, GL_VALIDATE_STATUS, validateStatus.addr) + if validateStatus == 0: + raise newException(E_GL, o.infoLog()) + +proc newProgram*(shaders: seq[TShader]): TProgram = + result.id = ?glCreateProgram() + if result.id == 0: + return + + for shader in shaders: + if shader.id == 0: + return + + ?result.attach(shader) + + result.shaders = shaders + result.link() + result.validate() + +proc use*(o: TProgram) = + ?glUseProgram(o.id) diff --git a/tests/manyloc/named_argument_bug/tri_engine/gfx/tex.nim b/tests/manyloc/named_argument_bug/tri_engine/gfx/tex.nim new file mode 100644 index 000000000..e5043ae34 --- /dev/null +++ b/tests/manyloc/named_argument_bug/tri_engine/gfx/tex.nim @@ -0,0 +1,31 @@ +import + tri_engine/gfx/gl/gl + +type + TTex* = object + id*: GLuint + +var gWhiteTex = TTex(id: 0) + +proc setTexParams() = + ?glTexParameteri(GLtexture2D, GLtextureMinFilter, GLlinear) + + #glTexParameteri(GLtexture2D, GLtextureMagFilter, GLlinear) + ?glTexParameteri(GLtexture2D, GLTextureMagFilter, GLnearest) + + ?glTexParameteri(GLtexture2D, GLTextureWrapS, GLClampToEdge) + ?glTexParameteri(GLtexture2D, GLTextureWrapT, GLClampToEdge) + +proc whiteTex*(): TTex = + if gWhiteTex.id.int != 0: + return gWhiteTex + + ?glGenTextures(1, gWhiteTex.id.addr) + ?glBindTexture(GLtexture2D, gWhiteTex.id) + setTexParams() + + var pixel = [255'u8, 255'u8, 255'u8, 255'u8] + ?glTexImage2D(GLtexture2D, 0, GL_RGBA, 1, 1, 0, GL_BGRA, cGLUnsignedByte, pixel[0].addr) + ?glBindTexture(GLtexture2D, 0) + + result = gWhiteTex diff --git a/tests/manyloc/named_argument_bug/tri_engine/math/circle.nim b/tests/manyloc/named_argument_bug/tri_engine/math/circle.nim new file mode 100644 index 000000000..7e7517998 --- /dev/null +++ b/tests/manyloc/named_argument_bug/tri_engine/math/circle.nim @@ -0,0 +1,9 @@ +import + tri_engine/config, + tri_engine/math/vec + +type + TCircle* = tuple[p: TV2[TR], r: TR] + +converter toCircle*(o: TR): TCircle = + (newV2(), o) diff --git a/tests/manyloc/named_argument_bug/tri_engine/math/rect.nim b/tests/manyloc/named_argument_bug/tri_engine/math/rect.nim new file mode 100644 index 000000000..b6fd9ce84 --- /dev/null +++ b/tests/manyloc/named_argument_bug/tri_engine/math/rect.nim @@ -0,0 +1,8 @@ +import + tri_engine/config, + tri_engine/math/vec + +type + TRect* = tuple[min, size: TV2[TR]] + +proc max*(o: TRect): TV2[TR] = o.min + o.size diff --git a/tests/manyloc/named_argument_bug/tri_engine/math/vec.nim b/tests/manyloc/named_argument_bug/tri_engine/math/vec.nim new file mode 100644 index 000000000..a6b7bac63 --- /dev/null +++ b/tests/manyloc/named_argument_bug/tri_engine/math/vec.nim @@ -0,0 +1,55 @@ +import + macros, + tri_engine/config + +type + TV2*[T:TNumber=TR] = array[0..1, T] + TV3*[T:TNumber=TR] = array[0..2, T] + TV4*[T:TNumber=TR] = array[0..3, T] + TVT*[T:TNumber=TR] = TV2|TV3|TV4 + #TV2* = array[0..1, TR] + #TV3* = array[0..2, TR] + #TV4* = array[0..3, TR] + +# TODO: Change to TVT when compiler issue is resolved. +proc `$`*[T](o: TV2[T]): string = + result = "(" + for i in 0 .. <o.len: + result &= $o[0] + if i != o.len - 1: + result &= ", " + + result & ")" + +proc newV2T*[T](x, y: T=0): TV2[T] = + [x, y] + +proc newV2*(x, y: TR=0.0): TV2[TR] = + [x, y] + +proc newV2xy*(xy: TR): TV2[TR] = + [xy, xy] + +proc x*[T](o: TV2[T]): T = + o[0] + +proc y*[T](o: TV2[T]): T = + o[1] + +proc `*`*(lhs: TV2[TR], rhs: TV2[TR]): TV2[TR] = + [(lhs.x * rhs.x).TR, (lhs.y * rhs.y).TR] + +proc `+`*(lhs: TV2[TR], rhs: TV2[TR]): TV2[TR] = + [(lhs.x + rhs.x).TR, (lhs.y + rhs.y).TR] + +#proc dotProduct[T](a: TVT[T], b: TVT[T]): T = +# for i in 0 .. a.len - 1: +# result += a[i] * b[i] + +proc dot[T](a, b: TV2[T]): T = + for i in 0 .. <a.len: + result += a[i] * b[i] + +assert dot(newV2(), newV2()) == 0.0 +assert dot(newV2(2, 3), newV2(6, 7)) == 33.0 +assert dot([2.0, 3.0], [6.0, 7.0]) == 33.0 diff --git a/tests/manyloc/named_argument_bug/tri_engine/tri_engine.nim b/tests/manyloc/named_argument_bug/tri_engine/tri_engine.nim new file mode 100644 index 000000000..ba9989bbb --- /dev/null +++ b/tests/manyloc/named_argument_bug/tri_engine/tri_engine.nim @@ -0,0 +1,106 @@ +import + algorithm, + tri_engine/config, + tri_engine/gfx/gl/gl, + tri_engine/gfx/gl/primitive, + tri_engine/gfx/gl/shader, + tri_engine/gfx/color + +const primitiveVs = """ +#version 330 core + +layout(location = 0) in vec2 pos; +layout(location = 1) in vec2 texCoord; + +out vec2 uv; + +void main() +{ + gl_Position = vec4(pos, 0, 1); + uv = texCoord; +} + +""" +const primitiveFs = """ +#version 330 core + +in vec2 uv; +out vec4 color; +uniform sampler2D tex; +uniform vec4 inColor; + +void main() +{ + color = texture(tex, uv) * inColor; +} + +""" + +var gW, gH: Natural = 0 + +proc w*(): int = + gW + +proc h*(): int = + gH + +type + PRenderer = ref object + primitiveProgram: TProgram + primitives: seq[PPrimitive] + +proc setupGL() = + ?glEnable(GLblend) + ?glBlendFunc(GLsrcAlpha, GLoneMinusSrcAlpha) + ?glClearColor(0.0, 0.0, 0.0, 1.0) + ?glPolygonMode(GLfrontAndBack, GLfill) + +proc newRenderer*(w, h: Positive): PRenderer = + gW = w + gH = h + + new(result) + newSeq(result.primitives, 0) + loadExtensions() + setupGL() + result.primitiveProgram = newProgram(@[ + newShaderFromSrc(primitiveVs, TShaderType.vert), + newShaderFromSrc(primitiveFs, TShaderType.frag)]) + +proc draw(o: PRenderer, p: PPrimitive) = + let loc = proc(x: string): Glint = + result = glGetUniformLocation(o.primitiveProgram.id, x) + if result == -1: + raise newException(E_GL, "Shader error: " & x & " does not correspond to a uniform variable") + + setUniformV4(loc("inColor"), p.color) + ?glActiveTexture(GLtexture0) + ?glBindTexture(GLtexture2D, p.tex.id.GLuint) + ?glUniform1i(loc("tex"), 0) + + p.bindBufs() + setVertAttribPointers() + + ?glDrawElements(p.vertMode.GLenum, p.indices.len.GLsizei, cGLunsignedShort, nil) + +proc draw*(o: PRenderer) = + ?glClear(GLcolorBufferBit) + o.primitiveProgram.use() + + enableVertAttribArrs() + var zSortedPrimitives = o.primitives + zSortedPrimitives.sort(proc(x, y: PPrimitive): int = + if x.z < y.z: + -1 + elif x.z > y.z: + 1 + else: + 0) + + for x in zSortedPrimitives: + o.draw(x) + + disableVertAttribArrs() + +proc addPrimitive*(o: PRenderer, p: PPrimitive) = + o.primitives.add(p) |