Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

RMVXA-GL - 3D graphics in RPG Maker!

Ryaryu

Member

I've been playing with it (and learning new OpenGL programing style haha), and was able to create normal mapping.
Next I'll try to expand it to every sprite in-screen...



I haven't cared for GL 2.1 so it probably won't work there.
 
Ryaryu":1bos4taz said:
I've been playing with it (and learning new OpenGL programing style haha), and was able to create normal mapping.
Next I'll try to expand it to every sprite in-screen...

http://i814.photobucket.com/albums/zz68/Arashin_Sieg/CapturadeTela2.png

I haven't cared for GL 2.1 so it probably won't work there.
You just made my day.

2.1 support still isn't figured out, so I might lock it to 3.0 frankly (Which opens up a lot of options).
 
看起来是个非常厉害的系统呢,连远在地球另一边的立华揍都跑过来了。
Seems to be a very powerful system, even as far as the other side of the globe Tachibana Kanade ran all over.
 
Thank you Allen2014.

Allen2014":2k7jh41t said:
连远在地球另一边的立华揍都跑过来了。
even as far as the other side of the globe Tachibana Kanade ran all over.
你的句子的最后一部分是混乱的。你能解释一下这句话?

The last part of your sentence is confusing. Can you explain this statement?
 
Xilef":2dpph11r said:
Thank you Allen2014.

Allen2014":2dpph11r said:
连远在地球另一边的立华揍都跑过来了。
even as far as the other side of the globe Tachibana Kanade ran all over.
你的句子的最后一部分是混乱的。你能解释一下这句话?

The last part of your sentence is confusing. Can you explain this statement?

我来自中国 我是通过一个传送门抵达这里的,我这里有一个彪悍的天使她两只手都装备了长刀……【不要在意这些细节
I come from China I is through a portal arrived here, here I have a tough Angel her two hands are equipped with long knives...... [don't care about these details
 
Xilef":1b702uky said:
Thank you Allen2014.

Allen2014":1b702uky said:
连远在地球另一边的立华揍都跑过来了。
even as far as the other side of the globe Tachibana Kanade ran all over.
你的句子的最后一部分是混乱的。你能解释一下这句话?

The last part of your sentence is confusing. Can you explain this statement?

Just call me Allen
BTW:
I have been and princess Amy for help, I want to HB the forum released a game about 400MB in size, but not SkyDrive, can you help me?
 
Allen2014":f4c7e28c said:
Just call me Allen
BTW:
I have been and princess Amy for help, I want to HB the forum released a game about 400MB in size, but not SkyDrive, can you help me?
I would suggest DropBox where you get 2GB free file hosting https://www.dropbox.com/plans
It is similar to SkyDrive.

There is also MediaFire which is more like a traditional file host where you have 10GB free https://www.mediafire.com/upgrade/

But please keep within the thread topic.
 
Xilef":2fzix524 said:
Allen2014":2fzix524 said:
Just call me Allen
BTW:
I have been and princess Amy for help, I want to HB the forum released a game about 400MB in size, but not SkyDrive, can you help me?
I would suggest DropBox where you get 2GB free file hosting https://www.dropbox.com/plans
It is similar to SkyDrive.

There is also MediaFire which is more like a traditional file host where you have 10GB free https://www.mediafire.com/upgrade/

But please keep within the thread topic.

Oh sorry I digress, this is called the slanting floor in our...... Your system is tough, I can only use some simple scripts, the word is a very good very good very good
 

Ryaryu

Member

I've been struggling with the Tileset. It's draw methods are hidden, and I can't figure out how it draws the scene, hence I can't apply bump mapping to the map right now... has anyone found some Tileset implementation so far?
 
Tileset! I've got an RMXP implementation for you right here. Well...it will probably take some modification, because the viewport code uses other systems I wrote and it is designed for GOSU rather than plain OpenGL. You probably don't want to split the images into individual textures like this, you want to load it as one texture (if you can) and draw with UVs. But you can do this I think. The only part that needs explaining is that `Gosu::Image.load_tiles` creates an array of textures, in this case all 32x32 pixel tiles, row-by-row (so the first row would be tiles 0-7, the next 8-15, etc).

Every time I come back to this I am again disappointed that I did not do the GL calls myself in this way. Oh well. This should help you get started though.

[rgss]# RMXP Tilemap (gosu)
#
# Readable/Writable Attributes :
#  - viewport         : Viewport used for sprites
#  - map_data         : 3D Table of Tile ID Data
#  - flash_data       : 3D Table of Tile Color Data
#  - priorities       : 3D Table of Tile Priorities
#  - ox, oy           : Tilemap layer offsets
#  - zoom             : Zoom value as fraction
#  - tilesize         : Zoom value as size of individual tile (normal is 32.0)
#  - visible          : Tilemap Visible Flag
#  - is_a_plane       : Behaves like a Plane (loops around edges)
#  - tileset          : Name of Bitmap
#  - autotiles        : Array of Autotile Filenames
class Tilemap
  include Disposable
  VP                = 2    # Number of tiles beyond viewport to refresh
  FA                = 64   # Alpha value of the color of flash data
  Autotile_Speed    = 20   # Number of frames between autotile animations
  Autotiles = [
    [416,432,512,528], [ 64,432,512,528], [416, 80,512,528], [ 64, 80,512,528],
    [416,432,512,176], [ 64,432,512,176], [416, 80,512,176], [ 64, 80,512,176],
    [416,432,160,528], [ 64,432,160,528], [416, 80,160,528], [ 64, 80,160,528],
    [416,432,160,176], [ 64,432,160,176], [416, 80,160,176], [ 64, 80,160,176],
    [384,400,480,496], [384, 80,480,496], [384,400,480,176], [384, 80,480,176],
    [224,240,320,336], [224,240,320,176], [224,240,160,336], [224,240,160,176],
    [448,464,544,560], [448,464,160,560], [ 64,464,544,560], [ 64,464,160,560],
    [608,624,704,720], [ 64,624,704,720], [608, 80,704,720], [ 64, 80,704,720],
    [384,464,480,560], [224,240,704,720], [192,208,288,304], [192,208,288,176],
    [256,272,352,368], [256,272,160,368], [640,656,736,752], [ 64,656,736,752],
    [576,592,672,688], [576, 80,672,688], [192,272,288,368], [192,208,672,688],
    [576,656,672,752], [256,272,736,752], [192,272,672,752], [  0, 16, 96,112]
  ]
  DEFAULTS = {:tileset => nil, :autotiles => [], :map_data => nil,
              :flash_data => nil, :priorities => nil, :visible => true,
              :eek:x => 0, :eek:y => 0, :zoom => 1.0, :is_a_plane => true,
              :manager => nil}
 
  # Public Instance Variables
  attr_reader   :gosuwindow     # Instance of Gosu::Window it's drawing to
  attr_reader   :tileset        # Tileset Image
  attr_reader   :autotiles      # Array of Autotile Images
  attr_accessor :map_data       # 3D Table of Tile Settings
  attr_reader   :flash_data     # 3D Table of Sprite Flash Colors
  attr_accessor :priorities     # 3D Table of Tileset Priorities
  attr_accessor :visible        # Tilemap Visibility
  attr_accessor :eek:x             # Bitmap Offsets
  attr_accessor :eek:y             # Bitmap Offsets
  attr_accessor :zoom           # Zoom Fraction
  attr_accessor :is_a_plane     # Loops around edges
 
  # Object Initialization
  def initialize(manager = nil, opts = {})
    @gosuwindow = $GameWindow
    DEFAULTS.merge!(opts).each do |sym, val|
      instance_variable_set("@#{sym}", val)
    end
    @manager           = manager unless manager.nil?
    @autotiles_cache   = @autotiles
    self.flash_data    = @flash_data
    @tiles             = []
    @frame             = 0
    (@manager.nil? ? @gosuwindow.draw_manager : @manager).manage(self)
  end
 
  # Get "viewport"
  def viewport
    @manager
  end
 
  # Set "viewport"
  def viewport=(manager)
    (@manager.nil? ? @gosuwindow.draw_manager : @manager).unmanage(self)
    (manager.nil? ? @gosuwindow.draw_manager : manager).manage(self)
    @manager = manager
  end
 
  # Get Tile Size
  def tilesize
    (zoom * 32).to_i
  end
 
  # Set Tile Size
  def tilesize=(tilesize)
    self.zoom = tilesize / 32.0
  end
 
  # Set tileset graphic. Recaches the internal tileset.
  def tileset=(tileset)
    @tiles[384..-1] = Gosu::Image.load_tiles(@gosuwindow, tileset, 32, 32, true)
    @tileset = tileset
  end
 
  # Set list of autotiles. Recaches the internal tileset.
  def autotiles=(autotiles)
    autotiles.each_with_index do |autotile, i|
      Autotiles.each_with_index do |tiles, j|
        key = (i + 1) * 48 + j
        @tiles[key] = []
        # Draws Auto-Tile Rects
        for f in 0..(autotile.width / 96)
          bmp = Gosu::Image.new(@gosuwindow,
                                TexPlay::EmptyImageStub.new(32, 32), true)
          tiles.each_with_index do |pos, k|
            opts = {:crop => [x1 = pos%96+f*96, x2=pos / 96, x1 + 16, x2 + 16]}
            bmp.splice(k % 2 * 16, k / 2 * 16, autotile, opts)
          end
          @tiles[key][f] = bmp
        end
      end
    end
    @autotiles = @autotiles_cache = autotiles
  end
 
  # Set flash data. For speed we maintain a separate list of GOSU::Color
  # object for actual display.
  def flash_data=(flash_data)
    @flash_data = flash_data
    if flash_data.nil?
      @flash_data_colors = nil
    else
      @flash_data_colors = Hash.new
      for y in 0...flash_data.ysize
        for x in 0...flash_data.xsize
          hex = @flash_data[x, y]
          @flash_data_colors[[x, y]] =
            Gosu::Color.rgba((hex<<8)*16, ((hex<<4)%16)*16, (hex%16)*16, FA))
        end
      end
    end
  end
 
  # Dispose
  def dispose
    @visible = false
    super
  end
 
  # Update autotile animation
  def update
    @frame += 1
  end
 
  # Per-frame draw function
  def draw
    return if @map_data.nil? or @priorities.nil? or !@visible
   
    self.autotiles = @autotiles if @autotiles != @autotiles_cache
    ts = tilesize
    frame = @frame / Autotile_Speed
    xmax = (((@viewport.nil? ? @gosuwindow : @viewport.rect).width + @ox) / ts)
    ymax = (((@viewport.nil? ? @gosuwindow : @viewport.rect).height + @oy) / ts)
    ydts = @oy / ts
    yrange = ydts - VP...ymax + VP
    xrange = (@ox / ts) - VP...xmax + VP
   
    for y in yrange
      ytop = y - ydts
      if y < 0 or y >= @map_data.ysize
        next unless @is_a_plane
        y %= @map_data.ysize
        y += @map_data.ysize if y < 0
      end
      draw_y = y * ts - @oy
     
      for x in xrange
        if x < 0 or x >= @map_data.xsize
          next unless @is_a_plane
          x %= @map_data.xsize
          x += @map_data.xsize if x < 0
        end
        draw_x = x * ts - @ox
       
        for layer in 0...@map_data.zsize
          id = @map_data[x, y, layer]
          next if id == 0
          z = (ytop + z) * 32 + 64 unless (z = @priorities[id]) == 0
          tile = @tiles[id]
          tile = @tiles[id][frame % tile.size] if tile.is_a?(Array)
          tile.draw(draw_x, draw_y, z, @zoom, @zoom)
        end
        unless @flash_data.nil?
          c = @flash_data_colors[[x, y]]
          @gosuwindow.draw_quad(draw_x, draw_y,    c, draw_x+ts, draw_y,    c,
                                draw_x, draw_y+ts, c, draw_x+ts, draw_y+ts, c)
        end
      end # for x
    end # for y
  end
end
 
[/rgss]
 

Ryaryu

Member

rey meustrus":4kwcskea said:
Tileset! I've got an RMXP implementation for you right here. Well...it will probably take some modification, because the viewport code uses other systems I wrote and it is designed for GOSU rather than plain OpenGL. You probably don't want to split the images into individual textures like this, you want to load it as one texture (if you can) and draw with UVs. But you can do this I think. The only part that needs explaining is that `Gosu::Image.load_tiles` creates an array of textures, in this case all 32x32 pixel tiles, row-by-row (so the first row would be tiles 0-7, the next 8-15, etc).

Every time I come back to this I am again disappointed that I did not do the GL calls myself in this way. Oh well. This should help you get started though.

[rgss]# RMXP Tilemap (gosu)
#
# Readable/Writable Attributes :
#  - viewport         : Viewport used for sprites
#  - map_data         : 3D Table of Tile ID Data
#  - flash_data       : 3D Table of Tile Color Data
#  - priorities       : 3D Table of Tile Priorities
#  - ox, oy           : Tilemap layer offsets
#  - zoom             : Zoom value as fraction
#  - tilesize         : Zoom value as size of individual tile (normal is 32.0)
#  - visible          : Tilemap Visible Flag
#  - is_a_plane       : Behaves like a Plane (loops around edges)
#  - tileset          : Name of Bitmap
#  - autotiles        : Array of Autotile Filenames
class Tilemap
  include Disposable
  VP                = 2    # Number of tiles beyond viewport to refresh
  FA                = 64   # Alpha value of the color of flash data
  Autotile_Speed    = 20   # Number of frames between autotile animations
  Autotiles = [
    [416,432,512,528], [ 64,432,512,528], [416, 80,512,528], [ 64, 80,512,528],
    [416,432,512,176], [ 64,432,512,176], [416, 80,512,176], [ 64, 80,512,176],
    [416,432,160,528], [ 64,432,160,528], [416, 80,160,528], [ 64, 80,160,528],
    [416,432,160,176], [ 64,432,160,176], [416, 80,160,176], [ 64, 80,160,176],
    [384,400,480,496], [384, 80,480,496], [384,400,480,176], [384, 80,480,176],
    [224,240,320,336], [224,240,320,176], [224,240,160,336], [224,240,160,176],
    [448,464,544,560], [448,464,160,560], [ 64,464,544,560], [ 64,464,160,560],
    [608,624,704,720], [ 64,624,704,720], [608, 80,704,720], [ 64, 80,704,720],
    [384,464,480,560], [224,240,704,720], [192,208,288,304], [192,208,288,176],
    [256,272,352,368], [256,272,160,368], [640,656,736,752], [ 64,656,736,752],
    [576,592,672,688], [576, 80,672,688], [192,272,288,368], [192,208,672,688],
    [576,656,672,752], [256,272,736,752], [192,272,672,752], [  0, 16, 96,112]
  ]
  DEFAULTS = {:tileset => nil, :autotiles => [], :map_data => nil,
              :flash_data => nil, :priorities => nil, :visible => true,
              :eek:x => 0, :eek:y => 0, :zoom => 1.0, :is_a_plane => true,
              :manager => nil}
 
  # Public Instance Variables
  attr_reader   :gosuwindow     # Instance of Gosu::Window it's drawing to
  attr_reader   :tileset        # Tileset Image
  attr_reader   :autotiles      # Array of Autotile Images
  attr_accessor :map_data       # 3D Table of Tile Settings
  attr_reader   :flash_data     # 3D Table of Sprite Flash Colors
  attr_accessor :priorities     # 3D Table of Tileset Priorities
  attr_accessor :visible        # Tilemap Visibility
  attr_accessor :eek:x             # Bitmap Offsets
  attr_accessor :eek:y             # Bitmap Offsets
  attr_accessor :zoom           # Zoom Fraction
  attr_accessor :is_a_plane     # Loops around edges
 
  # Object Initialization
  def initialize(manager = nil, opts = {})
    @gosuwindow = $GameWindow
    DEFAULTS.merge!(opts).each do |sym, val|
      instance_variable_set("@#{sym}", val)
    end
    @manager           = manager unless manager.nil?
    @autotiles_cache   = @autotiles
    self.flash_data    = @flash_data
    @tiles             = []
    @frame             = 0
    (@manager.nil? ? @gosuwindow.draw_manager : @manager).manage(self)
  end
 
  # Get "viewport"
  def viewport
    @manager
  end
 
  # Set "viewport"
  def viewport=(manager)
    (@manager.nil? ? @gosuwindow.draw_manager : @manager).unmanage(self)
    (manager.nil? ? @gosuwindow.draw_manager : manager).manage(self)
    @manager = manager
  end
 
  # Get Tile Size
  def tilesize
    (zoom * 32).to_i
  end
 
  # Set Tile Size
  def tilesize=(tilesize)
    self.zoom = tilesize / 32.0
  end
 
  # Set tileset graphic. Recaches the internal tileset.
  def tileset=(tileset)
    @tiles[384..-1] = Gosu::Image.load_tiles(@gosuwindow, tileset, 32, 32, true)
    @tileset = tileset
  end
 
  # Set list of autotiles. Recaches the internal tileset.
  def autotiles=(autotiles)
    autotiles.each_with_index do |autotile, i|
      Autotiles.each_with_index do |tiles, j|
        key = (i + 1) * 48 + j
        @tiles[key] = []
        # Draws Auto-Tile Rects
        for f in 0..(autotile.width / 96)
          bmp = Gosu::Image.new(@gosuwindow,
                                TexPlay::EmptyImageStub.new(32, 32), true)
          tiles.each_with_index do |pos, k|
            opts = {:crop => [x1 = pos%96+f*96, x2=pos / 96, x1 + 16, x2 + 16]}
            bmp.splice(k % 2 * 16, k / 2 * 16, autotile, opts)
          end
          @tiles[key][f] = bmp
        end
      end
    end
    @autotiles = @autotiles_cache = autotiles
  end
 
  # Set flash data. For speed we maintain a separate list of GOSU::Color
  # object for actual display.
  def flash_data=(flash_data)
    @flash_data = flash_data
    if flash_data.nil?
      @flash_data_colors = nil
    else
      @flash_data_colors = Hash.new
      for y in 0...flash_data.ysize
        for x in 0...flash_data.xsize
          hex = @flash_data[x, y]
          @flash_data_colors[[x, y]] =
            Gosu::Color.rgba((hex<<8)*16, ((hex<<4)%16)*16, (hex%16)*16, FA))
        end
      end
    end
  end
 
  # Dispose
  def dispose
    @visible = false
    super
  end
 
  # Update autotile animation
  def update
    @frame += 1
  end
 
  # Per-frame draw function
  def draw
    return if @map_data.nil? or @priorities.nil? or !@visible
   
    self.autotiles = @autotiles if @autotiles != @autotiles_cache
    ts = tilesize
    frame = @frame / Autotile_Speed
    xmax = (((@viewport.nil? ? @gosuwindow : @viewport.rect).width + @ox) / ts)
    ymax = (((@viewport.nil? ? @gosuwindow : @viewport.rect).height + @oy) / ts)
    ydts = @oy / ts
    yrange = ydts - VP...ymax + VP
    xrange = (@ox / ts) - VP...xmax + VP
   
    for y in yrange
      ytop = y - ydts
      if y < 0 or y >= @map_data.ysize
        next unless @is_a_plane
        y %= @map_data.ysize
        y += @map_data.ysize if y < 0
      end
      draw_y = y * ts - @oy
     
      for x in xrange
        if x < 0 or x >= @map_data.xsize
          next unless @is_a_plane
          x %= @map_data.xsize
          x += @map_data.xsize if x < 0
        end
        draw_x = x * ts - @ox
       
        for layer in 0...@map_data.zsize
          id = @map_data[x, y, layer]
          next if id == 0
          z = (ytop + z) * 32 + 64 unless (z = @priorities[id]) == 0
          tile = @tiles[id]
          tile = @tiles[id][frame % tile.size] if tile.is_a?(Array)
          tile.draw(draw_x, draw_y, z, @zoom, @zoom)
        end
        unless @flash_data.nil?
          c = @flash_data_colors[[x, y]]
          @gosuwindow.draw_quad(draw_x, draw_y,    c, draw_x+ts, draw_y,    c,
                                draw_x, draw_y+ts, c, draw_x+ts, draw_y+ts, c)
        end
      end # for x
    end # for y
  end
end
 
[/rgss]

Woa!
Interesting. I'll try to play with it, thanks. One question though, your implementation works in RMVXAce as it is?
 
Absolutely not. It is RMXP only and would not work in any RGSS-based project without modification. I don't know enough about VX or VX Ace's Tilemap class to construct a newer version. Mainly because I haven't really used either maker much at all. I've been...lazy, I guess. If you count various time-consuming real life things getting in the way as lazy, which I do because I hate myself.

If you want an immediately RGSS-compatible option, you could also extract it from the Map Image Maker. Just create a new project, close it, replace its Data/Scripts.rxdata file with the MapMaker.rxdata file (renaming it to Scripts.rxdata), and open up the project and the script editor. In RMXP, of course. There are a number of other things in there in which you may be interested as well.
 
Sorry to bump this old topic but I noticed upon downloading the demo that it does not come with the "Shaders" folder or a "fragments.fsh" file mentioned in the first post (something that is kind of "hard" to edit when the file needed doesn't exist). I get the feeling that those two things were a part of the prior GLSL demo from the other thread but just like the link to that demo, the file and folder was "removed/deleted" before this demo went up. Also, because there's no documentation on how to "call" for the shaders (through events or otherwise), it kind of makes it difficult to work out how to utilize GLSL in my own project.

Is there some way to obtain these?
 
Espilonarge":rbaxoyjj said:
Sorry to bump this old topic but I noticed upon downloading the demo that it does not come with the "Shaders" folder or a "fragments.fsh" file mentioned in the first post (something that is kind of "hard" to edit when the file needed doesn't exist). I get the feeling that those two things were a part of the prior GLSL demo from the other thread but just like the link to that demo, the file and folder was "removed/deleted" before this demo went up. Also, because there's no documentation on how to "call" for the shaders (through events or otherwise), it kind of makes it difficult to work out how to utilize GLSL in my own project.

Is there some way to obtain these?
This experiment is not production ready nor is it supported. Do not use it in your own project (if you are unable to figure out how to use this, then you definitely should not be using it!).

All 3D functionality experimented with here is much easier to implement in RPG Maker MV, if you wish to do 3D graphics in RPG Maker then consider switching to MV.
 
I was aiming more towards effects like Gaussian Blur and other filters, not the 3D aspect of it.

The reason why I was asking is because I've been trying to find something to odd-load some of the heavy-ended effects that a couple of scripts are doing that is driving CPU usage through the roof (Zeus81's Map Effects being a prime culprit when using Gaussian Blur and such). I also tried to get SweetFX to work with VXAce but because it doesn't use Direct3D or OpenGL, I had to find an alternative, hence why when I ran in to your previous project and this one while searching around, I wanted to at least find some way of implementing at least a basic Gaussian Blur effect that is less likely to cripple the CPU.

To give you an example of what I'm trying to do.

I currently have Zeus81's Map Effects to generate a Guassian Blur with an Opacity of 25% to give sprites and tiles a "soft" edge effect (a form of "fantasy" like bloom). The problem is that if I try to use the functions/effects from MGC's Mode 7 or Woratora's Multiple Layers scripts on any map with those effects enabled, it can cause the FPS to nosedive painfully as it puts too much strain doing a "call" to the CPU to make the snapshots. At the same time, there is a bug with Zeus81's Map Effects affecting Effectus causing events and shadows (engine-generated) to shift 2 pixels in the same direction you're walking which is also why I wanted to try and get your script functions working.

mSlASz2.png
 
My script functions here are not production ready and have compatibility and security problems. If it's post-processing shaders you're after, then it may be worth finding a scripter (or paying me) to write you a complete script and new processing DLL based on the technique I used here.

I am guessing that you're simply wanting a way to program GPU accelerated post-processing atop the Tilemap?
 
My script functions here are not production ready and have compatibility and security problems. If it's post-processing shaders you're after, then it may be worth finding a scripter (or paying me) to write you a complete script and new processing DLL based on the technique I used here.

I am guessing that you're simply wanting a way to program GPU accelerated post-processing atop the Tilemap?
Extreme necro, but would you mind reuploading this project?
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top