///
/// file : cubeworld.tks
/// author : Bastian Spiegel <fli@tkscript.de>
/// descr. :
/// license: provided "AS IS". no copyright, no liability. use as you want.
/// created: 190902
/// updated: 06Feb2003 <fli> added render2texture (DrawRasters())
///
///
module Main;
use "tksdl";
#define HST_LEN 88
#define R2T_SU 256.0
#define R2T_SV 256.0
#define GRIDSX 6
#define GRIDSY 6
#define GRIDSZ 6
int hst_idx=0;
int rubber_mode=1;
int tex_mode=1;
int draw_quads=1;
Camera cam;
Texture tex_fb;
Texture tex_r2t[HST_LEN];
float oval=rnd(2PI);
float rfld=rnd(2.0);
float rquadx=rnd(2PI);
float rquady=rnd(2PI);
float rquadz=rnd(2PI);
float scrcnt=0.0;
DisplayList dl_cube;
int need_dl=1;
int waitvblank=0;
int enable_rotation=1;
function DrawRasters() compile {
int y=0;
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
zglColorARGB(#ffffffff);
int sy=Viewport.height;
float sx=Viewport.width;
float ival=oval;
float iadd=2PI/sy;
int idx=(hst_idx-1);
if(idx<0) idx+=HST_LEN;
float v=1.0;
float vstep=1.0/sy;
float vn;
loop(sy)
{
vn=v-vstep;
float c=sin(ival)*0.5+0.5;
idx=-1-c*(HST_LEN-1);
idx=(hst_idx+idx);
if(idx<0) idx+=HST_LEN;
_=tex_r2t[idx].bind();
glBegin(GL_QUADS);
glTexCoord2f(0.0, v);
glVertex2f(0, y);
glTexCoord2f(1.0, v);
glVertex2f(sx, y);
glTexCoord2f(1.0, vn);
glVertex2f(sx, y+1);
glTexCoord2f(0.0, vn);
glVertex2f(0, y+1);
glEnd();
ival+=iadd;
y++;
v=vn;
}
}
function DrawCube(Pointer _ca) {
IntArray ca<=_ca; // get color array
compile {
glBegin(GL_QUADS); // Draw A Quad
zglColorARGB(ca[0]);
glVertex3f(1.0, 1.0, -1.0); // Top Right Of The Quad (Top)
zglColorARGB(ca[1]);
glVertex3f(-1.0, 1.0, -1.0); // Top Left Of The Quad (Top)
zglColorARGB(ca[2]);
glVertex3f(-1.0, 1.0, 1.0); // Bottom Left Of The Quad (Top)
zglColorARGB(ca[3]);
glVertex3f(1.0, 1.0, 1.0); // Bottom Right Of The Quad (Top)
zglColorARGB(ca[4]);
glVertex3f(1.0, -1.0, 1.0); // Top Right Of The Quad (Bottom)
zglColorARGB(ca[5]);
glVertex3f(-1.0, -1.0, 1.0); // Top Left Of The Quad (Bottom)
zglColorARGB(ca[6]);
glVertex3f(-1.0, -1.0, -1.0); // Bottom Left Of The Quad (Bottom)
zglColorARGB(ca[7]);
glVertex3f(1.0, -1.0, -1.0); // Bottom Right Of The Quad (Bottom)
zglColorARGB(ca[3]);
glVertex3f(1.0, 1.0, 1.0); // Top Right Of The Quad (Front)
zglColorARGB(ca[2]);
glVertex3f(-1.0, 1.0, 1.0); // Top Left Of The Quad (Front)
zglColorARGB(ca[5]);
glVertex3f(-1.0, -1.0, 1.0); // Bottom Left Of The Quad (Front)
zglColorARGB(ca[4]);
glVertex3f(1.0, -1.0, 1.0); // Bottom Right Of The Quad (Front)
zglColorARGB(ca[7]);
glVertex3f(1.0, -1.0, -1.0); // Top Right Of The Quad (Back)
zglColorARGB(ca[6]);
glVertex3f(-1.0,-1.0,-1.0); // Top Left Of The Quad (Back)
zglColorARGB(ca[1]);
glVertex3f(-1.0, 1.0,-1.0); // Bottom Left Of The Quad (Back)
zglColorARGB(ca[0]);
glVertex3f(1.0, 1.0, -1.0); // Bottom Right Of The Quad (Back)
zglColorARGB(ca[2]);
glVertex3f(-1.0, 1.0, 1.0); // Top Right Of The Quad (Left)
zglColorARGB(ca[1]);
glVertex3f(-1.0, 1.0, -1.0); // Top Left Of The Quad (Left)
zglColorARGB(ca[6]);
glVertex3f(-1.0, -1.0, -1.0); // Bottom Left Of The Quad (Left)
zglColorARGB(ca[5]);
glVertex3f(-1.0, -1.0, 1.0); // Bottom Right Of The Quad (Left)
zglColorARGB(ca[0]);
glVertex3f(1.0, 1.0, -1.0); // Top Right Of The Quad (Right)
zglColorARGB(ca[3]);
glVertex3f(1.0, 1.0, 1.0); // Top Left Of The Quad (Right)
zglColorARGB(ca[4]);
glVertex3f(1.0, -1.0, 1.0); // Bottom Left Of The Quad (Right)
zglColorARGB(ca[7]);
glVertex3f(1.0, -1.0, -1.0); // Bottom Right Of The Quad (Right)
glEnd(); // Done Drawing The Quad
}
}
float DrawTexturedCube_u;
float DrawTexturedCube_v;
float DrawTexturedCube_ustep;
float DrawTexturedCube_vstep;
function DrawTexturedCube(Pointer _ca) {
IntArray ca<=_ca; // get color array
compile {
glDisable(GL_TEXTURE_2D);
glBegin(GL_QUADS); // Draw A Quad
zglColorARGB(ca[0]);
glTexCoord2f(DrawTexturedCube_u+DrawTexturedCube_ustep, DrawTexturedCube_v);
glVertex3f(1.0, 1.0, -1.0); // Top Right Of The Quad (Top)
zglColorARGB(ca[1]);
glTexCoord2f(DrawTexturedCube_u, DrawTexturedCube_v);
glVertex3f(-1.0, 1.0, -1.0); // Top Left Of The Quad (Top)
zglColorARGB(ca[2]);
glTexCoord2f(DrawTexturedCube_u, DrawTexturedCube_v+DrawTexturedCube_vstep);
glVertex3f(-1.0, 1.0, 1.0); // Bottom Left Of The Quad (Top)
zglColorARGB(ca[3]);
glTexCoord2f(DrawTexturedCube_u+DrawTexturedCube_ustep, DrawTexturedCube_v+DrawTexturedCube_vstep);
glVertex3f(1.0, 1.0, 1.0); // Bottom Right Of The Quad (Top)
glEnd(); // Done Drawing The Quad
glDisable(GL_TEXTURE_2D);
glBegin(GL_QUADS); // Draw A Quad
zglColorARGB(ca[4]);
glTexCoord2f(DrawTexturedCube_u+DrawTexturedCube_ustep, DrawTexturedCube_v);
glVertex3f(1.0, -1.0, 1.0); // Top Right Of The Quad (Bottom)
zglColorARGB(ca[5]);
glTexCoord2f(DrawTexturedCube_u, DrawTexturedCube_v+DrawTexturedCube_vstep);
glVertex3f(-1.0, -1.0, 1.0); // Top Left Of The Quad (Bottom)
zglColorARGB(ca[6]);
glTexCoord2f(DrawTexturedCube_u, DrawTexturedCube_v);
glVertex3f(-1.0, -1.0, -1.0); // Bottom Left Of The Quad (Bottom)
zglColorARGB(ca[7]);
glTexCoord2f(DrawTexturedCube_u+DrawTexturedCube_ustep, DrawTexturedCube_v);
glVertex3f(1.0, -1.0, -1.0); // Bottom Right Of The Quad (Bottom)
glEnd(); // Done Drawing The Quad
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS); // Draw A Quad
zglColorARGB(ca[3]);
glTexCoord2f(DrawTexturedCube_u+DrawTexturedCube_ustep, DrawTexturedCube_v+DrawTexturedCube_vstep);
glVertex3f(1.0, 1.0, 1.0); // Top Right Of The Quad (Front)
zglColorARGB(ca[2]);
glTexCoord2f(DrawTexturedCube_u, DrawTexturedCube_v+DrawTexturedCube_vstep);
glVertex3f(-1.0, 1.0, 1.0); // Top Left Of The Quad (Front)
zglColorARGB(ca[5]);
glTexCoord2f(DrawTexturedCube_u, DrawTexturedCube_v);
glVertex3f(-1.0, -1.0, 1.0); // Bottom Left Of The Quad (Front)
zglColorARGB(ca[4]);
glTexCoord2f(DrawTexturedCube_u+DrawTexturedCube_ustep, DrawTexturedCube_v);
glVertex3f(1.0, -1.0, 1.0); // Bottom Right Of The Quad (Front)
glEnd(); // Done Drawing The Quad
glEnable(GL_TEXTURE_2D);
glBegin(GL_QUADS); // Draw A Quad
zglColorARGB(ca[7]);
glTexCoord2f(DrawTexturedCube_u+DrawTexturedCube_ustep, DrawTexturedCube_v);
glVertex3f(1.0, -1.0, -1.0); // Top Right Of The Quad (Back)
zglColorARGB(ca[6]);
glTexCoord2f(DrawTexturedCube_u, DrawTexturedCube_v);
glVertex3f(-1.0,-1.0,-1.0); // Top Left Of The Quad (Back)
zglColorARGB(ca[1]);
glTexCoord2f(DrawTexturedCube_u, DrawTexturedCube_v+DrawTexturedCube_vstep);
glVertex3f(-1.0, 1.0,-1.0); // Bottom Left Of The Quad (Back)
zglColorARGB(ca[0]);
glTexCoord2f(DrawTexturedCube_u+DrawTexturedCube_ustep, DrawTexturedCube_v+DrawTexturedCube_vstep);
glVertex3f(1.0, 1.0, -1.0); // Bottom Right Of The Quad (Back)
glEnd(); // Done Drawing The Quad
glDisable(GL_TEXTURE_2D);
glBegin(GL_QUADS); // Draw A Quad
zglColorARGB(ca[2]);
glTexCoord2f(DrawTexturedCube_u+DrawTexturedCube_ustep, DrawTexturedCube_v+DrawTexturedCube_vstep);
glVertex3f(-1.0, 1.0, 1.0); // Top Right Of The Quad (Left)
zglColorARGB(ca[1]);
glTexCoord2f(DrawTexturedCube_u+DrawTexturedCube_ustep, DrawTexturedCube_v);
glVertex3f(-1.0, 1.0, -1.0); // Top Left Of The Quad (Left)
zglColorARGB(ca[6]);
glTexCoord2f(DrawTexturedCube_u, DrawTexturedCube_v);
glVertex3f(-1.0, -1.0, -1.0); // Bottom Left Of The Quad (Left)
zglColorARGB(ca[5]);
glTexCoord2f(DrawTexturedCube_u, DrawTexturedCube_v+DrawTexturedCube_vstep);
glVertex3f(-1.0, -1.0, 1.0); // Bottom Right Of The Quad (Left)
glEnd(); // Done Drawing The Quad
glDisable(GL_TEXTURE_2D);
glBegin(GL_QUADS); // Draw A Quad
zglColorARGB(ca[0]);
glTexCoord2f(DrawTexturedCube_u+DrawTexturedCube_ustep, DrawTexturedCube_v);
glVertex3f(1.0, 1.0, -1.0); // Top Right Of The Quad (Right)
zglColorARGB(ca[3]);
glTexCoord2f(DrawTexturedCube_u+DrawTexturedCube_ustep, DrawTexturedCube_v+DrawTexturedCube_vstep);
glVertex3f(1.0, 1.0, 1.0); // Top Left Of The Quad (Right)
zglColorARGB(ca[4]);
glTexCoord2f(DrawTexturedCube_u, DrawTexturedCube_v+DrawTexturedCube_vstep);
glVertex3f(1.0, -1.0, 1.0); // Bottom Left Of The Quad (Right)
zglColorARGB(ca[7]);
glTexCoord2f(DrawTexturedCube_u, DrawTexturedCube_v);
glVertex3f(1.0, -1.0, -1.0); // Bottom Right Of The Quad (Right)
glEnd(); // Done Drawing The Quad
}
}
// ---- define cube colors ----
IntArray cube_colors<=[
#ffffffff, // ++-0
#ff00ff55, // -+-1
#ff000000, // -++2
#ffffff00, // +++3
#ffffffff, // +-+4
#ffffffff, // --+5
#ff770000, // ---6
#ff00afaf // +--7
];
// ---- define modulation cube colors ----
IntArray cube_colors2<=[
#ffffffff, // -+-1
#fff79ea8, // ++-0
#ffffffff, // +-+4
#ffff0000, // +--7
#ffff0000, // +++3
#ff770000, // ---6
#ffffffff, // --+5
#ffffff00 // -++2
];
int c_cube_colors[8]; c_cube_colors.numElements=c_cube_colors.maxElements;
function onDraw() {
zglInitPerspective(1.0, 70.0, 0.001, 10.0);
compile {
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_FLAT);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
}
glScalef(R2T_SU/Viewport.width, R2T_SV/Viewport.height, 1.0);
// ---- update palette ----
int i=0;
float bf=sin(oval*6)*0.35+0.35;
//Integer io;
loop(c_cube_colors.numElements)
{
int c32a=cube_colors[i];
int c32b=cube_colors2[i];
//int c32=mathC32Blend(c32a, c32, bf);
int c32=mathC32Multiply(c32a, c32, bf);
//io.value=c32; trace "c32a*c32b="+io.printf("#%08x");
c_cube_colors[i]=c32;
i++;
}
need_dl=1;
if(need_dl)
{
// ---- create cube display list ----
need_dl=0;
dl_cube.free();
dl_cube.alloc();
dl_cube.begin();
if(tex_mode)
{
DrawTexturedCube_u=0.0;
DrawTexturedCube_ustep=1.0/GRIDSX;
DrawTexturedCube_v=0.0;
DrawTexturedCube_vstep=1.0/GRIDSY;
DrawTexturedCube(c_cube_colors);
}
else
{
DrawCube(c_cube_colors);
}
dl_cube.end();
}
int id=dl_cube.id;
cam.loadTransform();
if(tex_mode)
tex_fb.bind();
compile {
glRotatef(rquadx,1.0,0.0,0.0);
glRotatef(rquady,0.0,1.0,0.0);
glRotatef(rquadz,0.0,0.0,1.0);
float fld=(0.5+sin(rfld)*0.5);
fld=2.0+1.5*fld;
glScalef(1/(GRIDSX*2.0), 1/(GRIDSY*2.0), 1.0/(GRIDSZ*2.0));
glTranslatef(-fld*(GRIDSX/2), -fld*(GRIDSY/2), -fld*(GRIDSZ/2));
float tstep=1.0/GRIDSX;
float sq3=1.0/sqrt(3.0);
if(tex_mode)
{
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
float tz=0.0;
loop(GRIDSZ)
{ // ---- loopz ----
float ty=0.0;
loop(GRIDSY)
{ // ---- loopy ----
float tx=0.0;
loop(GRIDSX)
{ // ---- loopx ----
glCallList(id);
glTranslatef(fld, 0.0, 0.0);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(tx,ty,tz);
glMatrixMode(GL_MODELVIEW);
tx+=tstep;
}
glTranslatef(-fld*GRIDSX, fld, 0.0);
ty+=tstep;
}
glTranslatef(0.0, -fld*GRIDSY, fld);
tz+=tstep;
}
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
}
else
{
loop(GRIDSZ)
{ // ---- loopz ----
loop(GRIDSY)
{ // ---- loopy ----
loop(GRIDSX)
{ // ---- loopx ----
glCallList(id);
glTranslatef(fld, 0.0, 0.0);
}
glTranslatef(-fld*GRIDSX, fld, 0.0);
}
glTranslatef(0.0, -fld*GRIDSY, fld);
}
}
}
glDisable(GL_CULL_FACE);
Debug.Draw();
if(rubber_mode)
{
glEnable(GL_TEXTURE_2D);
_=tex_r2t[hst_idx].bind(); // a workaround to evaluate an expr as a statement..
// ---- grab texture ----
glLoadIdentity();
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (Viewport.width-R2T_SU)/2,(Viewport.height-R2T_SV)/2,R2T_SU,R2T_SV, 0);
hst_idx=(hst_idx+1);
if(hst_idx>=HST_LEN) hst_idx-=HST_LEN;
zglInit2D(Viewport.width, Viewport.height);
glTranslatef(-Viewport.width/4, -Viewport.height/4, 0);
glScalef(1.45, 1.45,1);
// ---- draw raster lines ----
DrawRasters();
}
if(tex_mode)
{
glEnable(GL_TEXTURE_2D);
tex_fb.bind();
// ---- grab texture ----
glLoadIdentity();
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (Viewport.width-R2T_SU)/2,(Viewport.height-R2T_SV)/2,R2T_SU,R2T_SV, 0);
}
if(waitvblank)Viewport.waitVBlank();
// ---- increase counters ----
float dt=FPS.precision;
if enable_rotation rquadx+=dt*1.7321894395*(sin(oval)*0.5+0.5);
if enable_rotation rquady+=dt*5.92321894395*(sin(oval)*0.15+0.85);
if enable_rotation rquadz+=dt*2.64321894395;//*(cos(oval)*0.15+0.85);
if(rquadx>=360.0) rquadx-=360.0;
if(rquady>=360.0) rquady-=360.0;
if(rquadz>=360.0) rquadz-=360.0;
if enable_rotation rfld+=dt*0.10658227115*(sin(oval*2)*0.45+0.45)+0.005123456;
scrcnt+=dt*0.05;
wrap scrcnt 0 3;
if enable_rotation oval+=2.64321894395/384; //0.041494345*dt;
if(oval>=2PI)oval-=2PI;
}
function onReopen() {
need_dl=1;
Debug.Init();
if(1/*rubber_mode*/)
{
// ---- prepare texture to render to ----
// ---- the texture data is only allocated for the upload() call which
// ---- allocates a new texture with the given size in gfx memory
// ---- the (system memory) texture data can safely be deleted after
// ---- texture nameid generation (upload()).
int i=0;
int flags=TEX_MINFILTERLINEAR|TEX_MAGFILTERLINEAR;//|TEX_MODULATE;
// ---- feedback texture ----
tex_fb.free();
tex_fb.setFlags(TEX_MINFILTERLINEAR|TEX_MAGFILTERLINEAR|TEX_MODULATE);
tex_fb.upload();
_=tex_r2t[0].free();
_=tex_r2t[0].setFlags(flags);
_=tex_r2t[0].upload();
loop(HST_LEN-1)
{
i++;
_=tex_r2t[i].free();
_=tex_r2t[i].setFlags(flags);
_=tex_r2t[i].upload();
}
}
}
function onMouse(int _dx, int _dy, int _cbs, int _nbs) {
//cam.onMouse(_dx*0.01, _dy*0.01, _cbs, _nbs);
}
function onKeyboard(Key _k) {
if(_k.pressed) switch(_k.pressed) {
case 'r': rubber_mode=1-rubber_mode; trace "rubber_mode set to "+rubber_mode; break;
case 't': tex_mode=1-tex_mode; trace "tex_mode set to "+tex_mode; break;
case ' ': draw_quads=1-draw_quads; Debug.Init(); break;
case VKEY_LCTRL: enable_rotation=0; enable_rotation=1; break;
case 'v': waitvblank=1-waitvblank; trace "vsync set to "+waitvblank; Debug.Init(); break;
default: Debug.OnKeyboard(_k); break;
}
}
function main() {
Viewport.openWindow(512, 384);
FPS.tickInterval=1000.0/20;
FPS.tickBuffer=0;
Viewport.setScreenResolution(800,600,32);
cam.init();
onReopen();
cam.lookatz=-3.63;
cam.xrotclamp=false;
trace "-------- cubeworld --------";
trace " g : (un-grab) mouse";
trace " d : toggle debug overlay";
trace "ctrl-d : toggle console debug output";
trace " f : toggle fullscreen mode";
trace " v : toggle vsync";
trace " lctrl : stop rotation";
trace " r : toggle rubber_mode";
trace "\n\n";
use callbacks;
SDL.eventLoop();
}