Skip to content

Instantly share code, notes, and snippets.

@FeepingCreature
Created December 9, 2011 22:23
Show Gist options
  • Save FeepingCreature/1453583 to your computer and use it in GitHub Desktop.
Save FeepingCreature/1453583 to your computer and use it in GitHub Desktop.
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