## 3d animated tunnel in pure FB

angros47
Posts: 1554
Joined: Jun 21, 2005 19:04

### 3d animated tunnel in pure FB

Textured tunnels were widely used in demoscenes in '90s, to show that even on a simple VGA 3d effects were possible. Later, when even cheapest computers had a 3d accelerator, tunnels lose popularity in demo competitions (everyone could build one with a 3d cylinder, so it become trivial).

But doing a tunnel in old-school way is still funny:

Code: Select all

`screenres 800,600,24dim shared as unsigned integer LookUpTable (800,600,2)Dim texture As unsigned integer Ptr = ImageCreate( 247, 247,24 )BLoad "IvyTexture.bmp", texturedim as integer x,yfor x=0 to 800   for y=0 to 600      if y=300 then         if x<400 then LookUpTable(x,y,1)=0 else LookUpTable(x,y,1)=1024      else         LookUpTable(x,y,1)=1024*(.5+atn((x-400)/(y-300))/3.1415926)         if y<300 then LookUpTable(x,y,1)+=1024      end if      LookUpTable(x,y,2)= 8388608/((x-400)^2+(y-300)^2)   nextnextdim as unsigned integer t=0dim as unsigned integer u,vtexture +=8 ' Skip header datado   dim as unsigned integer ptr target=screenptr   screenlock   for y=1 to 600      for x=1 to 800         u=(LookUpTable(x,y,1) + t) mod 247         v=(LookUpTable(x,y,2) + t) mod 247         *target=*(texture +u*248+v)     'point(u , v , texture)         target+=1      next   next   screenunlock   sleep 1   t+=1loop until inkey<>""end`

you need this texture:
http://www.math.ucsd.edu/~sbuss/MathCG/OpenGLsoft/FourTextures/IvyTexture.bmp

Note: the above code works in DOS, too (you might have to trim the file name of the texture, if LFN aren't supported)

It's just a port of this tutorial:

http://benryves.com/tutorials/tunnel/1

It's not the first example of that in FreeBasic (relsoft made something similar years ago), but this one is made in pure FB, with no external libraries, and it's about 35 lines of code!
Tyr_Anassazi
Posts: 26
Joined: Jul 01, 2013 15:01
Location: Russia, Novosibirsk
Contact:

### Re: 3d animated tunnel in pure FB

Hi, angros47.
Cool effect, and it is made by means of 2d. Thanks.
It is a pseudo 3d, but looks like real 3d.
Pritchard
Posts: 5494
Joined: Sep 12, 2005 20:06
Location: Ohio, USA

### Re: 3d animated tunnel in pure FB

This is AWESOME!

And so simple. I understand very basic 2D/3D math, but it never hit me how to get "all" of the pixels on the screen using polar coordinates. I see now, thanks to the simplicity of this demo, that polar values for each x/y coordinate can simply be calculated instead.

That makes so much more sense to me than the other things I tried. Sheesh. Now, I actually feel dumb for having never thought of it :)

Great job!
relsoft
Posts: 1767
Joined: May 27, 2005 10:34
Location: Philippines
Contact:

### Re: 3d animated tunnel in pure FB

Yo angros47! Nice effect!

Was it this?

Code: Select all

`'' Twisted Tunnelconst BUFF_XMAX = 400 const BUFF_YMAX = 350 const XMID = BUFF_XMAX \ 2 const YMID = BUFF_YMAX \ 2 const PI = 3.141593                     'PI for rotation const TWOPI = (2 * PI) const BUFF_SIZE = BUFF_XMAX * BUFF_YMAXconst MAXPOINTS = 32 const TUNNEL_TEXT_XMAX = 256 const TUNNEL_TEXT_YMAX = 256 declare sub draw_tunnel( Texture() as integer,_                                               byval addx as integer, byval addy as integer) declare sub tunnel_init_texture() declare function dist (byval x as single,byval  y as single,_                    xc() as single, yc() as single,_                   byref nearest_dist as single   ) as single dim texture as unsigned integer Ptr = ImageCreate(  BUFF_XMAX,  BUFF_YMAX, 32 )    dim shared tunnel_texture( 255, 255) as integer dim shared distbuffer( 255, 255) as single dim shared xcoords(MAXPOINTS) as single dim shared ycoords(MAXPOINTS) as single     dim shared sqrt(-(XMID^2 + YMID^2)*2 to (XMID^2 + YMID^2)*2) as singledim shared atan(-YMID*2 to YMID*2, -XMID*2 to XMID*2) as singlerandomize timer dim as integer x,y for x = -XMID*2 to XMID*2   for y = -YMID*2 to YMID*2       atan(y,x) = atan2(y,x)   next ynext xfor x = -(XMID^2 + YMID^2)*2 to (XMID^2 + YMID^2)*2   sqrt(x) = sqr(x)next x    dim fold_off as singledim fold_num as singledim fold_scale as singlefold_off = 0.02fold_scale = 0.05fold_num = 16tunnel_init_texture() dim shared demotime as integerdim shared t as singlescreenres BUFF_XMAX,BUFF_YMAX,32do     t = timer     demotime = t * 500        screenlock    draw_tunnel( tunnel_texture(), (BUFF_XMAX shr 1)* sin(t * .5),_                (t *.8)* (BUFF_YMAX shr 1) )                    fold_off = fold_off +  sin(demotime/500) * 0.25                           fold_scale =   0.5 + sin(demotime/500) * 0.20                       screenunlock    sleep 1    screensyncloop until Inkey\$ <>"" end sub draw_tunnel( tunnel_texture() as integer,_                                         byval addx as integer, byval addy as integer)        dim as integer x, y, tx, ty           static as integer cx = XMID, cy = YMID     dim xdist as single     dim as integer cxmx, cymy, diamxscale     static frame as short     static  as single fold_off = 0.02     static  as single squig_off = 0.02     static  as single fold_scale = 0.07' * sin(timer / 512.0)     static  as single fold_num = 5     static  as single rad_factor = 0     dim as integer diameter     static  as integer old_scale_sign = 0    frame +=1     diameter = 128     diamxscale = 64 * diameter     cx = (XMID)+ sin(addx/80)*50     cy = (YMID)+ sin(addy/90)*50     dim temp as short     temp = 512/PI     dim angle as single     fold_off += 0.2        fold_scale = 0.5 * sin(frame / 40)        dim as integer light     dim as single inv_180 = 1/180    dim as integer adder = BUFF_XMAX         if sgn(fold_scale)<>0 then     if sgn(fold_scale)<> old_scale_sign then         fold_num = (fold_num+1) mod 6        old_scale_sign = sgn(fold_scale)    end if    end if   dim as unsigned integer ptr p = screenptr   for y = 0 to BUFF_YMAX - 1         cymy = cy - y       for x = 0 to BUFF_XMAX - 1             cxmx = cx -x                                                              xdist = sqrt((cxmx*cxmx) + (cymy*cymy))             angle = atan(cymy,cxmx) + (((sin((fold_off) +  (fold_num-3) * xdist*inv_180)) * fold_scale)+1)                         tx = int(angle * temp) + addx            xdist = xdist * ((sin(fold_off + fold_num * angle) * fold_scale)+1)                        light = xdist * 5             if light > 255 then light = 255             light = 255 - light             ty =  (diamxscale / xdist) + addy                                    tx = (tx) and 255             ty = (ty) and 255                              *p  = tunnel_texture(tx, ty) or (light shl 16 or light shl 8 or light)          p += 1      next x            next y end sub function dist ( byval x as single,byval  y as single,_                 xc() as single, yc() as single,_             byref nearest_dist as single   ) as single     dim mindist as single     dim max as integer     dim d as single     dim dx as single, dy as single     dim diff as single     dim i as integer     mindist = 1D+32     max = ubound(xc)     for i = 0 to max         dx = abs(xc(i) - x)         dy = abs(yc(i) - y)         if dx > TUNNEL_TEXT_XMAX/2.0 then dx = TUNNEL_TEXT_XMAX-dx        if dy > TUNNEL_TEXT_YMAX/2.0 then dy = TUNNEL_TEXT_YMAX-dy        d = sqr( dx*dx + dy*dy )         if d < mindist then            nearest_dist = mindist          mindist = d       end if     next i     dist = mindist end function sub tunnel_init_Texture()    dim i as integer    dim frame as integer     for i = 0 to MAXPOINTS         xcoords(i) = rnd * (TUNNEL_TEXT_XMAX + 1)         ycoords(i) = rnd * (TUNNEL_TEXT_YMAX + 1)     next i     frame = 0    dim mindist as single    dim maxdist as single           mindist = 1D+32           maxdist = 0         dim tx as single         dim ty as single         dim x as integer         dim y as integer         dim distance as single         dim distance2 as single         dim nearest_dist as single           for y = 0 to TUNNEL_TEXT_YMAX - 1           for x = 0 to TUNNEL_TEXT_XMAX  - 1               tx = x               ty = y               distance = dist(tx, ty, xcoords(), ycoords(), nearest_dist)               distbuffer(x, y) = distance               if distance < mindist then mindist = distance               if distance > maxdist then maxdist = distance           next x           next y         dim c as single         dim as ubyte r,g, b           for y = 0 to TUNNEL_TEXT_YMAX - 1           for x = 0 to TUNNEL_TEXT_XMAX - 1               c = (distbuffer(x, y) - mindist) / ((maxdist - mindist))               r = 255 - (c * 255)               g = (c * 255)               b = r               tunnel_texture(x , y) = r shl 24 or g shl 16 or b shl 8 or 255          next x           next y end sub`
angros47
Posts: 1554
Joined: Jun 21, 2005 19:04

### Re: 3d animated tunnel in pure FB http://www.freebasic.net/forum/viewtopic.php?t=3647

(I haven't tested, because I haven't tinyptc installed)

Anyway, your effect is nice, too.
Posts: 47
Joined: Apr 26, 2017 8:57
Contact:

### Re: 3d animated tunnel in pure FB

Hello, just as curiosity, this a translated code from Relsoft of his tunnel effect to tinyc. 9kb compiled code and almost no wasting processor. Save the file as "tunnel.c" and compile with "tcc tunnel.c". All the merit for Relsoft.
If it is not allowed to posted c source code, you can delete the post.

Code: Select all

`#include <windows.h>#include <math.h>#define cdXPos          CW_USEDEFAULT#define cdYPos          CW_USEDEFAULT#define cdXSize         320 //cdYSize*1.6#define cdYSize         200#define cdColFondo      0#define MAIN_ICON       100    //  IDI_APPLICATION#define cdVCursor       IDC_ARROW#define cdVBarTipo      0#define cdVBtnTipo      WS_OVERLAPPEDWINDOW#define cdIdTimer       1#define DIB_RGB_COLORS  0#define cdimTeja        128#define cdimTile        (cdimTeja*2)#define deg2rad         0.01745329251994   // pi/180#define cdPI            3.1415926535897932384626433832795#define cd2PI           6.283185307179586476925286766559#define maxpoints       32// Prototipos de funcionesLRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;// Variables globalesint               *pMainDIB    = NULL;int                vdxClient, vdyClient;BITMAPINFOHEADER   bi = {sizeof(BITMAPINFOHEADER),cdXSize,-cdYSize,1,32,0,0,0,0,0,0};int                Buffer[cdXSize*cdYSize];int                Tangle[cdXSize][cdYSize], Tdepth[cdXSize][cdYSize];int                Texture, Distbuffer;double             xcoords[maxpoints], ycoords[maxpoints];double             tmp = 0;void DrawTunnel (int addx, int addy) {  int x, y, tx, ty, k = 0;  for (y = 0; y < cdYSize; y++) {    for (x = 0; x < cdXSize; x++, k++) {      tx = (Tangle[x][y] + addx) & 255;      ty = (Tdepth[x][y] + addy) & 255;      *(pMainDIB + k) = Texture[tx][ty];    }    }  }  double dist (double x, double y, double xc[], double yc[]) {  double mindist = 1E+16, a, b, d;  int i;  for (i = 0; i < maxpoints; i++) {    a = (xc[i] - x) * (xc[i] - x) ;    b = (yc[i] - y) * (yc[i] - y);    d = sqrt(a + b);    if (d < mindist) mindist = d;  }  return(mindist);}  void doPrecalc (void) {  int x, y, i, r, g, b, cx, cy, diameter = 64;  double mindist, maxdist, distance, c, tx, ty;  for (i = 0; i < maxpoints; i++) {    xcoords[i] = rand() % cdXSize;    ycoords[i] = rand() % cdYSize;  }  mindist = 1E+16;  maxdist = 0;  for (y = 0; y < 256; y++) {    for (x = 0; x < 256; x++) {      tx = abs(x-128); ty = abs(y - 128);      distance = dist (tx, ty, xcoords, ycoords) ;      Distbuffer [x][y] = distance;      if (distance < mindist) mindist = distance;      if (distance > maxdist) maxdist = distance;    }    }    for (y = 0; y < 256; y++) {    for (x = 0; x < 256; x++) {      c =(Distbuffer [x][y] - mindist) / (maxdist - mindist);      r = (int)(c * 55.);      g = (int)(c * 155.);      b = (int)(c * 255.);      Texture[x][y] = (r << 16) | (g << 8) | b;    }    }  cx = cdXSize/2; cy = cdYSize/2;  for (x = 0; x < cdXSize; x++) {    for (y = 0; y < cdYSize; y++) {      Tangle[x][y] = (int)(atan2(cy - y, cx - x) * 256. / M_PI );      distance = (sqrt((x-cx)*(x-cx) + (y-cy)*(y-cy)));      Tdepth[x][y] =  256. * diameter / distance;    }    }  }  void PintaObjeto (void) {  DrawTunnel ((cdXSize/2)* sin(tmp * .5), (tmp *.8)* (cdYSize/2));  tmp += .05;}void Inicio (void) {  doPrecalc ();}LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){     static   HDC               bufDIBDC;     static   HBITMAP           hMainDIB;              HDC               hdc ;              PAINTSTRUCT       ps ;     static   HGDIOBJ           hOldDIB=0, hGDITmp;              int               bResult;     switch (message)     {     case WM_CHAR :          if (wParam == VK_ESCAPE) {            goto     wmDestruimos;          }          return 0 ;     case WM_CREATE:          hdc = GetDC(hWnd);                    // Crea un búfer dib para PintaObjeto. pMainDIB es un puntero a él          bufDIBDC = CreateCompatibleDC (hdc);          hMainDIB = CreateDIBSection(hdc, (BITMAPINFO *) &bi, DIB_RGB_COLORS, (void **) &pMainDIB, NULL, 0);          hOldDIB  = SelectObject (bufDIBDC, hMainDIB);                  ReleaseDC (hWnd, hdc);   // Libera device context                    Inicio ();          SetTimer (hWnd, cdIdTimer, 20, NULL) ;          return 0 ;     case WM_TIMER :          InvalidateRect (hWnd, NULL, FALSE) ;          return 0 ;     case WM_SIZE :          vdxClient = lParam & 0xFFFF;          vdyClient = lParam >> 0x10;          return 0 ;     case WM_PAINT :          hdc = BeginPaint(hWnd, &ps);          PintaObjeto ();          // bResult = BitBlt(hdc, 0, 0, cdXSize, cdYSize, bufDIBDC, 0, 0, SRCCOPY);          bResult = StretchBlt (hdc, 0, 0, vdxClient, vdyClient, bufDIBDC, 0, 0, cdXSize, cdYSize, SRCCOPY);          EndPaint(hWnd, &ps);          return 0 ;     case WM_DESTROY :          wmDestruimos:          KillTimer (hWnd, cdIdTimer) ;          hGDITmp = SelectObject (bufDIBDC, hOldDIB);          bResult = DeleteDC (bufDIBDC);          bResult = DeleteObject (hMainDIB);          bResult = DestroyWindow (hWnd);          PostQuitMessage (0) ;          return 0 ;     }     return DefWindowProc (hWnd, message, wParam, lParam) ;}int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,                    PSTR szCmdLine, int iCmdShow){     RECT   WRect;     static TCHAR szAppName[] = TEXT ("SWGPTG") ;     HWND         hWnd ;     MSG          msg ;     WNDCLASS     wndclass ;     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;     wndclass.lpfnWndProc   = WndProc ;     wndclass.cbClsExtra    = 0 ;     wndclass.cbWndExtra    = 0 ;     wndclass.hbrBackground = cdColFondo ;     wndclass.lpszMenuName  = NULL ;     wndclass.lpszClassName = szAppName ;     wndclass.hInstance     = GetModuleHandle (NULL) ;     wndclass.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(MAIN_ICON)) ;     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;     if (!RegisterClass (&wndclass)) {          MessageBox (NULL, TEXT ("This program requires Windows NT!"),                      TEXT ("Error"), MB_ICONERROR) ;          return 0 ;     }     SetRect (&WRect, 0, 0, cdXSize, cdYSize);     AdjustWindowRectEx (&WRect, cdVBtnTipo, 0, cdVBarTipo);     WRect.bottom -= WRect.top;     WRect.right  -= WRect.left;     WRect.left    = (GetSystemMetrics (SM_CXSCREEN) - WRect.right)/2;     WRect.top     = (GetSystemMetrics (SM_CYSCREEN) - WRect.bottom) / 3;          hWnd = CreateWindow (szAppName, TEXT ("Tunnel - from Relsoft"),                          cdVBtnTipo,//WS_OVERLAPPEDWINDOW,                          WRect.left,WRect.top,WRect.right,WRect.bottom,                          NULL, NULL, hInstance, NULL) ;     ShowWindow (hWnd, iCmdShow) ;     UpdateWindow (hWnd) ;     while (GetMessage (&msg, NULL, 0, 0)) {          TranslateMessage (&msg) ;          DispatchMessage (&msg) ;     }     return msg.wParam ;}`
jj2007
Posts: 1318
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

### Re: 3d animated tunnel in pure FB

Looks interesting, but I don't have TinyC installed. So I tried Visual C, Gcc and PellesC. All three fail with this code, with very different error messages, of course. It would be nice if C was compatible to something ;-)
dodicat
Posts: 6155
Joined: Jan 10, 2006 20:30
Location: Scotland

### Re: 3d animated tunnel in pure FB

In tiny c, MP_I isn't declared, so a fail.
I made MP_I as 1, just to get a runner, compiled fine, but Avira antivirus stopped the .exe from running and ditched it into the quarantine.

fb 1.06 is no longer compatible with much of the old fb forum code due to
...
Suffixes are only valid in -lang fb or deprecated or fblite
...

I don't know the reason for doing this, suffixes are part of most basic dialects.

luckily relsoft's code only required one suffix to be expunged.
Posts: 47
Joined: Apr 26, 2017 8:57
Contact:

### Re: 3d animated tunnel in pure FB

Tiny C is ANSI compatible. This code may be compiled with any of your three c compilers with a tiny effort. You need a tiny effort because each compiler has its own specifications. Luckily, to install tiny c you just need to unzip the package.

Tiny c does not usually get along with antivirus, beeing common false positives. Lately I've seen that Avast goes pretty well with Tiny C. Not long ago It also gave many false positives, but I sent them the code and, curiously, it seems that they have taken it into account, because now it works quite well. Avira, on the other hand, is still quite strict with tinyc.

I guess I do not have the possibility to attach files, so I can not upload any snap shot.
dodicat
Posts: 6155
Joined: Jan 10, 2006 20:30
Location: Scotland

### Re: 3d animated tunnel in pure FB

Perhaps my tiny c is a bit old.
If I strip the .exe before I run it, the false positive is gone.
It strips to 10 kb, and runs fine.
This is probably why the .exe files produced by freebasic -gen gcc don't give avira problems, because compiled .exe by gcc (Dev-C++, or mingw) often give false positives when using Win api functions.

For curiosiuty, where is the MP_1 defined or declared?
Maybe I should get an updated tcc .zip
UEZ
Posts: 374
Joined: May 05, 2017 19:59
Location: Germany

### Re: 3d animated tunnel in pure FB

paul doe
Posts: 1066
Joined: Jul 25, 2017 17:22
Location: Argentina

### Re: 3d animated tunnel in pure FB

I guess I do not have the possibility to attach files, so I can not upload any snap shot.

Nobody here does. You need to use an external host for your images like imgbox.
Posts: 47
Joined: Apr 26, 2017 8:57
Contact:

### Re: 3d animated tunnel in pure FB

What is MP_1? I have never seen it
Posts: 47
Joined: Apr 26, 2017 8:57
Contact:

### Re: 3d animated tunnel in pure FB

Here it is another enhanced version of the tunnel. Compiled in 10Kb with tiny c, almost no wasting cpu. Code: Select all

`#define cdXPos          CW_USEDEFAULT#define cdYPos          CW_USEDEFAULT#define cdXSize         320 //cdYSize*1.6#define cdYSize         200#define cdColFondo      0#define MAIN_ICON       100    //  IDI_APPLICATION#define cdVCursor       IDC_ARROW#define cdVBarTipo      0#define cdVBtnTipo      WS_OVERLAPPEDWINDOW#define cdIdTimer       1#define DIB_RGB_COLORS  0#define deg2rad         0.01745329251994   // pi/180#define cdPI            3.1415926535897932384626433832795#define cd2PI           6.283185307179586476925286766559#define maxpoints       32// Prototipos de funcionesLRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;// Variables globalesint               *pMainDIB    = NULL;int                vdxClient, vdyClient;BITMAPINFOHEADER   bi = {sizeof(BITMAPINFOHEADER),cdXSize,-cdYSize,1,32,0,0,0,0,0,0};int                Tangle[cdXSize*2][cdYSize*2], Tdepth[cdXSize*2][cdYSize*2];int                Texture, Distbuffer;double             xcoords[maxpoints], ycoords[maxpoints];double             tmp = 0;double dist (double x, double y, double xc[], double yc[]) {  double mindist = 1E+16, a, b, d;  int i;  for (i = 0; i < maxpoints; i++) {    a = (xc[i] - x) * (xc[i] - x) ;    b = (yc[i] - y) * (yc[i] - y);    d = sqrt(a + b);    if (d < mindist) mindist = d;  }  return(mindist);}  void doPrecalc (void) {  int x, y, i, r, g, b, cx, cy, diameter = 64;  double mindist, maxdist, distance, c, tx, ty;  for (i = 0; i < maxpoints; i++) {    xcoords[i] = rand() % cdXSize;    ycoords[i] = rand() % cdYSize;  }  mindist = 1E+16;  maxdist = 0;  for (y = 0; y < 256; y++) {    for (x = 0; x < 256; x++) {      tx = abs(x-128); ty = abs(y - 128);      distance = dist (tx, ty, xcoords, ycoords) ;      Distbuffer [x][y] = distance;      if (distance < mindist) mindist = distance;      if (distance > maxdist) maxdist = distance;    }    }    for (y = 0; y < 256; y++) {    for (x = 0; x < 256; x++) {      c =(Distbuffer [x][y] - mindist) / (maxdist - mindist);      r = (int)(c * 55.);      g = (int)(c * 155.);      b = (int)(c * 255.);      Texture[x][y] = (r << 16) | (g << 8) | b;    }    }  cx = cdXSize; cy = cdYSize;  for (x = 0; x < cdXSize*2; x++) {    for (y = 0; y < cdYSize*2; y++) {      Tangle[x][y] = (int)(atan2(cy - y, cx - x) * 256. / M_PI );      distance = (sqrt((x-cx)*(x-cx) + (y-cy)*(y-cy)));      Tdepth[x][y] =  256. * diameter / distance;    }    }  }  void PintaObjeto (void) {  int x, y, tx, ty;  static double currtime = 0.0;  int sx, sy, slx, sly, k = 0, r, g, b, c;  double    d;  currtime += 0.00913;  sx = (int)(256 * 1.0 * currtime);  sy = (int)(256 * 0.25 * currtime);  //Calculate the movement  slx = cdXSize / 2 + (int)(cdXSize / 2 * cos(currtime));  sly = cdYSize / 2 + (int)(cdYSize / 2 * sin(currtime * 3.3));    for (y = 0; y < cdYSize; y++) {    for (x = 0; x < cdXSize; x++, k++) {      tx = (unsigned int)(Tdepth[x + slx][y + sly] + sx) & 255;      ty = (unsigned int)2*(Tangle[x + slx][y + sly] + sy) & 255;      d = (54./Tdepth[x + slx][y + sly]);      c = Texture[tx][ty];      r = (c & (0xFF0000))>>16; g = (c & (0xFF00))>>8; b = c & 0xFF;      r = (int) ((double)r * d); g = (int)((double)g * d); b = (int)((double)b * d);      if (r & 0x1F00) r = 255; if (g & 0x1F00) g = 255; if (b & 0x1F00) b = 255;      *(pMainDIB + k) = b|(g<<8)|(r<<16);    }    }  }void Inicio (void) {  doPrecalc ();}LRESULT CALLBACK WndProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){     static   HDC               bufDIBDC;     static   HBITMAP           hMainDIB;              HDC               hdc ;              PAINTSTRUCT       ps ;     static   HGDIOBJ           hOldDIB=0, hGDITmp;              int               bResult;     switch (message)     {     case WM_CHAR :          if (wParam == VK_ESCAPE) {            goto     wmDestruimos;          }          return 0 ;     case WM_CREATE:          hdc = GetDC(hWnd);                    // Crea un búfer dib para PintaObjeto. pMainDIB es un puntero a él          bufDIBDC = CreateCompatibleDC (hdc);          hMainDIB = CreateDIBSection(hdc, (BITMAPINFO *) &bi, DIB_RGB_COLORS, (void **) &pMainDIB, NULL, 0);          hOldDIB  = SelectObject (bufDIBDC, hMainDIB);                  ReleaseDC (hWnd, hdc);   // Libera device context                    Inicio ();          SetTimer (hWnd, cdIdTimer, 20, NULL) ;          return 0 ;     case WM_TIMER :          InvalidateRect (hWnd, NULL, FALSE) ;          return 0 ;     case WM_SIZE :          vdxClient = lParam & 0xFFFF;          vdyClient = lParam >> 0x10;          return 0 ;     case WM_PAINT :          hdc = BeginPaint(hWnd, &ps);          PintaObjeto ();          // bResult = BitBlt(hdc, 0, 0, cdXSize, cdYSize, bufDIBDC, 0, 0, SRCCOPY);          bResult = StretchBlt (hdc, 0, 0, vdxClient, vdyClient, bufDIBDC, 0, 0, cdXSize, cdYSize, SRCCOPY);          EndPaint(hWnd, &ps);          return 0 ;     case WM_DESTROY :          wmDestruimos:          KillTimer (hWnd, cdIdTimer) ;          hGDITmp = SelectObject (bufDIBDC, hOldDIB);          bResult = DeleteDC (bufDIBDC);          bResult = DeleteObject (hMainDIB);          bResult = DestroyWindow (hWnd);          PostQuitMessage (0) ;          return 0 ;     }     return DefWindowProc (hWnd, message, wParam, lParam) ;}int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,                    PSTR szCmdLine, int iCmdShow){     RECT   WRect;     static TCHAR szAppName[] = TEXT ("SWGPTG") ;     HWND         hWnd ;     MSG          msg ;     WNDCLASS     wndclass ;     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;     wndclass.lpfnWndProc   = WndProc ;     wndclass.cbClsExtra    = 0 ;     wndclass.cbWndExtra    = 0 ;     wndclass.hbrBackground = cdColFondo ;     wndclass.lpszMenuName  = NULL ;     wndclass.lpszClassName = szAppName ;     wndclass.hInstance     = GetModuleHandle (NULL) ;     wndclass.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(MAIN_ICON)) ;     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;     if (!RegisterClass (&wndclass)) {          MessageBox (NULL, TEXT ("This program requires Windows NT!"),                      TEXT ("Error"), MB_ICONERROR) ;          return 0 ;     }     SetRect (&WRect, 0, 0, cdXSize, cdYSize);     AdjustWindowRectEx (&WRect, cdVBtnTipo, 0, cdVBarTipo);     WRect.bottom -= WRect.top;     WRect.right  -= WRect.left;     WRect.left    = (GetSystemMetrics (SM_CXSCREEN) - WRect.right)/2;     WRect.top     = (GetSystemMetrics (SM_CYSCREEN) - WRect.bottom) / 3;          hWnd = CreateWindow (szAppName, TEXT ("Tunnel - from Relsoft"),                          cdVBtnTipo,//WS_OVERLAPPEDWINDOW,                          WRect.left,WRect.top,WRect.right,WRect.bottom,                          NULL, NULL, hInstance, NULL) ;     ShowWindow (hWnd, iCmdShow) ;     UpdateWindow (hWnd) ;     while (GetMessage (&msg, NULL, 0, 0)) {          TranslateMessage (&msg) ;          DispatchMessage (&msg) ;     }     return msg.wParam ;}`
dodicat
Posts: 6155
Joined: Jan 10, 2006 20:30
Location: Scotland

### Re: 3d animated tunnel in pure FB

hurtado wrote:What is MP_1? I have never seen it

Tangle[x][y] = (int)(atan2(cy - y, cx - x) * 256. / M_PI ); // line 88

sorry, M_PI I meant to write.