5 New OpenGL Programs!!! :-)

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

5 New OpenGL Programs!!! :-)

Post by KristopherWindsor »

These are small demos since I am just learning OpenGL.
They should all run even on Lachie's computer. ;-)
In all of the programs, the space bar toggles the camera mode.

1) Maze

Image
Image

This is a 3D maze with one level.
Controls: left, right, and up
This uses Inkey, so don't hold the keys down.

Code: Select all

' 3D Maze in OpenGL! v1.0
' (C) 2008 Innova and Kristopher Windsor

#include "GL/gl.bi"
#include "GL/glu.bi"

'undefine this to see 2D FBGFX display
#define d3

Const screenx = 640, screeny = 480
Const true = -1, false = 0, pihalf = Atn(1) * 2

Const map_max = 64

Type camera_type
  As Double eye(1 To 3)
  As Double see(1 To 3)
  As Double up(1 To 3)
  
  'transition
  As Double teye(1 To 3)
  As Double tsee(1 To 3)
  As Double tup(1 To 3)
End Type

Type finish_type
  As Integer x, y
End Type

Type map_type
  As Integer c
  As Integer ison
End Type

Type player_type
  As Integer x, y
  As Integer angle '0 - 3 (multiply by pi / 2)
  
  'transition
  As Double tx, ty
  As Double tangle, tav '0 - 3.999...
End Type

Dim Shared As Integer map_total_x, map_total_y
Dim Shared LightDiffuse(0 To 3) As Single => {2, 2, 2, 1}
Dim Shared LightPosition(0 To 3) As Single => {0, 0, 0, 1}
Dim Shared As String key
Dim Shared As camera_type camera 'openGL mode only
Dim Shared As finish_type finish
Dim Shared As map_type map(1 To map_max, 1 To map_max)
Dim Shared As player_type player

Sub map_reset
  Dim As String l
  
  map_total_x = 0
  map_total_y = 0
  
  Restore
  Do
    Read l
    
    If l <> "END" Then
      map_total_y += 1
      If map_total_y = 1 Then map_total_x = Len(l)
      
      For a As Integer = 1 To map_total_x
        With map(a, map_total_y)
          .c = Rgb(Rnd * 256, Rnd * 256, Rnd * 256)
          .ison = (Mid(l, a, 1) = "0")
          
          If Mid(l, a, 1) = "X" Then
            With finish
              .x = a
              .y = map_total_y
            End With
          End If
        End With
      Next a
    End If
  Loop Until l = "END"
End Sub

Sub player_reset
  With player
    .x = 2
    .y = 2
    .angle = 0
    
    .tx = .x
    .ty = .y
    .tangle = .angle
    .tav = 0
  End With
End Sub

Sub player_move
  Dim As Integer x, y
  
  With player
    'input
    Select Case key
    Case Chr(255, 75)
      'left
      .angle -= 1
      If .angle = -1 Then .angle = 3
      .tav = -.15
    Case Chr(255, 77)
      'right
      .angle += 1
      If .angle = 4 Then .angle = 0
      .tav = .15
    Case Chr(255, 72)
      'advance
      x = .x
      y = .y
      Select Case .angle
      Case 0
        x += 1
      Case 1
        y += 1
      Case 2
        x -= 1
      Case 3
        y -= 1
      End Select
      
      If map(x, y).ison = false Then
        .x = x
        .y = y
      End If
    End Select
    
    'animation
    .tx += (.x - .tx) / 10
    .ty += (.y - .ty) / 10
    
    If Abs(.angle - .tangle) < .15 Then
      .tav = 0
    Else
      .tangle += .tav
      If .tangle >= 4 Then .tangle -= 4
      If .tangle < 0 Then .tangle += 4
    End If
  End With
End Sub

#ifdef d3
  Sub display_start
    Screenres screenx, screeny, 32,, 2
    
    glMatrixMode GL_PROJECTION
    glLoadIdentity
    gluPerspective 35.0, screenx / screeny, .1, 300
    glMatrixMode GL_MODELVIEW
    glLoadIdentity
    
    glClearColor 0, 0, 0, 1
    glEnable GL_DEPTH_TEST 'properly handles overlapping polygons (draw order for layering)
    
    glEnable GL_LIGHT1
    glLightfv GL_LIGHT1, GL_DIFFUSE, @LightDiffuse(0)
    glEnable GL_LIGHTING
    glEnable GL_COLOR_MATERIAL
  End Sub
  
  Sub display_go
    Static As Integer camera_mode
    
    Dim As Double r, g, b
    Dim As Double cx, cy, pa
    
    If key = " " Then camera_mode = Not camera_mode
    
    'coords are set for bird's eye view
    'top left of map is at (0, 0, 0)
    'all parts of map are 1un cubed
    
    glClear GL_DEPTH_BUFFER_BIT Or GL_COLOR_BUFFER_BIT
    glLoadIdentity
    
    With camera
      If camera_mode Then
        pa = player.tangle * pihalf
        .eye(1) = player.tx + .5
        .eye(2) = player.ty + .5
        .eye(3) = -.5
        .see(1) = player.tx + Cos(pa) + .5
        .see(2) = player.ty + Sin(pa) + .5
        .see(3) = -.5
        .up(1) = 0
        .up(2) = 0
        .up(3) = -1 '-1 keeps y-coords like fbgfx (not like graphing coords)
      Else
        .eye(1) = map_total_x / 2
        .eye(2) = map_total_y / 2
        .eye(3) = -map_total_x * 1.4
        .see(1) = map_total_x / 2
        .see(2) = map_total_y / 2
        .see(3) = 0
        .up(1) = 0
        .up(2) = -1 '-1 keeps y-coords like fbgfx (not like graphing coords)
        .up(3) = 0
      End If
      
      LightPosition(0) = .eye(1) 'player.tx + .5'
      LightPosition(1) = .eye(2) 'player.ty + .5'
      LightPosition(2) = .eye(3) '-.5'
      glLightfv GL_LIGHT1, GL_POSITION, @LightPosition(0)
      
      For a As Integer = 1 To 3
        .teye(a) += (.eye(a) - .teye(a)) / 8
        .tsee(a) += (.see(a) - .tsee(a)) / 8
        .tup(a) += (.up(a) - .tup(a)) / 8
      Next a
      
      gluLookat .teye(1), .teye(2), .teye(3), .tsee(1), .tsee(2), .tsee(3), .tup(1), .tup(2), .tup(3)
    End With
    
    'map
    glBegin GL_QUADS
      For x As Integer = 1 To map_total_x
        For y As Integer = 1 To map_total_y
          With map(x, y)
            If .ison Then
              r = ((.c And &HFF0000) Shr 16) / 255
              g = ((.c And &HFF00) Shr 8) / 255
              b = (.c And &HFF) / 255
              'ceiling
              glColor3f r, g, b
              glNormal3f 0, 0, 1
              glVertex3f x,     y,     -1
              glVertex3f x + 1, y,     -1
              glVertex3f x + 1, y + 1, -1
              glVertex3f x,     y + 1, -1
              'left wall
              glColor3f r, g, b
              glNormal3f -1, 0, 0
              glVertex3f x,     y,     0
              glVertex3f x,     y + 1, 0
              glVertex3f x,     y + 1, -1
              glVertex3f x,     y,     -1
              'right wall
              glColor3f r, g, b
              glNormal3f 1, 0, 0
              glVertex3f x + 1, y,     0
              glVertex3f x + 1, y + 1, 0
              glVertex3f x + 1, y + 1, -1
              glVertex3f x + 1, y,     -1
              'north wall
              glColor3f r, g, b
              glNormal3f 0, -1, 0
              glVertex3f x,     y,     0
              glVertex3f x + 1, y,     0
              glVertex3f x + 1, y,     -1
              glVertex3f x,     y,     -1
              'south wall
              glColor3f r, g, b
              glNormal3f 0, 1, 0
              glVertex3f x,     y + 1, 0
              glVertex3f x + 1, y + 1, 0
              glVertex3f x + 1, y + 1, -1
              glVertex3f x,     y + 1, -1
            End If
          End With
        Next y
      Next x
    glEnd
    
    'finish
    glBegin GL_TRIANGLES
      With finish
        'left
        glColor3f 1, 1, 1
        glNormal3f -1, 0, 0
        glVertex3f .x + .5, .y + .5, -1
        glVertex3f .x,      .y,      0
        glVertex3f .x,      .y + 1,  0
        'right
        glColor3f 1, 1, 1
        glNormal3f 1, 0, 0
        glVertex3f .x + .5, .y + .5, -1
        glVertex3f .x + 1,  .y,      0
        glVertex3f .x + 1,  .y + 1,  0
        'top
        glColor3f 1, 1, 1
        glNormal3f 0, -1, 0
        glVertex3f .x + .5, .y + .5, -1
        glVertex3f .x,      .y,      0
        glVertex3f .x + 1,  .y,      0
        'bottom
        glColor3f 1, 1, 1
        glNormal3f 0, 1, 0
        glVertex3f .x + .5, .y + .5, -1
        glVertex3f .x,      .y + 1,  0
        glVertex3f .x + 1,  .y + 1,  0
      End With
    glEnd
    
    'player
    glBegin GL_QUADS
      With player
        cx = .tx + .5
        cy = .ty + .5
        pa = .tangle * pihalf
        
        glColor3f 1, 1, 1
        glNormal3f 0, 0, -1
        glVertex3f cx - Cos(pa) * .2, cy - Sin(pa) * .2, -.2
        glVertex3f cx + Cos(pa + pihalf) * .5, cy + Sin(pa + pihalf) * .5, -.2
        glVertex3f cx + Cos(pa) * .6, cy + Sin(pa) * .6, -.2
        glVertex3f cx + Cos(pa - pihalf) * .5, cy + Sin(pa - pihalf) * .5, -.2
      End With
    glEnd
    
    Flip
  End Sub
#else
  Sub display_start
    Screenres screenx, screeny, 32
  End Sub
  
  Sub display_go
    Screenlock
    Cls
    
    'map
    For x As Integer = 1 To map_total_x
      For y As Integer = 1 To map_total_y
        With map(x, y)
          If .ison Then
            Line (x * 12, y * 12) - Step(11, 11), .c, BF
          End If
        End With
      Next y
    Next x
    
    'finish
    With finish
      Line (.x * 12 + 2, .y * 12 + 2) - Step(7, 7), &HFFFFFFFF, BF
    End With
    
    'player
    With player
      Circle (.tx * 12 + 6, .ty * 12 + 6), 6, &HFFFFFFFF,,, 1
      Line Step(0, 0) - Step(Cos(.tangle * pihalf) * 6, Sin(.tangle * pihalf) * 6), &HFFFFFFFF
    End With
    
    Screenunlock
  End Sub
#endif

Sub game_play
  map_reset
  player_reset
  
  Do
    player_move
    display_go
    Sleep 10
    key = Inkey
  Loop Until key = Chr(27) Or (player.x = finish.x And player.y = finish.y)
End Sub

display_start
game_play

Data "00000000000000000000000000000"
Data "0  0  0   0            0    0"
Data "0  0  0   0   0000000  0 0000"
Data "0  0  0   00  0             0"
Data "0  0    0 00  0000000000000 0"
Data "0  0    0 00  0         0   0"
Data "0       0 00  0  000000 0 000"
Data "000000000 00  0       0 0   0"
Data "0         0   0  000000 000 0"
Data "000000000 0  00  0      0   0"
Data "0         0  00  0 000000 000"
Data "0 000000000  00  0 0   0    0"
Data "0            00 X0   0   0  0"
Data "00000000000000000000000000000"
Data "END"
2) Ride the Train

Image

This is a ride around the city demo.
Of course, since you're on the train, you can't see the train. :-P
This program has no controls, except the space bar.

Code: Select all

' Ride the Train Walkaround OpenGL Demo! v1.0
' (C) 2008 Innova and Kristopher Windsor

#include "GL/gl.bi"
#include "GL/glu.bi"

Const screenx = 640, screeny = 480
Const mapx = 10, mapy = 10
Const true = -1, false = 0, pihalf = Atn(1) * 2
Const building_max = 12, road_max = 48, tree_max = 40

Type camera_type
  As Double eye(1 To 3)
  As Double see(1 To 3)
  As Double up(1 To 3)
End Type

Type coord_type
  As Double x, y
End Type

Type train_type
  As Integer road_current
  As Double angle
  As coord_type p
End Type

Dim Shared LightDiffuse(0 To 3) As Single => {2, 2, 2, 1}
Dim Shared LightPosition(0 To 3) As Single => {0, 0, 0, 1}
Dim Shared As String key
Dim Shared As camera_type camera
Dim Shared As coord_type building(1 To building_max)
Dim Shared As coord_type road(1 To road_max)
Dim Shared As coord_type tree(1 To tree_max)
Dim Shared As train_type train

Sub start
  Dim As Integer can
  Dim As Double x, y, xv, yv
  
  Screenres screenx, screeny, 32,, 2
  
  glMatrixMode GL_PROJECTION
  glLoadIdentity
  gluPerspective 35.0, screenx / screeny, .1, 20
  glMatrixMode GL_MODELVIEW
  glLoadIdentity
  
  glClearColor 0, 0, 0, 1
  glEnable GL_DEPTH_TEST 'properly handles overlapping polygons (draw order for layering)
  
  glEnable GL_LIGHT1
  glLightfv GL_LIGHT1, GL_DIFFUSE, @LightDiffuse(0)
  glEnable GL_LIGHTING
  glEnable GL_COLOR_MATERIAL
  
  Randomize Timer
  
  x = 2: y = 2
  xv = .5
  For a As Integer = 1 To road_max
    Select Case a - 1
    Case 12
      Swap xv, yv
    Case 18
      Swap xv, yv
      xv *= -1
    Case 24
      Swap xv, yv
      yv *= -1
    Case 30
      Swap xv, yv
      xv *= -1
    Case 36
      Swap xv, yv
    End Select
    
    x += xv
    y += yv
    
    With road(a)
      .x = x
      .y = y
    End With
  Next a
  
  For a As Integer = 1 To building_max
    With building(a)
      Do
        .x = Rnd * mapx
        .y = Rnd * mapy
        can = true
        For b As Integer = 1 To road_max
          If Abs(.x - road(b).x) + Abs(.y - road(b).y) < 1 Then can = false
        Next b
      Loop Until can
    End With
  Next a
  
  For a As Integer = 1 To tree_max
    With tree(a)
      Do
        .x = Rnd * mapx
        .y = Rnd * mapy
        can = true
        For b As Integer = 1 To road_max
          If Abs(.x - road(b).x) + Abs(.y - road(b).y) < 1 Then can = false
        Next b
        For b As Integer = 1 To building_max
          If Abs(.x - building(b).x) + Abs(.y - building(b).y) < 1 Then can = false
        Next b
      Loop Until can
    End With
  Next a
  
  With train
    .road_current = 2
    .p.x = road(1).x
    .p.y = road(1).y
  End With
End Sub

Sub go
  Dim As Double a
  
  'coords are set for bird's eye view
  'top left of map is at (0, 0, 0)
  'all parts of map are 1un cubed
  
  glClear GL_DEPTH_BUFFER_BIT Or GL_COLOR_BUFFER_BIT
  glLoadIdentity
  Static As Double xx
  With train
    a = Atan2(road(.road_current).y - .p.y, road(.road_current).x - .p.x)
    If Abs(a - .angle) > .02 Then
      .angle += Sgn(a - .angle) * .02
    Else
      .angle = a
      
      .p.x += Cos(a) * .05
      .p.y += Sin(a) * .05
      
      If Abs(.p.y - road(.road_current).y) + Abs(.p.x - road(.road_current).x) < .1 Then
        .p.y = road(.road_current).y
        .p.x = road(.road_current).x
        .road_current += 1
        If .road_current = road_max Then .road_current = 1
      End If
    End If
    LightPosition(0) = .p.x
    LightPosition(1) = .p.y
    LightPosition(2) = -1
    glLightfv GL_LIGHT1, GL_POSITION, @LightPosition(0)
  End With
  
  With camera
    If Multikey(&H39) Then
      .eye(1) = mapx / 2
      .eye(2) = mapy / 2
      .eye(3) = -mapx * 1.4
      .see(1) = mapx / 2
      .see(2) = mapy / 2
      .see(3) = 0
      .up(1) = 0
      .up(2) = 1
      .up(3) = 0
    Else
      .eye(1) = train.p.x
      .eye(2) = train.p.y
      .eye(3) = -.2
      .see(1) = train.p.x + Cos(train.angle)
      .see(2) = train.p.y + Sin(train.angle)
      .see(3) = -.2
      .up(1) = 0
      .up(2) = 0
      .up(3) = -1
    End If
    
    gluLookat .eye(1), .eye(2), .eye(3), .see(1), .see(2), .see(3), .up(1), .up(2), .up(3)
  End With
  
  glBegin GL_QUADS
    'ground
    glColor3d .4, .2, 0
    glNormal3f 0, 0, -1
    glVertex3d 0,    0,    0
    glVertex3d mapx, 0,    0
    glVertex3d mapx, mapy, 0
    glVertex3d 0,    mapy, 0

    'road
    For a As Integer = 1 To road_max
      With road(a)
        glColor3d 1, .6, .2
        glNormal3f 0, 0, -1
        glVertex3d .x - .25, .y - .25, -.04
        glVertex3d .x + .25, .y - .25, -.04
        glVertex3d .x + .25, .y + .25, -.04
        glVertex3d .x - .25, .y + .25, -.04
      End With
    Next a
    
    'buildings
    For a As Integer = 1 To building_max
      With building(a)
        'left
        glColor3d .6, .6, .8
        glNormal3f -1, 0, 0
        glVertex3d .x - .5, .y - .5, 0
        glVertex3d .x - .5, .y + .5, 0
        glVertex3d .x - .5, .y + .5, -1
        glVertex3d .x - .5, .y - .5, -1
        'right
        glColor3d .6, .6, .8
        glNormal3f 1, 0, 0
        glVertex3d .x + .5, .y - .5, 0
        glVertex3d .x + .5, .y + .5, 0
        glVertex3d .x + .5, .y + .5, -1
        glVertex3d .x + .5, .y - .5, -1
        'north
        glColor3d .6, .6, .8
        glNormal3f 0, 1, 0
        glVertex3d .x - .5, .y + .5, 0
        glVertex3d .x + .5, .y + .5, 0
        glVertex3d .x + .5, .y + .5, -1
        glVertex3d .x - .5, .y + .5, -1
        'south
        glColor3d .6, .6, .8
        glNormal3f 0, -1, 0
        glVertex3d .x - .5, .y - .5, 0
        glVertex3d .x + .5, .y - .5, 0
        glVertex3d .x + .5, .y - .5, -1
        glVertex3d .x - .5, .y - .5, -1
        'roof
        glColor3d .6, .6, .8
        glNormal3f 0, 0, -1
        glVertex3d .x - .5, .y - .5, -1
        glVertex3d .x + .5, .y - .5, -1
        glVertex3d .x + .5, .y + .5, -1
        glVertex3d .x - .5, .y + .5, -1
      End With
    Next a
  glEnd
  
  glBegin GL_TRIANGLES
    'trees
    For a As Integer = 1 To tree_max
      With tree(a)
        glColor3d .2, 1, .2
        glNormal3f -1, 0, 0
        glVertex3d .x,      .y,      -.5
        glVertex3d .x - .1, .y - .1, 0
        glVertex3d .x - .1, .y + .1, 0
        
        glColor3d .2, 1, .2
        glNormal3f 1, 0, 0
        glVertex3d .x,      .y,      -.5
        glVertex3d .x + .1, .y - .1, 0
        glVertex3d .x + .1, .y + .1, 0
        
        glColor3d .2, 1, .2
        glNormal3f 0, -1, 0
        glVertex3d .x,      .y,      -.5
        glVertex3d .x - .1, .y - .1, 0
        glVertex3d .x + .1, .y - .1, 0
        
        glColor3d .2, 1, .2
        glNormal3f 0, 1, 0
        glVertex3d .x,      .y,      -.5
        glVertex3d .x - .1, .y + .1, 0
        glVertex3d .x + .1, .y + .1, 0
      End With
    Next a
    
    'train
    With train
      glColor3d 1, 1, 1
      glNormal3f 0, 0, -1
      glVertex3d .p.x, .p.y, -.2
      glVertex3d .p.x + Cos(.angle + .1), .p.y + Sin(.angle + .1), -.2
      glVertex3d .p.x + Cos(.angle - .1), .p.y + Sin(.angle - .1), -.2
    End With
  glEnd
  
  Flip
End Sub

Sub main
  start
  Do
    go
    Sleep 10
    key = Inkey
  Loop Until key = Chr(27)
End Sub

main
3) Space Wars

Image

This is another demo without controls (except the space bar).
The space ships were inspired by Star Wars, although they only have 3 polygons. xD

Code: Select all

' Watch the Space Wars OpenGL Demo! v1.0
' (C) 2008 Innova and Kristopher Windsor

#include "GL/gl.bi"
#include "GL/glu.bi"

Const screenx = 640, screeny = 480
Const true = -1, false = 0, pi = Atn(1) * 4
Const missile_max = 256, pod_max = 8

Type camera_type
  As Double eye(1 To 3)
  As Double see(1 To 3)
  As Double up(1 To 3)
End Type

Type coord_type
  As Double x, y
End Type

Type missile_type
  As coord_type p, v
  As Integer killme
End Type

Dim Shared As Integer missile_total
Dim Shared LightDiffuse(0 To 3) As Single => {3, 3, 3, 1}
Dim Shared LightPosition(0 To 3) As Single => {0, 0, 0, 1}
Dim Shared As Double pod(1 To pod_max)
Dim Shared As String key

Dim Shared As camera_type camera
Dim Shared As missile_type missile(1 To missile_max)

Sub start
  Screenres screenx, screeny, 32,, 2
  
  glMatrixMode GL_PROJECTION
  glLoadIdentity
  gluPerspective 35.0, screenx / screeny, .05, 8
  glMatrixMode GL_MODELVIEW
  glLoadIdentity
  
  glClearColor 0, 0, 0, 1
  glEnable GL_DEPTH_TEST 'properly handles overlapping polygons (draw order for layering)
  
  glEnable GL_LIGHT1
  glLightfv GL_LIGHT1, GL_DIFFUSE, @LightDiffuse(0)
  glEnable GL_LIGHTING
  glEnable GL_COLOR_MATERIAL
  
  Randomize Timer
  
  For a As Integer = 1 To pod_max
    pod(a) = Rnd * pi * 2
  Next a
End Sub

Sub go
  Dim As Integer i
  Dim As Double d, cx, cy
  
  'coords are set for bird's eye view
  'top left of map is at (0, 0, 0)
  'all parts of map are 1un cubed
  
  'process space ships
  For a As Integer = 1 To pod_max
    pod(a) += .01
    
    If Rnd < .1 Then
      If missile_total + 2 <= missile_max Then
        cx = Cos(pod(a))
        cy = Sin(pod(a))
        d = pod(a) + pi / 2
        
        missile_total += 1
        With missile(missile_total)
          .p.x = cx + Cos(d + 1 * pi / 4) * .02
          .p.y = cy + Sin(d + 1 * pi / 4) * .02
          .v.x = Cos(d) * .1
          .v.y = Sin(d) * .1
          .killme = false
        End With
        
        missile_total += 1
        With missile(missile_total)
          .p.x = cx + Cos(d + 5 * pi / 4) * .02
          .p.y = cy + Sin(d + 5 * pi / 4) * .02
          .v.x = Cos(d) * .1
          .v.y = Sin(d) * .1
          .killme = false
        End With
      End If
    End If
  Next a
  
  'process missiles
  For a As Integer = 1 To missile_total
    With missile(a)
      .p.x += .v.x
      .p.y += .v.y
      If .p.x < -5 Or .p.y < -5 Or .p.x > 5 Or .p.y > 5 Then .killme = true
    End With
  Next a
  
  i = 1
  While i <= missile_total
    If missile(i).killme Then
      Swap missile(i), missile(missile_total)
      missile_total -= 1
    Else
      i += 1
    End If
  Wend
  
  'start drawing
  glClear GL_DEPTH_BUFFER_BIT Or GL_COLOR_BUFFER_BIT
  glLoadIdentity
  
  LightPosition(0) = 0
  LightPosition(1) = 0
  LightPosition(2) = 3
  glLightfv GL_LIGHT1, GL_POSITION, @LightPosition(0)
  
  With camera
    If Multikey(&H39) Then
      .eye(1) = 0
      .eye(2) = 0
      .eye(3) = 4
      .see(1) = 0
      .see(2) = 0
      .see(3) = 0
      .up(1) = 0
      .up(2) = 1
      .up(3) = 0
    Else
      d = Timer * .6
      .eye(1) = Cos(d) + 1 '+ 1 centers on corner of blue ground
      .eye(2) = Sin(d) + 1
      .eye(3) = .5
      .see(1) = 1
      .see(2) = 1
      .see(3) = .4 + Sin(d * .4) * .25
      .up(1) = 0
      .up(2) = 0
      .up(3) = 1
    End If
    
    gluLookat .eye(1), .eye(2), .eye(3), .see(1), .see(2), .see(3), .up(1), .up(2), .up(3)
  End With
  
  glBegin GL_QUADS
    'ground (blue)
    glColor3d .2, .2, .8
    glNormal3f 0, 0, 1
    glVertex3d -1, -1, 0
    glVertex3d 1,  -1, 0
    glVertex3d 1,  1,  0
    glVertex3d -1, 1,  0
    'extended ground (green)
    glColor3d .2, .8, .2
    glNormal3f 0,  0, 1
    glVertex3d -2, -2, -.3
    glVertex3d 2,  -2, -.3
    glVertex3d 2,  2,  -.3
    glVertex3d -2, 2,  -.3
    
    For a As Integer = 1 To pod_max
      cx = Cos(pod(a))
      cy = Sin(pod(a))
      d = pod(a) + pi / 2
      
      glColor3d 1, 1, 1
      glNormal3f 0, 0, 1
      glVertex3d cx + Cos(d + 1 * pi / 4) * .02, cy + Sin(d + 1 * pi / 4) * .02, .3
      glVertex3d cx + Cos(d + 3 * pi / 4) * .02, cy + Sin(d + 3 * pi / 4) * .02, .3
      glVertex3d cx + Cos(d + 5 * pi / 4) * .02, cy + Sin(d + 5 * pi / 4) * .02, .3
      glVertex3d cx + Cos(d + 7 * pi / 4) * .02, cy + Sin(d + 7 * pi / 4) * .02, .3
      
      glColor3d 1, 1, 1
      glNormal3f Cos(d + pi / 2), Sin(d + pi / 2), 0
      glVertex3d cx + Cos(d + 1 * pi / 4) * .02, cy + Sin(d + 1 * pi / 4) * .02, .25
      glVertex3d cx + Cos(d + 1 * pi / 4) * .02, cy + Sin(d + 1 * pi / 4) * .02, .35
      glVertex3d cx + Cos(d + 3 * pi / 4) * .02, cy + Sin(d + 3 * pi / 4) * .02, .35
      glVertex3d cx + Cos(d + 3 * pi / 4) * .02, cy + Sin(d + 3 * pi / 4) * .02, .25
      
      glColor3d 1, 1, 1
      glNormal3f Cos(d + 3 * pi / 2), Sin(d + 3 * pi / 2), 0
      glVertex3d cx + Cos(d + 5 * pi / 4) * .02, cy + Sin(d + 5 * pi / 4) * .02, .25
      glVertex3d cx + Cos(d + 5 * pi / 4) * .02, cy + Sin(d + 5 * pi / 4) * .02, .35
      glVertex3d cx + Cos(d + 7 * pi / 4) * .02, cy + Sin(d + 7 * pi / 4) * .02, .35
      glVertex3d cx + Cos(d + 7 * pi / 4) * .02, cy + Sin(d + 7 * pi / 4) * .02, .25
    Next a
    
    For a As Integer = 1 To missile_total
      With missile(a)
        glColor3d 1, .2, .2
        glNormal3f 0, 0, 1 'would take some rotation to be correct
        glVertex3d .p.x,            .p.y,            .303
        glVertex3d .p.x - .v.x / 2, .p.y - .v.y / 2, .303
        glVertex3d .p.x - .v.x / 2, .p.y - .v.y / 2, .297
        glVertex3d .p.x,            .p.y,            .297
      End With
    Next a
  glEnd
  
  Flip
End Sub

Sub main
  start
  Do
    go
    Sleep 20
    key = Inkey
  Loop Until key = Chr(27)
End Sub

main
Tags: kristopherwindsor_program_graphics kristopherwindsor_feature_program
Last edited by KristopherWindsor on Mar 22, 2008 6:37, edited 2 times in total.
Lachie Dazdarian
Posts: 2338
Joined: May 31, 2005 9:59
Location: Croatia
Contact:

Post by Lachie Dazdarian »

Well, to my shock all these programs runs quite smooth on my wretched PC. And all are very cool and interesting. Love those simple vector-like GFX.

BTW, why is zooming so crazy in the maze game? Like the movement there.
JohnB
Posts: 236
Joined: Jul 22, 2005 3:53
Location: Minnesota Arizona

Post by JohnB »

Very nice demos !

JohnB
Ryan
Posts: 695
Joined: Jun 10, 2005 2:13
Location: Louisville, KY
Contact:

Post by Ryan »

Great demos... train was my favorite. ^_^
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Post by KristopherWindsor »

I modeled a (literally) primitive car in OpenGL, and made two more programs!! :-)

4) Car Show

Image

This is a demo without controls.
The lighting looks great, but ironically, I found out you have to set the camera before positioning the lights while writing this, but I left it incorrect here since it looked so nice. :-)

Code: Select all

' Car Show OpenGL Demo! v1.0
' (C) 2008 Innova and Kristopher Windsor

#include "GL/gl.bi"
#include "GL/glu.bi"

Const screenx = 640, screeny = 480
Const true = -1, false = 0, pihalf = Atn(1) * 2

Type camera_type
  As Double eye(1 To 3)
  As Double see(1 To 3)
  As Double up(1 To 3)
End Type

Type coord_type
  As Double x, y
End Type

Dim Shared LightDiffuse(0 To 3) As Single => {3, 3, 3, 1}
Dim Shared LightPosition(0 To 3) As Single => {0, 0, 0, 1}
Dim Shared As String key
Dim Shared As camera_type camera

Sub start
  Screenres screenx, screeny, 32,, 2
  
  glMatrixMode GL_PROJECTION
  glLoadIdentity
  gluPerspective 35.0, screenx / screeny, .01, 8
  glMatrixMode GL_MODELVIEW
  glLoadIdentity
  
  glClearColor 0, 0, 0, 1
  glEnable GL_DEPTH_TEST 'properly handles overlapping polygons (draw order for layering)
  
  glEnable GL_LIGHT1
  glLightfv GL_LIGHT1, GL_DIFFUSE, @LightDiffuse(0)
  glEnable GL_LIGHTING
  glEnable GL_COLOR_MATERIAL
  
  Randomize Timer
End Sub

Sub show_car (Byval x As Double, Byval y As Double, Byval spin As Double)
  Const w = .4, h = .6
  
  #define c glColor3d 1, 1, 1
  #define c2(px, py, pz) glColor3d px, py, pz
  #macro v(px, py, pz)
    Scope
      Dim As Double a, d, px2
      px2 = px * w
      a = Atan2(py, px2) + spin
      d = Sqr(px2 * px2 + py * py)
      glVertex3d x + Cos(a) * d, y + Sin(a) * d, pz * h
    End Scope
  #endmacro
  
  'rear bumper
  c
  glNormal3f 0, -1, 0
  v(1,  -1,  .6)
  v(-1, -1,  .6)
  v(-1, -1,  .3)
  v(1,  -1,  .3)
  'rear license plate
  c2(0, 1, 0)
  glNormal3f 0, -1, 0
  v(.4,  -1.02, .53)
  v(-.4, -1.02, .53)
  v(-.4, -1.02, .37)
  v(.4,  -1.02, .37)
  'fin above rear bumper
  c2(1, 0, 0)
  glNormal3f 0, -1, 0
  v(1, -1, .6)
  v(-1, -1, .6)
  v(-1, -1.04, .7)
  v(1, -1.04, .7)
  'top of trunk
  c
  glNormal3f 0, 0, 1
  v(-1, -.7, .6)
  v(1,  -.7, .6)
  v(1,  -1,  .6)
  v(-1, -1,  .6)
  'rear window
  c2(.8, .8, 1)
  glNormal3f 0, -1, 0
  v(1,  -.5, 1)
  v(-1, -.5, 1)
  v(-1, -.7,  .6)
  v(1,  -.7,  .6)
  'roof
  c
  glNormal3f 0, 0, 1
  v(-1, -.5, 1)
  v(1,  -.5, 1)
  v(1,  .25,  1)
  v(-1, .25,  1)
  'windshield
  c2(.8, .8, 1)
  glNormal3f 0, 1, 0
  v(1,  .25, 1)
  v(-1, .25, 1)
  v(-1, .6,  .6)
  v(1,  .6,  .6)
  'hood
  c
  glNormal3f 0, 0, 1
  v(-1, .6, .6)
  v(1,  .6, .6)
  v(1,  1,  .6)
  v(-1, 1,  .6)
  'front bumper
  c
  glNormal3f 0, 1, 0
  v(1,  1,  .6)
  v(-1, 1,  .6)
  v(-1, 1,  .3)
  v(1,  1,  .3)
  'front license plate
  c2(0, 1, 0)
  glNormal3f 0, 1, 0
  v(.4,  1.02, .53)
  v(-.4, 1.02, .53)
  v(-.4, 1.02, .37)
  v(.4,  1.02, .37)
  
  'left side
  c2(1, 0, 0)
  glNormal3f -1, 0, 0
  v(-1, -1, .6)
  v(-1, -1, .3)
  v(-1, 1,  .3)
  v(-1, 1,  .6)
  c2(1, 1, 0)
  glNormal3f -1, 0, 0
  v(-1, -.5, 1)
  v(-1, -.7, .6)
  v(-1, .6,  .6)
  v(-1, .25,  1)
  
  'right side
  c2(1, 0, 0)
  glNormal3f 1, 0, 0
  v(1, -1, .6)
  v(1, -1, .3)
  v(1, 1,  .3)
  v(1, 1,  .6)
  c2(1, 1, 0)
  glNormal3f 1, 0, 0
  v(1, -.5, 1)
  v(1, -.7, .6)
  v(1, .6,  .6)
  v(1, .25,  1)
  
  'front left wheel
  c2(.5, 1, .5)
  glNormal3f -1, 0, 0
  v(-1, .59, .1)
  v(-1, .65, 0)
  v(-1, .7, 0)
  v(-1, .76, .1)
  c2(.5, 1, .5)
  glNormal3f -1, 0, 0
  v(-1, .55, .3)
  v(-1, .59, .1)
  v(-1, .76, .1)
  v(-1, .8, .3)
  'front right wheel
  c2(.5, 1, .5)
  glNormal3f 1, 0, 0
  v(1, .59, .1)
  v(1, .65, 0)
  v(1, .7, 0)
  v(1, .76, .1)
  c2(.5, 1, .5)
  glNormal3f 1, 0, 0
  v(1, .55, .3)
  v(1, .59, .1)
  v(1, .76, .1)
  v(1, .8, .3)
  'rear left wheel
  c2(.5, 1, .5)
  glNormal3f -1, 0, 0
  v(-1, -.59, .1)
  v(-1, -.65, 0)
  v(-1, -.7, 0)
  v(-1, -.76, .1)
  c2(.5, 1, .5)
  glNormal3f -1, 0, 0
  v(-1, -.55, .3)
  v(-1, -.59, .1)
  v(-1, -.76, .1)
  v(-1, -.8, .3)
  'rear right wheel
  c2(.5, 1, .5)
  glNormal3f 1, 0, 0
  v(1, -.59, .1)
  v(1, -.65, 0)
  v(1, -.7, 0)
  v(1, -.76, .1)
  c2(.5, 1, .5)
  glNormal3f 1, 0, 0
  v(1, -.55, .3)
  v(1, -.59, .1)
  v(1, -.76, .1)
  v(1, -.8, .3)
End Sub

Sub go
  Dim As Double angle
  
  'coords are set for bird's eye view
  'top left of map is at (0, 0, 0)
  'all parts of map are 1un cubed
  
  glClear GL_DEPTH_BUFFER_BIT Or GL_COLOR_BUFFER_BIT
  glLoadIdentity

  LightPosition(0) = 0
  LightPosition(1) = 0
  LightPosition(2) = -1
  glLightfv GL_LIGHT1, GL_POSITION, @LightPosition(0)
  
  angle = -Timer * .4
  With camera
    .eye(1) = Cos(angle) * 3
    .eye(2) = Sin(angle) * 3
    .eye(3) = .8
    .see(1) = 0
    .see(2) = 0
    .see(3) = .4
    .up(1) = 0
    .up(2) = 0
    .up(3) = 1
    
    gluLookat .eye(1), .eye(2), .eye(3), .see(1), .see(2), .see(3), .up(1), .up(2), .up(3)
  End With
  
  glBegin GL_QUADS
    'ground
    glColor3d .4, .2, 0
    glNormal3f 0, 0, 1
    glVertex3d -1, -1, 0
    glVertex3d 1,  -1, 0
    glVertex3d 1,  1,  0
    glVertex3d -1, 1,  0
    
    show_car 0, 0, 0
  glEnd
  
  Flip
End Sub

Sub main
  start
  Do
    go
    Sleep 10
    key = Inkey
  Loop Until key = Chr(27)
End Sub

main
5) Car Highway

Image
Image

This is the first demo that allows free - form navigation.
You can control the car with the up, left, and right arrow keys.
You will only see your car in bird's eye view mode, which you can use by holding down the space bar.

Code: Select all

' Car Highway OpenGL Demo! v1.0
' (C) 2008 Innova and Kristopher Windsor

#include once "fbgfx.bi"
#include once "GL/gl.bi"
#include once "GL/glu.bi"

Const screenx = 640, screeny = 480
Const true = -1, false = 0, pi = Atn(1) * 4, mapsize = 8
Const car_max = 4, tree_max = 8

Type camera_type
  As Double eye(1 To 3)
  As Double see(1 To 3)
  As Double up(1 To 3)
End Type

Type coord_type
  As Double x, y
End Type

Type player_type
  As coord_type p, v
  As Double angle
End Type

Dim Shared LightDiffuse(0 To 3) As Single => {1, 1, 1, 1}
Dim Shared LightPosition(0 To 3) As Single => {0, 0, 0, 1}
Dim Shared As Double car(1 To car_max)
Dim Shared As String key
Dim Shared As camera_type camera
Dim Shared As player_type player
Dim Shared As coord_type tree(1 To tree_max)

Sub start
  Dim As Integer can
  
  Screenres screenx, screeny, 32,, 2
  
  glMatrixMode GL_PROJECTION
  glLoadIdentity
  gluPerspective 35.0, screenx / screeny, .01, 24
  glMatrixMode GL_MODELVIEW
  glLoadIdentity
  
  glClearColor 0, 0, 0, 1
  glEnable GL_DEPTH_TEST 'properly handles overlapping polygons (draw order for layering)
  
  glEnable GL_LIGHT1
  glLightfv GL_LIGHT1, GL_DIFFUSE, @LightDiffuse(0)
  glEnable GL_LIGHTING
  glEnable GL_COLOR_MATERIAL
  
  Randomize Timer
  
  For a As Integer = 1 To car_max
    Do
      can = true
      car(a) = Rnd * mapsize * 2 - mapsize
      For b As Integer = 1 To a - 1
        If Abs(car(b) - car(a)) < 2 Then can = false
      Next b
    Loop Until can
  Next a
  
  For a As Integer = 1 To tree_max
    With tree(a)
      Do
        .x = Rnd * mapsize * 2 - mapsize
        .y = Rnd * mapsize * 2 - mapsize
        can = true
        If Abs(.x) < 1 Then can = false
      Loop Until can
    End With
  Next a
End Sub

Sub show_car (Byval x As Double, Byval y As Double, Byval spin As Double)
  Const w = .4, h = .6
  
  #define c glColor3d 1, 1, 1
  #define c2(px, py, pz) glColor3d px, py, pz
  #macro v(px, py, pz)
    Scope
      Dim As Double a, d, px2
      px2 = px * w
      a = Atan2(py, px2) + spin - pi / 2
      d = Sqr(px2 * px2 + py * py)
      glVertex3d x + Cos(a) * d, y + Sin(a) * d, pz * h
    End Scope
  #endmacro
  
  'rear bumper
  c
  glNormal3f 0, -1, 0
  v(1,  -1,  .6)
  v(-1, -1,  .6)
  v(-1, -1,  .3)
  v(1,  -1,  .3)
  'rear license plate
  c2(0, 1, 0)
  glNormal3f 0, -1, 0
  v(.4,  -1.1, .53)
  v(-.4, -1.1, .53)
  v(-.4, -1.1, .37)
  v(.4,  -1.1, .37)
  'fin above rear bumper
  c2(1, 0, 0)
  glNormal3f 0, -1, 0
  v(1, -1, .6)
  v(-1, -1, .6)
  v(-1, -1.04, .7)
  v(1, -1.04, .7)
  'top of trunk
  c
  glNormal3f 0, 0, 1
  v(-1, -.7, .6)
  v(1,  -.7, .6)
  v(1,  -1,  .6)
  v(-1, -1,  .6)
  'rear window
  c2(.8, .8, 1)
  glNormal3f 0, -1, 0
  v(1,  -.5, 1)
  v(-1, -.5, 1)
  v(-1, -.7,  .6)
  v(1,  -.7,  .6)
  'roof
  c
  glNormal3f 0, 0, 1
  v(-1, -.5, 1)
  v(1,  -.5, 1)
  v(1,  .25,  1)
  v(-1, .25,  1)
  'windshield
  c2(.8, .8, 1)
  glNormal3f 0, 1, 0
  v(1,  .25, 1)
  v(-1, .25, 1)
  v(-1, .6,  .6)
  v(1,  .6,  .6)
  'hood
  c
  glNormal3f 0, 0, 1
  v(-1, .6, .6)
  v(1,  .6, .6)
  v(1,  1,  .6)
  v(-1, 1,  .6)
  'front bumper
  c
  glNormal3f 0, 1, 0
  v(1,  1,  .6)
  v(-1, 1,  .6)
  v(-1, 1,  .3)
  v(1,  1,  .3)
  'front license plate
  c2(0, 1, 0)
  glNormal3f 0, 1, 0
  v(.4,  1.1, .53)
  v(-.4, 1.1, .53)
  v(-.4, 1.1, .37)
  v(.4,  1.1, .37)
  
  'left side
  c2(1, 0, 0)
  glNormal3f -1, 0, 0
  v(-1, -1, .6)
  v(-1, -1, .3)
  v(-1, 1,  .3)
  v(-1, 1,  .6)
  c2(1, 1, 0)
  glNormal3f -1, 0, 0
  v(-1, -.5, 1)
  v(-1, -.7, .6)
  v(-1, .6,  .6)
  v(-1, .25,  1)
  
  'right side
  c2(1, 0, 0)
  glNormal3f 1, 0, 0
  v(1, -1, .6)
  v(1, -1, .3)
  v(1, 1,  .3)
  v(1, 1,  .6)
  c2(1, 1, 0)
  glNormal3f 1, 0, 0
  v(1, -.5, 1)
  v(1, -.7, .6)
  v(1, .6,  .6)
  v(1, .25,  1)
  
  'front left wheel
  c2(.5, 1, .5)
  glNormal3f -1, 0, 0
  v(-1, .59, .1)
  v(-1, .65, 0)
  v(-1, .7, 0)
  v(-1, .76, .1)
  c2(.5, 1, .5)
  glNormal3f -1, 0, 0
  v(-1, .55, .3)
  v(-1, .59, .1)
  v(-1, .76, .1)
  v(-1, .8, .3)
  'front right wheel
  c2(.5, 1, .5)
  glNormal3f 1, 0, 0
  v(1, .59, .1)
  v(1, .65, 0)
  v(1, .7, 0)
  v(1, .76, .1)
  c2(.5, 1, .5)
  glNormal3f 1, 0, 0
  v(1, .55, .3)
  v(1, .59, .1)
  v(1, .76, .1)
  v(1, .8, .3)
  'rear left wheel
  c2(.5, 1, .5)
  glNormal3f -1, 0, 0
  v(-1, -.59, .1)
  v(-1, -.65, 0)
  v(-1, -.7, 0)
  v(-1, -.76, .1)
  c2(.5, 1, .5)
  glNormal3f -1, 0, 0
  v(-1, -.55, .3)
  v(-1, -.59, .1)
  v(-1, -.76, .1)
  v(-1, -.8, .3)
  'rear right wheel
  c2(.5, 1, .5)
  glNormal3f 1, 0, 0
  v(1, -.59, .1)
  v(1, -.65, 0)
  v(1, -.7, 0)
  v(1, -.76, .1)
  c2(.5, 1, .5)
  glNormal3f 1, 0, 0
  v(1, -.55, .3)
  v(1, -.59, .1)
  v(1, -.76, .1)
  v(1, -.8, .3)
End Sub

Sub go
  'Dim As Double angle
  
  'coords are set for bird's eye view
  'top left of map is at (0, 0, 0)
  'all parts of map are 1un cubed
  
  glClear GL_DEPTH_BUFFER_BIT Or GL_COLOR_BUFFER_BIT
  glLoadIdentity

  With player
    .v.x *= .95
    .v.y *= .95
    If Multikey(fb.sc_left) Then .angle += .06
    If Multikey(fb.sc_right) Then .angle -= .06
    If Multikey(fb.sc_up) Then
      .v.x += Cos(.angle) * .02
      .v.y += Sin(.angle) * .02
    End If
    
    .p.x += .v.x
    If .p.x < -mapsize Then .p.x = -mapsize
    If .p.x > mapsize Then .p.x = mapsize
    .p.y += .v.y
    If .p.y < -mapsize Then .p.y = -mapsize
    If .p.y > mapsize Then .p.y = mapsize
  End With
  
  For a As Integer = 1 To car_max Step 2
    car(a) += .1
    If car(a) > mapsize + 1 And Rnd < .1 Then car(a) = -mapsize - 1
    car(a + 1) -= .1
    If car(a + 1) < -mapsize - 1 And Rnd < .1 Then car(a + 1) = mapsize + 1
  Next a
  
  With camera
    If Multikey(&H39) Then
      .eye(1) = player.p.x
      .eye(2) = player.p.y
      .eye(3) = mapsize * 1.4
      .see(1) = player.p.x
      .see(2) = player.p.y
      .see(3) = 0
      .up(1) = 0
      .up(2) = 1
      .up(3) = 0
    Else
      .eye(1) = player.p.x
      .eye(2) = player.p.y
      .eye(3) = .4
      .see(1) = player.p.x + Cos(player.angle) * 4
      .see(2) = player.p.y + Sin(player.angle) * 4
      .see(3) = .4
      .up(1) = 0
      .up(2) = 0
      .up(3) = 1
    End If
    
    gluLookat .eye(1), .eye(2), .eye(3), .see(1), .see(2), .see(3), .up(1), .up(2), .up(3)
    
    LightPosition(0) = player.p.x
    LightPosition(1) = player.p.y
    LightPosition(2) = mapsize
    glLightfv GL_LIGHT1, GL_POSITION, @LightPosition(0)
  End With
  
  glBegin GL_QUADS
    'ground
    glColor3d .4, .2, 0
    glNormal3f 0, 0, 1
    glVertex3d -mapsize, -mapsize, 0
    glVertex3d mapsize,  -mapsize, 0
    glVertex3d mapsize,  mapsize,  0
    glVertex3d -mapsize, mapsize,  0
    'edge north
    glColor3d .5, 1, .5
    glNormal3f 0, 0, 1
    glVertex3d -mapsize, mapsize, 0
    glVertex3d -mapsize, mapsize * 1.4, 2
    glVertex3d mapsize, mapsize * 1.4, 2
    glVertex3d mapsize, mapsize, 0
    'edge south
    glColor3d .5, 1, .5
    glNormal3f 0, 0, 1
    glVertex3d -mapsize, -mapsize, 0
    glVertex3d -mapsize, -mapsize * 1.4, 2
    glVertex3d mapsize, -mapsize * 1.4, 2
    glVertex3d mapsize, -mapsize, 0
    'edge east
    glColor3d .5, 1, .5
    glNormal3f 0, 0, 1
    glVertex3d mapsize, -mapsize, 0
    glVertex3d mapsize * 1.4, -mapsize, 2
    glVertex3d mapsize * 1.4, mapsize, 2
    glVertex3d mapsize, mapsize, 0
    'edge west
    glColor3d .5, 1, .5
    glNormal3f 0, 0, 1
    glVertex3d -mapsize, -mapsize, 0
    glVertex3d -mapsize * 1.4, -mapsize, 2
    glVertex3d -mapsize * 1.4, mapsize, 2
    glVertex3d -mapsize, mapsize, 0
    
    With player
      If Multikey(&H39) Then show_car .p.x, .p.y, .angle
    End With
    
    For a As Integer = 1 To car_max Step 2
      show_car car(a), .5, 0
      show_car car(a + 1), -.5, pi
    Next a
  glEnd
  
  glBegin GL_TRIANGLES
    'trees
    For a As Integer = 1 To tree_max
      With tree(a)
        glColor3d .2, 1, .2
        glNormal3f -1, 0, 0
        glVertex3d .x,      .y,      1
        glVertex3d .x - .1, .y - .1, 0
        glVertex3d .x - .1, .y + .1, 0
        
        glColor3d .2, 1, .2
        glNormal3f 1, 0, 0
        glVertex3d .x,      .y,      1
        glVertex3d .x + .1, .y - .1, 0
        glVertex3d .x + .1, .y + .1, 0
        
        glColor3d .2, 1, .2
        glNormal3f 0, -1, 0
        glVertex3d .x,      .y,      1
        glVertex3d .x - .1, .y - .1, 0
        glVertex3d .x + .1, .y - .1, 0
        
        glColor3d .2, 1, .2
        glNormal3f 0, 1, 0
        glVertex3d .x,      .y,      1
        glVertex3d .x - .1, .y + .1, 0
        glVertex3d .x + .1, .y + .1, 0
      End With
    Next a
  glEnd
  
  Flip
End Sub

Sub main
  start
  Do
    go
    Sleep 10
    key = Inkey
  Loop Until key = Chr(27)
End Sub

main
Maybe I should do real modeling now. :-P xD
phycowelder
Posts: 74
Joined: Dec 19, 2007 6:55

Post by phycowelder »

Very impressed! i like! ive been trying to learn GL! and i think i can do some more learning with these examples!

Nice Work!
nkk_kan
Posts: 209
Joined: May 18, 2007 13:01
Location: India
Contact:

Post by nkk_kan »

gee..that's cool!
those 3d images intimidate me XD
certainly, it's worth learning openGL for this.
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Post by KristopherWindsor »

Thanks! If you can't beat them (OpenGL programmers), join them! :-)

These weren't too hard to write; you just need to understand the concept of 3D, and visually imagine / conceptualize it.
Essentially you just need 4 3D coords (since I use GL_QUADS) to draw each polygon.

I was playing with some code that loads bitmaps to GL texture, and - why is Metaknight in the windshield??? :-P xD

Image
integer
Posts: 408
Joined: Feb 01, 2007 16:54
Location: usa

Post by integer »

Those are impressive!
Cool & neat.

The CarShow is most meaningful.
because...

The local elementary school 6th grade science class students are creating
models of atoms -- made of clay. The nucleus, protons & neutrons, are lumps of clay rolled into balls. Some students have the clay spheres about the size of BB's and others have them about table-tennis ball size.
Obviously, they didn't all read the same quantum physics book!

Several of us adult volunteers made the observation that a computer generated image showing several protons/neutrons clumped together and rotating, MIGHT be as instructive/entertaining as the clay models.

Unfortunately, none of us are imaging/graphic programmers.
I have searched the forum, the internet, etc., and have found an enormous amount of information -- over whelming & over my head. The open gl tutorial seems to be the best, but Simply put -- I do not know where to start.

The rotating car -- WOW!
This really opens the door. I need to lean gl.

However, in the short term (short-cut) how could your car be replaced with
several spheres (neutrons,protons, two to eight clumped together) in the 3d view?
bfuller
Posts: 362
Joined: Jun 02, 2007 12:35
Location: Sydney, Australia

Post by bfuller »

I just played with OpenGL for the first time--its fun.

For your atoms, go have a look in the GL folder of the examples. Lesson 26 in NeHe is probably most useful for you I would think.
h4tt3n
Posts: 698
Joined: Oct 22, 2005 21:12
Location: Denmark

Post by h4tt3n »

integer wrote: However, in the short term (short-cut) how could your car be replaced with
several spheres (neutrons,protons, two to eight clumped together) in the 3d view?
Spheres are easy to make with the openGL utility library, also called glu.

I'll hack something together for you today.

*** Edit ***

Here is an example with a scientific touch to it. It's originally a demo by Dr_D that I've spiced up. If you want your atoms to move around I wouldn't mind helping you out setting up an atomic physics simulation.

Code: Select all

''Simulation of a solar system with gravitational attraction

Randomize Timer 

#include "GL/gl.bi" 
#include "GL/glu.bi"

Type Vector_3D 
  As Single X, Y, Z
End Type 

Type EntityType 
  As Vector_3D LookAt, DVector, UVector, RVector, acc, Vel, pos
  As Single Mass, GM, Density, Radius, Col(3), Emission(3)  
End Type 

Declare Sub Vector_Normalize (v As Vector_3D) 
Declare Sub Rot_X(Entity As EntityType, Angle As Single) 
Declare Sub Rot_Y(Entity As EntityType, Angle As Single) 
Declare Sub Rot_Z(Entity As EntityType, Angle As Single) 
Declare Function Vector_Cross (v1 As Vector_3D, v2 As Vector_3D) As Vector_3D
Declare Function Vector_Magnitude(V As Vector_3D) As Single 

Const Pi = 4*atn(1), twopi = 2*pi, Spec_Grav = 6.6742e-11, Timestep = 0.01
Dim As Integer i, i2, Button, TempX, TempY, Scrn_Wid, Scrn_Hgt, Cam_Speed, MidX, MidY
Dim as Single Distance, Dist_sqared, Dist_Cubed, Dist_Min, Spawn_Angle, Spawn_Dist, Light_pos(3)
Dim as EntityType Cam, Body(1 To 100)
Dim As Vector_3D Factor, Dist

'Initialize the camera's vectors for a right-handed system,
'and give it an initial Pos...
Cam.Pos.X = 0
Cam.Pos.Y = 0
Cam.Pos.Z = 10000

Cam.DVector.X = 0
Cam.DVector.Y = -1
Cam.DVector.Z = 0

Cam.UVector.X = 0
Cam.UVector.Y = -1
Cam.UVector.Z = 0

Cam.RVector.X = 0
Cam.RVector.Y = 0
Cam.RVector.Z = 1

Cam_Speed = 100

Light_pos(0) = 0 
Light_pos(1) = 0 
Light_pos(2) = 0 
Light_pos(3) = 1

''  The Sun
With Body(1)
  .Mass = 1e20
  .GM = .Mass * Spec_Grav
  .Density = 1e11
  .Radius = (((.Mass/.Density)/((4/3)*pi))^(1/3))
  .Col(0) = 1 
  .Col(1) = 1
  .Col(2) = 1
  .Col(3) = 1 
  .Emission(0)= 1 
  .Emission(1)= 1 
  .Emission(2)= 1
  .Emission(3)= 1 
End With

For i = 2 To Ubound(Body)
  With Body(i)
    Spawn_Angle = Rnd*Twopi
    Spawn_Dist = 12000 - (rnd*(10000)^(1/3))^3
    .Mass = 5e15 + (rnd*(95e15)^(1/6))^6
    .GM = .Mass * Spec_Grav
    .Density = 1e10
    .Radius = (((.Mass/.Density)/((4/3)*pi))^(1/3))
    .Pos.X = Body(1).Pos.X+Spawn_Dist*Sin(Spawn_Angle)
    .Pos.y = Body(1).Pos.y+Spawn_Dist*Cos(Spawn_Angle)    
    .Pos.z = Body(1).Pos.z+10-Rnd*20
    .Vel.X = Body(1).Vel.X+sqr(Body(1).GM/Spawn_Dist)*cos(Spawn_Angle)
    .Vel.y = Body(1).Vel.y+sqr(Body(1).GM/Spawn_Dist)*sin(-Spawn_Angle) 
    .Col(0) = 0.2+Rnd*0.8
    .Col(1) = 0.2+Rnd*0.8
    .Col(2) = 0.2+Rnd*0.8
    .Col(3) = 1                
  End With
Next 

ScreenInfo Scrn_Wid, Scrn_Hgt
ScreenRes Scrn_Wid, Scrn_Hgt, 16,, 1 or &h2
MidX = Scrn_Wid\2
MidY = Scrn_Hgt\2

glViewport 0, 0, Scrn_Wid, Scrn_Hgt
glMatrixMode GL_PROJECTION 
glLoadIdentity 
gluPerspective 60.0, Scrn_Wid/Scrn_Hgt, 25, 1000000
glMatrixMode GL_MODELVIEW 
glLoadIdentity 

glShadeModel GL_SMOOTH
glEnable(GL_CULL_FACE)
glCullFace(GL_BACK)
glClearColor 0.0, 0.0, 0.0, 1.0 
glClearDepth 1.0 
glEnable GL_DEPTH_TEST 
glEnable GL_COLOR_MATERIAL 
glEnable Gl_LIGHTING 
glEnable GL_LIGHT0 
glDepthFunc GL_LEQUAL 
glHint GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST 

Dim As GLUquadricObj Ptr Sphere
Sphere = gluNewQuadric 

Do 
  glClear GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT 
  
  Getmouse(TempX, TempY,, Button) 
  Factor.Y = (MidX-TempX)/500
  Factor.X = (MidY-TempY)/500
  If Button And 1 Then 
    Factor.Z = .01 
  Elseif Button And 2 Then 
    Factor.Z = -.01 
  Else 
    Factor.Z = 0 
  End If    
  SetMouse(MidX, MidY, 0) 
  
  Rot_X Cam, Factor.X 
  Rot_Y Cam, Factor.Y 
  Rot_Z Cam, Factor.Z 
  
  If Multikey(&h11) Then 
    Cam.pos.X += Cam.DVector.X*Cam_Speed
    Cam.pos.Y += Cam.DVector.Y*Cam_Speed 
    Cam.pos.Z += Cam.DVector.Z*Cam_Speed
  End If 
  If Multikey(&h1F) Then 
    Cam.pos.X -= Cam.DVector.X*Cam_Speed
    Cam.pos.Y -= Cam.DVector.Y*Cam_Speed 
    Cam.pos.Z -= Cam.DVector.Z*Cam_Speed
  End If 
  If Multikey(&h20) Then 
    Cam.pos.X += Cam.RVector.X*Cam_Speed
    Cam.pos.Y += Cam.RVector.Y*Cam_Speed
    Cam.pos.Z += Cam.RVector.Z*Cam_Speed
  End If 
  If Multikey(&h1E) Then 
    Cam.pos.X -= Cam.RVector.X*Cam_Speed
    Cam.pos.Y -= Cam.RVector.Y*Cam_Speed
    Cam.pos.Z -= Cam.RVector.Z*Cam_Speed
  End If 
  
  glMatrixMode GL_MODELVIEW 
  glLoadIdentity 
  
  Cam.LookAt.X = Cam.Pos.X + Cam.DVector.X 
  Cam.LookAt.Y = Cam.Pos.Y + Cam.DVector.Y 
  Cam.LookAt.Z = Cam.Pos.Z + Cam.DVector.Z 
  
  gluLookAt Cam.Pos.X, Cam.Pos.Y, Cam.Pos.Z, _ 
  Cam.LookAt.X, Cam.LookAt.Y, Cam.LookAt.Z, _ 
  Cam.UVector.X, Cam.UVector.Y, Cam.UVector.Z 
  
  Light_pos(0) = Body(1).Pos.X
  Light_pos(1) = Body(1).Pos.Y 
  Light_pos(2) = Body(1).Pos.Z 
  
  glLightfv GL_LIGHT0, GL_Position, @Light_pos(0) 
  
  For i = Lbound(Body) to Ubound(Body)-1
    For i2 = i+1 To Ubound(Body)
      Dist.X = Body(i).Pos.X-Body(i2).Pos.X
      Dist.Y = Body(i).Pos.Y-Body(i2).Pos.Y
      Dist.Z = Body(i).Pos.Z-Body(i2).Pos.Z
      Dist_sqared = Dist.X*Dist.X+Dist.Y*Dist.Y+Dist.Z*Dist.Z
      Distance = sqr(Dist_Sqared)
      Dist_Cubed = Distance*Dist_sqared
      Dist_Min = Body(i).Radius+Body(i2).Radius
      If Distance < Dist_Min then dist_cubed = dist_min*dist_min*dist_min
      
      Body(i).acc.X -= Body(i2).GM*Dist.X/Dist_Cubed
      Body(i).acc.Y -= Body(i2).GM*Dist.Y/Dist_Cubed
      Body(i).acc.Z -= Body(i2).GM*Dist.Z/Dist_Cubed
      
      Body(i2).acc.X += Body(i).GM*Dist.X/Dist_Cubed
      Body(i2).acc.Y += Body(i).GM*Dist.Y/Dist_Cubed
      Body(i2).acc.Z += Body(i).GM*Dist.Z/Dist_Cubed
    Next
  Next

  For i = Lbound(Body) to Ubound(Body)
    
    With Body(i)
      
      .Vel.X += .Acc.X*Timestep
      .Vel.Y += .Acc.Y*Timestep
      .Vel.Z += .Acc.Z*Timestep
      
      .Pos.X += .Vel.X*Timestep
      .Pos.Y += .Vel.Y*Timestep
      .Pos.Z += .Vel.Z*Timestep
      
      .acc.X = 0
      .acc.y = 0
      .acc.z = 0
      
      glPushMatrix           
      glTranslatef .Pos.X, .Pos.y, .Pos.Z 
      glColor4fV @.Col(0) 
      glMaterialfv GL_FRONT, GL_EMISSION, @.Emission(0) 
      gluSphere Sphere, .Radius, 16, 16
      glPopMatrix 
      
    End With
    
  Next 
  
  glflush
  Flip 
  
  Sleep 1, 1
  
Loop until multikey(1)

gluDeleteQuadric Sphere 

End


'*******************************************************************************


Function Vector_Cross (v1 As Vector_3D, v2 As Vector_3D) As Vector_3D
    Dim v As Vector_3D
    v.x = (v1.y * v2.z) - (v2.y * v1.z)
    v.y = (v1.z * v2.x) - (v2.z * v1.x)
    v.z = (v1.x * v2.y) - (v2.x * v1.y)
    Return v
End Function

Function Vector_Magnitude(V As Vector_3D) As Single 
    Dim As Single _
    Mag_sqr = v.x*v.x+v.y*v.y+v.z*v.z, _
    Mag = Sqr(mag_sqr)
    If Mag = 0 Then Mag = 1 
    Vector_Magnitude = Mag 
End Function 

Sub Vector_Normalize (v As Vector_3D) 
    Dim Mag As Single 
    Mag = Vector_Magnitude(V)    
    v.x = v.x / Mag 
    v.y = v.y / Mag 
    v.z = v.z / Mag 
End Sub 

Sub Rot_X(Entity As EntityType, Angle As Single) 
    Dim tDir As Vector_3D, tSin As Single, tCos As Single
    
    tCos = Cos(Angle)
    tSin = Sin(Angle)
    
    tDir.X = Entity.DVector.X*tCOS+Entity.UVector.X*tSin
    tDir.Y = Entity.DVector.Y*tCOS+Entity.UVector.Y*tSin
    tDir.Z = Entity.DVector.Z*tCOS+Entity.UVector.Z*tSin
    
    Vector_Normalize tDir
    
    Entity.DVector.X = tDir.X 
    Entity.DVector.Y = tDir.Y 
    Entity.DVector.Z = tDir.Z    
    
    Entity.UVector = Vector_Cross( Entity.DVector, Entity.RVector )
    
    Entity.UVector.X =-Entity.UVector.X
    Entity.UVector.Y =-Entity.UVector.Y
    Entity.UVector.Z =-Entity.UVector.Z
End Sub 

Sub Rot_Y(Entity As EntityType, Angle As Single) 
    Dim tDir As Vector_3D, tCos As Single, tSin As Single 
    
    tCos = Cos(Angle)
    tSin = Sin(Angle)
    
    tDir.X = Entity.DVector.X*tCOS-Entity.RVector.X*tSin
    tDir.Y = Entity.DVector.Y*tCOS-Entity.RVector.Y*tSin
    tDir.Z = Entity.DVector.Z*tCOS-Entity.RVector.Z*tSin
    
    Vector_Normalize tDir 
    
    Entity.DVector.X = tDir.X
    Entity.DVector.Y = tDir.Y
    Entity.DVector.Z = tDir.Z

    Entity.RVector = Vector_Cross( Entity.DVector, Entity.UVector )
End Sub 

Sub Rot_Z(Entity As EntityType, Angle As Single) 
    Dim tRight As Vector_3D, tCos As Single, tSin As Single 
    tCos = Cos(Angle) 
    tSin = Sin(Angle) 
    
    tRight.X = Entity.RVector.X*tCOS+Entity.UVector.X*tSin
    tRight.Y = Entity.RVector.Y*tCOS+Entity.UVector.Y*tSin
    tRight.Z = Entity.RVector.Z*tCOS+Entity.UVector.Z*tSin
    
    Vector_Normalize tRight

    Entity.RVector.X = tRight.X 
    Entity.RVector.Y = tRight.Y 
    Entity.RVector.Z = tRight.Z 
    
    Entity.UVector = Vector_Cross( Entity.DVector, Entity.RVector )
    Entity.UVector.X =-Entity.UVector.X 
    Entity.UVector.Y =-Entity.UVector.Y 
    Entity.UVector.Z =-Entity.UVector.Z 
End Sub
Cheers, Michael
integer
Posts: 408
Joined: Feb 01, 2007 16:54
Location: usa

Post by integer »

@h4tt3n

That looks great! I am impressed.

I looked at the code. However, at this stage of understanding what is going on, I am overwhelmed with the vast amount of information. I do not grasp what parts are generating which results.

At the moment, there would be no requirement for factual or actual graphics for atomic/molecular movement. You have to remember, the students are sixth graders, and only one of 58 has an idea of what the word calculus means. This phase of the science class will end during the last week of this month (February).

I am using super glue and marbles to create the visual aid.
A computer generated model would be a vast improvement.
If you have the time and can help it would be greatly appreciated.
What I really need help with is an example of how to create two spheres, how to "glue" then together, and how to rotate them to view as 3D objects.

Thanks.
bfuller
Posts: 362
Joined: Jun 02, 2007 12:35
Location: Sydney, Australia

Post by bfuller »

OK, after a lot of experimentation, I hacked the Car demo by replacing the contents of the "show car" Subroutine with some code that draws two spheres. Not pretty, but it works.

Code: Select all

' Atom Show OpenGL Demo! v0.1
' (C) 2008 Innova and Kristopher Windsor
'hacked by Brad Fuller

#include "GL/gl.bi"
#include "GL/glu.bi"

Const screenx = 640, screeny = 480
Const true = -1, false = 0, pihalf = Atn(1) * 2


Type camera_type
  As Double eye(1 To 3)
  As Double see(1 To 3)
  As Double up(1 To 3)
End Type

Type coord_type
  As Double x, y
End Type

Dim Shared LightDiffuse(0 To 3) As Single => {3, 3, 3, 1}
Dim Shared LightPosition(0 To 3) As Single => {0, 0, 0, 1}
Dim Shared As String Key
Dim Shared As camera_type camera

Sub start
  Screenres screenx, screeny, 32,, 2
  
  glMatrixMode GL_PROJECTION
  glLoadIdentity
  gluPerspective 35.0, screenx / screeny, .01, 8
  glMatrixMode GL_MODELVIEW
  glLoadIdentity
  
  glClearColor 0, 0, 0, 1
  glEnable GL_DEPTH_TEST 'properly handles overlapping polygons (draw order for layering)
  
  glEnable GL_LIGHT1
  glLightfv GL_LIGHT1, GL_DIFFUSE, @LightDiffuse(0)
  glEnable GL_LIGHTING
  glEnable GL_COLOR_MATERIAL
  
  Randomize Timer
End Sub

Sub show_car (Byval x As Double, Byval y As Double, Byval spin As Double)
            '' Draw two spheres instead of the car
            
	dim as GLUquadricObj ptr q                                  '' Quadratic For Drawing A Sphere

    q = gluNewQuadric()                          '' Initialize Quadratic
        glColor3b(127,0,0)                      ''set colour red
        gluSphere(q, 0.3, 32, 16)                         '' Draw A Sphere
		glColor3b(0,127,0)                      ''set colour green
        glTranslatef(0, -0.3, 0)                '' move the position
        gluSphere(q, 0.3, 32, 16)                         '' Draw A second Sphere


End Sub

Sub go
  Dim As Double angle
  
  'coords are set for bird's eye view
  'top left of map is at (0, 0, 0)
  'all parts of map are 1un cubed
  
  glClear GL_DEPTH_BUFFER_BIT Or GL_COLOR_BUFFER_BIT
  glLoadIdentity

  LightPosition(0) = 0
  LightPosition(1) = 0
  LightPosition(2) = -1
  glLightfv GL_LIGHT1, GL_POSITION, @LightPosition(0)
  
  angle = -Timer * .4
  With camera
    .eye(1) = Cos(angle) * 3
    .eye(2) = Sin(angle) * 3
    .eye(3) = .8
    .see(1) = 0
    .see(2) = 0
    .see(3) = .4
    .up(1) = 0
    .up(2) = 0
    .up(3) = 1
    
    gluLookat .eye(1), .eye(2), .eye(3), .see(1), .see(2), .see(3), .up(1), .up(2), .up(3)
  End With
  
  glBegin GL_QUADS
    'ground
    glColor3d .4, .2, 0
    glNormal3f 0, 0, 1
    glVertex3d -1, -1, 0
    glVertex3d 1,  -1, 0
    glVertex3d 1,  1,  0
    glVertex3d -1, 1,  0
    
    show_car 0, 0, 0
  glEnd
  
  Flip
End Sub

Sub main
  start
  Do
    go
    Sleep 10
    Key = Inkey
  Loop Until Key = Chr(27)
End Sub

main
 
At least you can see how the spheres are drawn--there is probably a better way to do it. I would not have a clue how to add electrons orbiting!
KristopherWindsor
Posts: 2428
Joined: Jul 19, 2006 19:17
Location: Sunnyvale, CA
Contact:

Post by KristopherWindsor »

bfuller wrote:OK, after a lot of experimentation, I hacked the Car demo by replacing the contents of the "show car" Subroutine with some code that draws two spheres. Not pretty, but it works.
Ha, I didn't know there was a built-in method for drawing spheres.
Fortunately, I didn't try to make them from polygons yet. xD

If you just want to display a few spheres, you can position and draw them manually without attaching them into an object or linking them. ;-)
integer
Posts: 408
Joined: Feb 01, 2007 16:54
Location: usa

Post by integer »

@ bfuller
after a lot of experimentation ... some code that draws two spheres. Not pretty, but it works.
At least you can see how the spheres are drawn--there is probably a better way to do it.

I would not have a clue how to add electrons orbiting!

from my view: it is beautiful.

There is no need for electron orbits. At the proton/electron scale the charged particles (electrons) no longer follow a smooth elliptical orbit -- and the relative sizes,... etc.
It isn't needed/wanted.

The modifications clarify some of my problems in understanding the manual.
I have done a lot of trial+error experimentation and still can't get the simple pieces to work.
The GLUT book might as well have been written in hieroglyphics, since I do not understand the functional basics. Your demo helps.

Thanks



@KristopherWindsor
If you just want to display a few spheres, you can position and draw them manually without attaching them into an object or linking them.
That is exactly what I'm trying to do, but finding the doorway is at this point very difficult.
It's as if I am at the side of the house searching for the door that is not there.

Any SIMPLE example demo will help me get to the door.
I like what you have done.

Thanks.
Post Reply