[Home] [Downloads] [Search] [Help/forum]

Gammon Software Solutions forum

See www.mushclient.com/spam for dealing with forum spam. Please read the MUSHclient FAQ!

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Miniwindows
. . -> [Subject]  Miniwindows showcase (has a lot of graphics)

Home  |  Users  |  Search  |  FAQ
Username:
Register forum user name
Password:
Forgotten password?
(New message)
Subject: Miniwindows showcase (has a lot of graphics)
Name:
Your forum user name.
Register forum user name
Password:
Your forum password.
Forgotten password?
Message:
Message to be posted (in English, please).
Forum codes:
Check this if your message uses 'forum codes' or templates (auto-detected for new posts).
Forum codes Templates

Save this message ...


Subject review (reverse sequence)

Pages: 1 2  

Posted by Nick Gammon   Australia  (18,772 posts)  [Biography] bio   Forum Administrator
Date Sun 06 Jun 2010 05:37 AM (UTC)  quote  ]

Amended on Sun 06 Jun 2010 06:01 AM (UTC) by Nick Gammon

Message

I think I got a lot of inspiration from here:

http://www.student.kuleuven.be/~m0216922/CG/raycasting.html

and:

http://www.student.kuleuven.be/~m0216922/CG/raycasting2.html

I think you can also download the graphics files (textures) from that page too.


- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (18,772 posts)  [Biography] bio   Forum Administrator
Date Sat 05 Jun 2010 11:13 PM (UTC)  quote  ]
Message
The image files are basically 64 x 64 pixel 24 bits-per-pixel bitmap (bmp) files, so any file along those lines should be OK if you want to try to run it.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (18,772 posts)  [Biography] bio   Forum Administrator
Date Sat 05 Jun 2010 10:58 PM (UTC)  quote  ]
Message


- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (18,772 posts)  [Biography] bio   Forum Administrator
Date Sat 05 Jun 2010 10:54 PM (UTC)  quote  ]

Amended on Sat 05 Jun 2010 11:11 PM (UTC) by Nick Gammon

Message
I can't get the 3D mapper to work right now (mainly because of the horrible way I was getting the mapping data into it), but this snippet (which you can run in the Immediate window) actually draws one 3D scene which a constant at the start of it. To try it out you need the texture files, which I don't want to supply because I'm not sure of the copyright. But it shows the general idea.


-- 3D mapper test 
-- Written by Nick Gammon 
-- Date: August 2008

-- test map

map = [==[
         ---     ---        
        |{+} {!} {+}|     
     -------     ---|        
    +{+} {+} {+} {+>|     
     -------     ---         
         [?] <!> [?]      
                 ---         
         [?] <#> < . [?]  
                 ---         
         [?] < > [?]      
     -------     -------     
     - - -!- < > -*- - -  
     -------     -------     
            |. .|    
          
            
                   
]==]


local mapWidth = 80
local mapHeight = 80

local texWidth = 64
local texHeight = 64

posX = 35; posY = 35;  --x and y start position
dirX = 0; dirY = -1; --initial direction vector
planeX = -0.7853; planeY = 0; --the 2d raycaster version of camera plane

HEIGHT_MULTIPLIER = 4

dir = "/Program Files/mushclient/"
  
require "tprint"
require "getlines"


-- make local for speed

local floor = math.floor
local ceil = math.ceil
local abs =  math.abs
local sqrt =  math.sqrt
local cos = math.cos
local sin = math.sin

local WindowLine = WindowLine

local function int (x)
  if x >= 0 then
    return floor (x)
  end  -- if positive

  return ceil (x)
end -- function int

function setup_map_window ()
  

  WINDOW_HEIGHT = 300
  WINDOW_WIDTH = 400 -- 320
  
  win = "3d"
  wins = "3dshadow"
  
  -- how many pixels per tile
  
  tilewidth = WINDOW_WIDTH / mapWidth
  tileheight = WINDOW_HEIGHT / mapHeight
  
  WindowCreate (win, 
    0, -- left
    0, -- top
    WINDOW_WIDTH, -- width
    WINDOW_HEIGHT, -- height
    8, -- mode
    0, -- flags
    0x383838)
  
  WindowCreate (wins, 
    0, -- left
    0, -- top
    WINDOW_WIDTH, -- width
    WINDOW_HEIGHT, -- height
    8, -- mode
    0, -- flags
    0xFFFFFF)
        
  WindowShow (win, true)
  
  local pencolour = 0x555555
  local centre = WINDOW_HEIGHT / 2
  
  -- sky
  WindowGradient (win, 0, 0, 0, centre, 
                  0xFFBF00,
                  ColourNameToRGB ("darkblue"), 
                  2)  -- top to bottom
  
  -- ground
  WindowGradient (win, 0, centre, 0, 0, 
          0x00091C, 
          ColourNameToRGB ("lightsalmon"), 
          2)  -- top to bottom
          
  -- noise        
  WindowFilter (win, 0, 0, 0, 0, 2, 15)
  
  WindowRectOp (win, 1,   -- frame rectangle
            0, 0, 
            0, 0, 
            0x00002F)
        
  images = {
      "eagle",        -- 1
      "redbrick",     -- 2
      "purplestone",  -- 3
      "greystone",    -- 4
      "bluestone",    -- 5
      "mossy",        -- 6
      "wood",         -- 7
      "colorstone",   -- 8
    }
  
  check (WindowLoadImage (win, "eagle", dir .. "eagle.bmp"))  
  check (WindowLoadImage (win, "redbrick", dir .. "redbrick.bmp"))
  check (WindowLoadImage (win, "purplestone", dir .. "purplestone.bmp"))
  check (WindowLoadImage (win, "greystone", dir .. "greystone.bmp"))
  check (WindowLoadImage (win, "bluestone", dir .. "bluestone.bmp"))
  check (WindowLoadImage (win, "mossy", dir .. "mossy.bmp"))
  check (WindowLoadImage (win, "wood", dir .. "wood.bmp"))
  check (WindowLoadImage (win, "colorstone", dir .. "colorstone.bmp"))
 
end -- setup_map_window

local colour_map = {
    [1] = ColourNameToRGB ("red"),
    [2] = ColourNameToRGB ("green"),
    [3] = ColourNameToRGB ("blue"),
    [4] = ColourNameToRGB ("white"),
    } -- end colour_map
    
        
local function hwall (wx, wy, which)
  for i = wx, wx + 9 do
    worldMap [i] [wy] = which
  end -- for
end -- hwall

local function vwall (wx, wy, which)
  for i = wy, wy + 9 do
    worldMap [wx] [i] = which
  end -- for
end -- hwall

    
function convert_map ()
  
  -- empty table
  maprooms = {}
  for x = 1, 8 do
    maprooms [x] = {}
  end -- for each x
  
  mapline = {}
  
  x = 1
  for line in getlines (map) do
    mapline [x] = line
    x = x + 1
  end -- for
  
  -- bleecccchh
  
  for x = 1, 8 do  
    for y = 1, 8 do
      local t = {}
      maprooms [x] [y] = t
      t.top = mapline [y * 2 - 1]:sub ((x - 1) * 4 + 1, (x - 1) * 4 + 5)
      t.middle = mapline [y * 2    ]:sub ((x - 1) * 4 + 1, (x - 1) * 4 + 5)
      t.bottom = mapline [y * 2 + 1]:sub ((x - 1) * 4 + 1, (x - 1) * 4 + 5)
    end -- each y
  end -- each x

  
  worldMap = {}
  
  for x = 1, mapWidth do
    local t = {}
    worldMap [x] = t
    for y = 1, mapHeight do
       t [y] = 0  -- nothing there yet
    end -- for
  end -- for
  
  for x = 1, 8 do  
    for y = 1, 8 do
      t = maprooms [x] [y]
      local wx = (x - 1) * 10 + 1
      local wy = (y - 1) * 10 + 1
     
      if t.top:sub (2, 3) == "--" then
        hwall (wx, wy, 4)
      end -- if
  
      if t.bottom:sub (2, 3) == "--" then
        hwall (wx, wy + 9, 4)
      end -- if

      if t.top:sub (2, 3) == "-+" then
        hwall (wx, wy, 2)
      end -- if

      if t.bottom:sub (2, 3) == "-+" then
        hwall (wx, wy, 2)
      end -- if

      if t.middle:sub (-1) == "|" then
        vwall (wx + 9, wy, 4)
      end -- if
      
      if t.middle:sub (1, 1) == "|" then
        vwall (wx, wy, 4)
      end -- if
       
      if t.middle == " [?] " then
        vwall (wx, wy, 7)
        vwall (wx + 9, wy, 7)
      end -- if
           
    end -- each y
  end -- each x  
     
end -- convert_map    

texture = {}
for x = 1, 64 do
  texture [x] = {}
  for y = 1, 64 do
    local c = bit.xor (x, y)
    texture [x] [y] = c + c * 0x000200 + x * 0x010000
  end -- for
end -- for

function Display_Map ()

  convert_map ()
  
  setup_map_window ()

  local w = WINDOW_WIDTH
  local h = WINDOW_HEIGHT
  
  for x = 0, w - 1 do
    --calculate ray position and direction 
   local cameraX = 2 * x / w - 1 --x-coordinate in camera space
   local rayPosX = posX
   local rayPosY = posY
   local rayDirX = dirX + planeX * cameraX
   local rayDirY = dirY + planeY * cameraX
    
  --which box of the map we're in  
  
   local mapX = int (rayPosX)
   local mapY = int (rayPosY)
     
    --length of ray from current position to next x or y-side
    local sideDistX
    local sideDistY
     
     --length of ray from one x or y-side to next x or y-side
    local deltaDistX = sqrt (1 + (rayDirY * rayDirY) / (rayDirX * rayDirX))
    local deltaDistY = sqrt (1 + (rayDirX * rayDirX) / (rayDirY * rayDirY))
    local perpWallDist
     
    --what direction to step in x or y-direction (either +1 or -1)
    local stepX
    local stepY

    local hit = false  --was there a wall hit?
    local YsideHit --was a NS or a EW wall hit?
    
    -- calculate step and initial sideDist
    
    if rayDirX < 0 then
      stepX = -1
      sideDistX = (rayPosX - mapX) * deltaDistX
    else
      stepX = 1
      sideDistX = (mapX + 1.0 - rayPosX) * deltaDistX
    end -- if
    
    if rayDirY < 0 then
      stepY = -1
      sideDistY = (rayPosY - mapY) * deltaDistY
    else
      stepY = 1
      sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY
    end -- if
        
   --perform DDA
   while not hit do
    
    --jump to next map square, OR in x-direction, OR in y-direction
    if sideDistX < sideDistY then
      sideDistX = sideDistX + deltaDistX
      mapX = int (mapX + stepX)
      YsideHit = false
    else
      sideDistY = sideDistY + deltaDistY
      mapY = int (mapY + stepY)
      YsideHit = true
    end -- if
    
    if mapX < 0 or 
       mapY < 0 or
       mapX > mapWidth or
       mapY > mapHeight then
       break
     end -- outside map
       
    if worldMap[mapX] == nil then
      break
    end -- if off map  
    
   if worldMap[mapX] [mapY] == nil then
      break
    end -- if off map  
    
    --Check if ray has hit a wall
    if worldMap[mapX][mapY] > 0 then
     hit = true
    end -- if hit
    
  end -- while 
  
 local wallX --where exactly the wall was hit
 local drawEnd
     
   --calculate value of wallX
    
    if YsideHit then
      wallX = rayPosX + ((mapY - rayPosY + (1 - stepY) / 2) / rayDirY) * rayDirX
    else       
      wallX = rayPosY + ((mapX - rayPosX + (1 - stepX) / 2) / rayDirX) * rayDirY
    end -- if 
    
    -- Calculate distance projected on camera direction (oblique distance will give fisheye effect!)
    
    if not YsideHit then
      perpWallDist = abs ((mapX - rayPosX + (1 - stepX) / 2) / rayDirX)
    else
      perpWallDist = abs ((mapY - rayPosY + (1 - stepY) / 2) / rayDirY)
    end -- if
 
      
    --Calculate height of line to draw on screen
    local lineHeight = int (abs  (h / perpWallDist) * HEIGHT_MULTIPLIER)
     
    --calculate lowest and highest pixel to fill in current stripe
    local drawStart = -lineHeight / 2 + h / 2
    if drawStart < 0 then
      drawStart = 0
    end -- if
    
    drawEnd = lineHeight / 2 + h / 2
    if drawEnd >= h then
      drawEnd = h - 1
    end -- if
    
   local adjwallX = wallX / 10
   adjwallX = adjwallX - floor((adjwallX))

   if hit then
 
      --texturing calculations
      local texNum = worldMap [mapX][mapY]
       
      --x coordinate on the texture
      local texX = int (adjwallX * texWidth)
      
      if (not YsideHit) and (rayDirX > 0) then
         texX = texWidth - texX - 1
      end -- if
       
      if YsideHit and (rayDirY < 0) then
       texX = texWidth - texX - 1
      end -- if
      
      check (WindowDrawImage(win, images [texNum], x + 1, drawStart , x + 2, drawEnd, 
             2, 
              texX, 0, texX + 1, 0))
          
      check (WindowFilter (win,  x + 1, drawStart , x + 2, drawEnd, 7, -perpWallDist * 4)) -- darken
      
      if x >  w / 2 then
        check (WindowFilter (win,  x + 1, drawStart , x + 2, drawEnd, 9, 1.4)) -- gamma (darken)
      else
        check (WindowFilter (win,  x + 1, drawStart , x + 2, drawEnd, 9, .8)) -- gamma (lighten)
      end -- if on RH side
               
   end -- of hit on wall
   
    --FLOOR CASTING

    local floorXWall, floorYWall -- x, y position of the floor texel at the bottom of the wall

    --4 different wall directions possible
    
    if not YsideHit and (rayDirX > 0) then
      floorXWall = mapX
      floorYWall = mapY + wallX
    elseif not YsideHit and (rayDirX < 0) then
      floorXWall = mapX + 1.0
      floorYWall = mapY + wallX
    elseif YsideHit and (rayDirY > 0) then
      floorXWall = mapX + wallX 
      floorYWall = mapY
    else
      floorXWall = mapX + wallX 
      floorYWall = mapY + 1.0
    end -- if
        
    local distWall, currentDist  

    distWall = perpWallDist
   
    if drawEnd < 0 then
      drawEnd = h -- becomes < 0 when the integer overflows
    end -- if
    
    --draw the floor from drawEnd to the bottom of the screen
    for y = int (drawEnd + 1), h do
      currentDist = h / (2 * y - h) -- you could make a small lookup table for this instead
      
      --floor
      WindowSetPixel (win, x, y, 0x0000FF / currentDist)
     
      -- ceiling (symmetrical!)
      WindowSetPixel (win, x, h- y, int (256 / currentDist) * 256)
      
    end -- for loop
         
    -- shadow
    
    if x > w / 2 then
      WindowLine(wins, x + 1, drawEnd , x - abs (drawStart - drawEnd), drawEnd, 0x777777, 0, 1)
    end -- if 
        
  end -- for each x
  
  WindowFilter(wins, 0, 0, 0, 0, 3, 0)
  WindowImageFromWindow (win, "shadows", wins)
  
  WindowBlendImage (win, "shadows", 4, 0, 0, 0, 6, 1)

end -- Display_Map

Display_Map ()



That's under 500 lines of Lua code to render a 3D window.

Below is the output as rendered by the above code.

That took 0.17 seconds to do the Display_Map part.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Twisol   USA  (2,229 posts)  [Biography] bio
Date Sat 05 Jun 2010 06:28 PM (UTC)  quote  ]
Message
Oh, of course. I'm just impressed that a 3D view could be done at all. ;)

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Nick Gammon   Australia  (18,772 posts)  [Biography] bio   Forum Administrator
Date Sat 05 Jun 2010 11:21 AM (UTC)  quote  ]

Amended on Sat 05 Jun 2010 11:22 AM (UTC) by Nick Gammon

Message
Let me tell you about the problems with the 3D view ...

When you initially look at it you think "Holy Guacamole! - that's amazing!" ... but after a little while you think "hey, this is the Jungle of Verume- it looks like a dungeon, not a jungle".

Then you go back to the City (Aylor) and it still looks the same, like a badly implemented version of Castle Wolfenstein.

http://en.wikipedia.org/wiki/Wolfenstein_3D

Then you start to think "it says there are 5 mobs in the room - well, where are they?" - so the 3D graphics actually lower the "suspension of disbelief" that is important to playing games.

You go into a shop, but you don't see a shopkeeper, or the things he sells. Now all this could be overcome to an extent with a lot of extra graphics and sprites, but then it starts to turn into a 3D graphical MMO and not a MUD game.

You hit problems with things like stairs leading down, or up, which are hard to represent. In fact in some rooms which have exits north, south, east, west, northeast, northwest, southeast, southwest, up *and* down, it is hard to work out a way of showing that in 3D.

So it looks good initially, and shows off what the miniwindows are capable of drawing, but as a MUD experience, it doesn't quite work, unfortunately.

This is one of the reasons why, in my more recent postings about improving MUD game retention rates, I have kept quiet about trying to do a 3D view.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (18,772 posts)  [Biography] bio   Forum Administrator
Date Sat 05 Jun 2010 10:19 AM (UTC)  quote  ]
Message
Ah yes, I wonder where I put it?

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Twisol   USA  (2,229 posts)  [Biography] bio
Date Sat 05 Jun 2010 10:10 AM (UTC)  quote  ]
Message
Nick Gammon said:

Twisol said:

I guess you effectively had to write the whole graphics pipeline there.


I don't know about that. The whole plugin was in Lua.


But I mean, you had to do the projection/transformation calculations yourself, I assume. You have a perspective view, and you have lighting (AND shadows). I'd be interested in seeing the source, even if just to boggle at.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Nick Gammon   Australia  (18,772 posts)  [Biography] bio   Forum Administrator
Date Sat 05 Jun 2010 10:06 AM (UTC)  quote  ]
Message
Twisol said:

I guess you effectively had to write the whole graphics pipeline there.


I don't know about that. The whole plugin was in Lua.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Twisol   USA  (2,229 posts)  [Biography] bio
Date Sat 05 Jun 2010 10:04 AM (UTC)  quote  ]

Amended on Sat 05 Jun 2010 10:07 AM (UTC) by Twisol

Message
One of the things I was thinking about while perusing the code a week ago was the possibility of an API to use the Direct3D library instead of GDI. I hear Windows 7 doesn't use hardware acceleration for GDI anymore. I think that would help a lot with things like this, because D3D handles the bulk of the math for you.

I'd rather break up the God Object (CMUSHClientDoc) [1], though, so that's just another of my long-term hopes...

[1] http://en.wikipedia.org/wiki/God_object

EDIT: Ah, it's actually Vista where GDI became non-accelerated. Earlier than I thought!

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Nick Gammon   Australia  (18,772 posts)  [Biography] bio   Forum Administrator
Date Sat 05 Jun 2010 10:02 AM (UTC)  quote  ]
Message
Twisol said:

I'm not much good at 3D maths, heh...


Me neither. That was part of the problem.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (18,772 posts)  [Biography] bio   Forum Administrator
Date Sat 05 Jun 2010 10:01 AM (UTC)  quote  ]
Message
Also in the same release:

Quote:

16. Added new script function BlendPixel - this does the same thing as WindowBlendImage, except it operates on a single pixel (that is, a single RGB colour for the blend colour, and a single RGB colour for the base colour). This does the same thing, to a single pixel, as WindowBlendImage (with the same codes). This is intended for situations where you need to work on individual colours - either in a miniwindow image, or generally, to do things like merge them together in various ways.


That's how I did the shadows.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Twisol   USA  (2,229 posts)  [Biography] bio
Date Sat 05 Jun 2010 10:01 AM (UTC)  quote  ]
Message
I guess you effectively had to write the whole graphics pipeline there. I'm not much good at 3D maths, heh... that's not something I'd readily undertake.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
[Go to top] top

Posted by Nick Gammon   Australia  (18,772 posts)  [Biography] bio   Forum Administrator
Date Sat 05 Jun 2010 09:58 AM (UTC)  quote  ]
Message
Check out the release notes for August 2008 (version 4.36):

http://www.gammon.com.au/scripts/showrelnote.php?version=4.36&productid=0

Quote:

6. Added new function WindowSetPixel - this lets you set individual pixel colours in a miniwindow.


Why else would I want you to be able to set individual pixels? 3D, ah yes!

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (18,772 posts)  [Biography] bio   Forum Administrator
Date Sat 05 Jun 2010 09:12 AM (UTC)  quote  ]
Message
Ah, about August 2008?

The thing is, I don't like releasing stuff until it works perfectly, and I wasn't happy with its overall effect. It worked fast enough, no problems there.

The whole thing was done with the released version of MUSHclient at the time, so anyone who wants to can do the same thing.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


6,859 views.

This is page 1, subject is 2 pages long: 1 2  [Next page]

[Reply to this subject]  Reply to this subject   [New subject]  Start a new subject   [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

[Home]

Written by Nick Gammon - 5K

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( http://www.gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Internet Contents Rating Association (ICRA) - 2K]    [Web site powered by FutureQuest.Net]