"Fossies" - the Fresh Open Source Software Archive

Member "FreeBASIC-1.09.0-win64/examples/graphics/OpenGL/NeHe/3Dobject.bi" (1 Jan 2022, 7791 Bytes) of package /windows/misc/FreeBASIC-1.09.0-win64.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Visual Basic source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 #ifndef _3DOBJECT_H_
    2 #define _3DOBJECT_H_
    3 #ifndef TRUE
    4 #define TRUE = not FALSE
    5 #endif
    6 
    7 '' vertex in 3d-coordinate system
    8 type sPoint
    9     x as single
   10     y as single
   11     z as single
   12 end type
   13 
   14 '' plane equation
   15 type sPlaneEq
   16     a as single
   17     b as single
   18     c as single
   19     d as single
   20 end type
   21 
   22 '' structure describing an object's face
   23 type sPlane
   24     p(0 to 2) as uinteger
   25     normals(0 to 2) as sPoint
   26     neigh(0 to 2) as uinteger
   27     PlaneEq as sPlaneEq
   28     visible as integer
   29 end type
   30 
   31 '' object structure
   32 type glObject
   33     nPlanes as uinteger
   34     nPoints as uinteger
   35     points(0 to 99) as sPoint
   36     planes(0 to 199) as sPlane
   37 end type
   38 
   39 '' read in a line from the data file
   40 private sub readstr(byval f as integer, byref sstring as string)
   41     sstring = ""
   42     do
   43         line input #f, sstring    '' Gets A String Of 255 Chars Max From f (File)
   44     loop while sstring = "" and not eof(f)
   45 end sub
   46 
   47 '' load object
   48 private function ReadObject(byref st as string, byval o as glObject ptr) as integer
   49     dim as integer file
   50     dim as uinteger i
   51     dim oneline as string * 256
   52 
   53     file = freefile
   54     if (open(st, for input, as #file)<>0) then  return 0
   55 
   56     ''points
   57     readstr(file, oneline)
   58     sscanf(strptr(oneline), "%d", @o->nPoints)
   59     for i=1 to o->nPoints
   60         readstr(file, oneline)
   61         sscanf(strptr(oneline), "%f %f %f", @o->points(i).x,@o->points(i).y,@o->points(i).z)
   62     next
   63     ''planes
   64     readstr(file, oneline)
   65     sscanf(strptr(oneline), "%d", @o->nPlanes)
   66     for i=0 to o->nPlanes-1
   67         readstr(file, oneline)
   68         sscanf(strptr(oneline), "%d %d %d %f %f %f %f %f %f %f %f %f", _
   69             @o->planes(i).p(0), _
   70             @o->planes(i).p(1), _
   71             @o->planes(i).p(2), _
   72             @o->planes(i).normals(0).x, _
   73             @o->planes(i).normals(0).y, _
   74             @o->planes(i).normals(0).z, _
   75             @o->planes(i).normals(1).x, _
   76             @o->planes(i).normals(1).y, _
   77             @o->planes(i).normals(1).z, _
   78             @o->planes(i).normals(2).x, _
   79             @o->planes(i).normals(2).y, _
   80             @o->planes(i).normals(2).z)
   81     next
   82     return TRUE
   83 end function
   84 
   85 '' connectivity procedure - based on Gamasutra's article
   86 '' hard to explain here
   87 private sub SetConnectivity(byval o as glObject ptr)
   88     dim as uinteger p1i, p2i, p1j, p2j
   89     dim as uinteger b1i, b2i, b1j, b2j
   90     dim as uinteger i,j,ki,kj
   91 
   92     for i=0  to o->nPlanes-2
   93         for j=i+1 to o->nPlanes-1
   94             for ki=0 to 2
   95                 if o->planes(i).neigh(ki) = 0 then
   96                     for kj=0 to 2
   97                         p1i=ki
   98                         p1j=kj
   99                         p2i=(ki+1) mod 3
  100                         p2j=(kj+1) mod 3
  101 
  102                         p1i=o->planes(i).p(p1i)
  103                         p2i=o->planes(i).p(p2i)
  104                         p1j=o->planes(j).p(p1j)
  105                         p2j=o->planes(j).p(p2j)
  106 
  107                         b1i=((p1i+p2i)-abs(p1i-p2i))\2
  108                         b2i=((p1i+p2i)+abs(p1i-p2i))\2
  109                         b1j=((p1j+p2j)-abs(p1j-p2j))\2
  110                         b2j=((p1j+p2j)+abs(p1j-p2j))\2
  111 
  112                         if ((b1i=b1j) and (b2i=b2j)) then  ''they are neighbours
  113                             o->planes(i).neigh(ki) = j+1
  114                             o->planes(j).neigh(kj) = i+1
  115                         end if
  116                     next
  117                 end if
  118             next
  119         next
  120     next
  121 end sub
  122 
  123 '' function for computing a plane equation given 3 points
  124 private sub CalcPlane(byval o as glObject ptr, byval plane as sPlane ptr)
  125     dim as sPoint v(0 to 3)
  126     dim as integer i
  127 
  128     for i=0  to 2
  129         v(i+1).x = o->points(plane->p(i)).x
  130         v(i+1).y = o->points(plane->p(i)).y
  131         v(i+1).z = o->points(plane->p(i)).z
  132     next
  133     plane->PlaneEq.a = v(1).y*(v(2).z-v(3).z) + v(2).y*(v(3).z-v(1).z) + v(3).y*(v(1).z-v(2).z)
  134     plane->PlaneEq.b = v(1).z*(v(2).x-v(3).x) + v(2).z*(v(3).x-v(1).x) + v(3).z*(v(1).x-v(2).x)
  135     plane->PlaneEq.c = v(1).x*(v(2).y-v(3).y) + v(2).x*(v(3).y-v(1).y) + v(3).x*(v(1).y-v(2).y)
  136     plane->PlaneEq.d =-( v(1).x*(v(2).y*v(3).z - v(3).y*v(2).z) + _
  137         v(2).x*(v(3).y*v(1).z - v(1).y*v(3).z) + _
  138         v(3).x*(v(1).y*v(2).z - v(2).y*v(1).z) )
  139 end sub
  140 
  141 '' procedure for drawing the object - very simple
  142 private sub DrawGLObject(byval o as glObject ptr)
  143     dim as uinteger i, j
  144 
  145     glBegin(GL_TRIANGLES)
  146         for i=0 to o->nPlanes-1
  147             for j=0 to 2
  148                 glNormal3f(o->planes(i).normals(j).x, _
  149                     o->planes(i).normals(j).y, _
  150                     o->planes(i).normals(j).z)
  151                 glVertex3f(o->points(o->planes(i).p(j)).x, _
  152                     o->points(o->planes(i).p(j)).y, _
  153                     o->points(o->planes(i).p(j)).z)
  154             next
  155         next
  156     glEnd()
  157 end sub
  158 
  159 private sub  CastShadow(byval o as glObject ptr, byval lp as single ptr)
  160     dim as uinteger i, j, k, jj
  161     dim as uinteger p1, p2
  162     dim as sPoint v1, v2
  163     dim as single side
  164 
  165     '' set visual parameter
  166     for i=0 to o->nPlanes-1
  167         '' chech to see if light is in front or behind the plane (face plane)
  168         side =  o->planes(i).PlaneEq.a*lp[0]+ _
  169             o->planes(i).PlaneEq.b*lp[1]+ _
  170             o->planes(i).PlaneEq.c*lp[2]+ _
  171             o->planes(i).PlaneEq.d*lp[3]
  172         if (side >0) then
  173             o->planes(i).visible = 1
  174         else
  175             o->planes(i).visible = 0
  176         end if
  177     next
  178 
  179     glDisable(GL_LIGHTING)
  180     glDepthMask(GL_FALSE)
  181     glDepthFunc(GL_LEQUAL)
  182 
  183     glEnable(GL_STENCIL_TEST)
  184     glColorMask(0, 0, 0, 0)
  185     glStencilFunc(GL_ALWAYS, 1, &hffffffff)
  186 
  187     '' first pass, stencil operation decreases stencil value
  188     glFrontFace(GL_CCW)
  189     glStencilOp(GL_KEEP, GL_KEEP, GL_INCR)
  190     for i=0 to o->nPlanes-1
  191         if o->planes(i).visible <> 0 then
  192             for j=0 to 2
  193                 k = o->planes(i).neigh(j)
  194                 if k = 0 or o->planes(k-1).visible = 0 then
  195                     '' here we have an edge, we must draw a polygon
  196                     p1 = o->planes(i).p(j)
  197                     jj = (j+1) mod 3
  198                     p2 = o->planes(i).p(jj)
  199 
  200                     '' calculate the length of the vector
  201                     v1.x = (o->points(p1).x - lp[0])*100
  202                     v1.y = (o->points(p1).y - lp[1])*100
  203                     v1.z = (o->points(p1).z - lp[2])*100
  204 
  205                     v2.x = (o->points(p2).x - lp[0])*100
  206                     v2.y = (o->points(p2).y - lp[1])*100
  207                     v2.z = (o->points(p2).z - lp[2])*100
  208                     
  209                     '' draw the polygon
  210                     glBegin(GL_TRIANGLE_STRIP)
  211                         glVertex3f(o->points(p1).x, _
  212                             o->points(p1).y, _
  213                             o->points(p1).z)
  214                         glVertex3f(o->points(p1).x + v1.x, _
  215                             o->points(p1).y + v1.y, _
  216                             o->points(p1).z + v1.z)
  217 
  218                         glVertex3f(o->points(p2).x, _
  219                             o->points(p2).y, _
  220                             o->points(p2).z)
  221                         glVertex3f(o->points(p2).x + v2.x, _
  222                             o->points(p2).y + v2.y, _
  223                             o->points(p2).z + v2.z)
  224                     glEnd()
  225                 end if
  226             next
  227         end if
  228     next
  229 
  230     '' second pass, stencil operation increases stencil value
  231     glFrontFace(GL_CW)
  232     glStencilOp(GL_KEEP, GL_KEEP, GL_DECR)
  233     for i=0 to o->nPlanes-1
  234         if o->planes(i).visible <> 0 then
  235             for j=0 to 2
  236                 k = o->planes(i).neigh(j)
  237                 if k = 0 or o->planes(k-1).visible= 0 then
  238                     '' here we have an edge, we must draw a polygon
  239                     p1 = o->planes(i).p(j)
  240                     jj = (j+1) mod 3
  241                     p2 = o->planes(i).p(jj)
  242 
  243                     ''calculate the length of the vector
  244                     v1.x = (o->points(p1).x - lp[0])*100
  245                     v1.y = (o->points(p1).y - lp[1])*100
  246                     v1.z = (o->points(p1).z - lp[2])*100
  247 
  248                     v2.x = (o->points(p2).x - lp[0])*100
  249                     v2.y = (o->points(p2).y - lp[1])*100
  250                     v2.z = (o->points(p2).z - lp[2])*100
  251                     
  252                     ''draw the polygon
  253                     glBegin(GL_TRIANGLE_STRIP)
  254                         glVertex3f(o->points(p1).x, _
  255                             o->points(p1).y, _
  256                             o->points(p1).z)
  257                         glVertex3f(o->points(p1).x + v1.x, _
  258                             o->points(p1).y + v1.y, _
  259                             o->points(p1).z + v1.z)
  260 
  261                         glVertex3f(o->points(p2).x, _
  262                             o->points(p2).y, _
  263                             o->points(p2).z)
  264                         glVertex3f(o->points(p2).x + v2.x, _
  265                             o->points(p2).y + v2.y, _
  266                             o->points(p2).z + v2.z)
  267                     glEnd()
  268                 end if
  269             next
  270         end if
  271     next
  272 
  273     glFrontFace(GL_CCW)
  274     glColorMask(1, 1, 1, 1)
  275 
  276     ''draw a shadowing rectangle covering the entire screen
  277     glColor4f(0.0, 0.0, 0.0, 0.4)
  278     glEnable(GL_BLEND)
  279     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
  280     glStencilFunc(GL_NOTEQUAL, 0, &hffffffff)
  281     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)
  282     glPushMatrix()
  283         glLoadIdentity()
  284         glBegin(GL_TRIANGLE_STRIP)
  285             glVertex3f(-0.1, 0.1,-0.10)
  286             glVertex3f(-0.1,-0.1,-0.10)
  287             glVertex3f( 0.1, 0.1,-0.10)
  288             glVertex3f( 0.1,-0.1,-0.10)
  289         glEnd()
  290     glPopMatrix()
  291     glDisable(GL_BLEND)
  292 
  293     glDepthFunc(GL_LEQUAL)
  294     glDepthMask(GL_TRUE)
  295     glEnable(GL_LIGHTING)
  296     glDisable(GL_STENCIL_TEST)
  297     glShadeModel(GL_SMOOTH)
  298 end sub
  299 
  300 #endif '' _3DOBJECT_H_