Created
December 9, 2011 22:23
-
-
Save FeepingCreature/1453583 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module pyramid; | |
import opengl, glsetup; | |
import sdl, camera; | |
import std.macros.switchover; | |
void main(string[] args) { | |
// resizeWindow (640, 480); | |
auto vertices = [vec3f (-1, -1, -1), vec3f(1, 1, 1)]; | |
void dividePyramid( | |
type-of &vertices pCorners, | |
void delegate(type-of &vertices) callback) { | |
auto a = (*pCorners)[0], b = (*pCorners)[1]; | |
for auto v <- [for tup <- cross (0..3, 0..3, 0..3): vec3i(tup)] { | |
int bsum = (v.x == 1) + (v.y == 1) + (v.z == 1); | |
if bsum < 2 { | |
vec3f x 2 temp = [a * (3 - v) / 3f + b * (v + 0) / 3f, | |
a * (2 - v) / 3f + b * (v + 1) / 3f]; | |
callback &temp; | |
} | |
} | |
} | |
auto ec = new EgoCam!PerspectiveCam (vec3f(0, 0, -3), 0, 0); | |
bool pass; | |
vec3f[auto~] vertexQuadData, colorQuadData; | |
int[auto~] vertexIndexData; | |
void addVertex(vec3f pos, vec3f col) { | |
auto limit = vertexQuadData.length - 64; | |
if (limit < 0) limit = 0; | |
alias eps = 0.00001f; | |
for (int i = vertexQuadData.length - 1; i >= limit; --i) { | |
if (|vertexQuadData[i] - pos| < eps) { vertexIndexData ~= i; return; } | |
} | |
vertexIndexData ~= vertexQuadData.length; | |
vertexQuadData ~= pos; | |
colorQuadData ~= col; | |
} | |
void rootFun(type-of &vertices pVecs) { | |
alias twoVecs = *pVecs; | |
auto vecs = [for | |
tup <- cross(0..2, 0..2, 0..2): | |
vec3f(twoVecs[tup[0]].x, twoVecs[tup[1]].y, twoVecs[tup[2]].z)]; | |
for (int i, int id) <- zip (0..-1, | |
[0, 1, 3, 2, | |
2, 3, 7, 6, | |
6, 7, 5, 4, | |
4, 5, 1, 0, | |
1, 5, 7, 3, | |
2, 6, 4, 0]) | |
{ | |
auto vec = vecs[id]; | |
addVertex (vec, vec + vec3f(1, 0.6, 0.3) * (i / 24f)); | |
} | |
} | |
auto mkFun(int depth) { | |
auto curFun = &rootFun; | |
for 0..depth | |
curFun = new \(type-of &vertices pVecs) { dividePyramid(pVecs, curFun); }; | |
return curFun; | |
} | |
int curDepth = 1; | |
GLuint x 3 lists; | |
void regenList() mode GL { | |
if (lists[0]) DeleteBuffers(3, lists.ptr); | |
GenBuffers(3, lists.ptr); | |
vertexQuadData.free; colorQuadData.free; | |
vertexIndexData.free; | |
writeln "call with $curDepth"; | |
auto fun = mkFun curDepth; | |
writeln "compute"; | |
fun &vertices; | |
writeln "upload $(vertexQuadData.length) vertices, $(vertexIndexData.length) indices. "; | |
for (int i, vec3f[] list) <- zip(0..2, [vertexQuadData[], colorQuadData[]]) using GL_ARRAY_BUFFER_ARB { | |
BindBuffer lists[i]; | |
BufferData ((size-of vec3f) * list.length, list.ptr, STATIC_DRAW); | |
} | |
using ELEMENT_ARRAY_BUFFER { | |
BindBuffer lists[2]; | |
// BufferData (4 * vertexIndexData.length, vertexIndexData.ptr, STATIC_DRAW); | |
BufferData vertexIndexData.(4 * length, ptr, STATIC_DRAW); | |
} | |
} | |
bool active; | |
void toggleActive() prefix SDL_ { | |
if (active) { | |
ShowCursor true; | |
} else { | |
ShowCursor false; | |
// WM_GrabInput(GRAB_ON); | |
WarpMouse(320, 240); | |
} | |
active = !active; | |
} | |
gl-context-callbacks ~= \{ | |
writeln "regenList()"; | |
regenList(); | |
}; | |
auto surf = setup-gl(); | |
{ | |
int res; | |
SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &res); | |
writeln "0 or 1, enable or disable double buffering: $(res)"; | |
prefix SDL_GL_ suffix _SIZE for (int num, string info) <- [ | |
(RED, "framebuffer red component"), | |
(GREEN, "framebuffer green component"), | |
(BLUE, "framebuffer blue component"), | |
(ALPHA, "framebuffer alpha component"), | |
(BUFFER, "framebuffer"), | |
(DEPTH, "depth buffer"), | |
(STENCIL, "stencil buffer"), | |
(ACCUM_RED, "accumulation buffer red component"), | |
(ACCUM_GREEN, "accumulation buffer green component"), | |
(ACCUM_BLUE, "accumulation buffer blue component"), | |
(ACCUM_ALPHA, "accumulation buffer alpha component")] | |
{ | |
SDL_GL_GetAttribute(num, &res); | |
writeln "Size of the $info, in bits: $res"; | |
} | |
} | |
while true { | |
mode GL { | |
ClearColor (0 x 3, 0); | |
ClearDepth 1; | |
Clear (COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT); | |
ec.aspect = surf.w * 1f / surf.h; | |
ec.gl-setup(); | |
// Rotatef (t++, 0, 1, 0); | |
EnableClientState VERTEX_ARRAY; | |
EnableClientState COLOR_ARRAY; | |
ARRAY_BUFFER.BindBuffer lists[0]; | |
VertexPointer(3, FLOAT, size-of vec3f, null); | |
ARRAY_BUFFER.BindBuffer lists[1]; | |
ColorPointer(3, FLOAT, size-of vec3f, null); | |
ELEMENT_ARRAY_BUFFER.BindBuffer lists[2]; | |
// DrawArrays (QUADS, 0, vertexQuadData.length); | |
DrawElements (QUADS, vertexIndexData.length, UNSIGNED_INT, null); | |
} | |
if surf.update() return; | |
if (active) { | |
auto idelta = mousepos - vec2i(320, 240); | |
auto delta = vec2f((0.001 * idelta).(x, y)); | |
using (ec, delta) { turn-left-x; turn-up-y; } // *MWAHAHAHAHAAAAAHAHA* | |
if idelta.x || idelta.y | |
SDL_WarpMouse(320, 240); | |
} | |
if (mouseClicked) toggleActive; | |
alias movestep = 0.034; | |
prefix SDLK_ { | |
switch int i over keyPressed[i] { | |
case w: ec.pos += ec.dir * movestep; | |
case s: ec.pos -= ec.dir * movestep; | |
case a: ec.pos += ec.left * movestep; | |
case d: ec.pos -= ec.left * movestep; | |
} | |
switch int i over keyPushed[i] { | |
case PLUS or KP_PLUS: curDepth ++; regenList; | |
case MINUS or KP_MINUS: if curDepth curDepth --; regenList; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment