wheybags / freeablo

[ARCHIVED] Modern reimplementation of the Diablo 1 game engine
GNU General Public License v3.0
2.16k stars 193 forks source link

Modern image file format support #23

Open wheybags opened 10 years ago

khanduras commented 10 years ago

Would this require each monster be redrawn as a PNG file?

wheybags commented 10 years ago

no, just the ability to make new monsters using pngs or something similar, instead of having to mess with arcane CEL / CL2 files

khanduras commented 10 years ago

Many monsters share the same cel/cl2 file with a trn file to make it a different colour, therefore a different monster. Ex Fallen and Carver are the same sprite with different colour. We'd have to make a PNG for each monster now, rather than just the base monster with a colour palette.

wheybags commented 10 years ago

Some sort of system could be sorted out, but palette swapping is a bit outdated in a world with more than 256 colours :P

khanduras commented 10 years ago

If you can bust through that palette system it would be a god send to Diablo modders. Also, being able to use multiple dungeon tilesets in each area. A hellish cave would be great, for example.

wheybags commented 10 years ago

Yeah, that seems sensible

mewmew commented 10 years ago

I'm also very interested in the support of modern image formats with open specification. The following steps can be taken to convert all CEL and CL2 images to PNG images. The commands are meant to facilitate the debugging and implementation of modern image support for freeablo. Please let me know if any of the steps require further explanation.

  1. Install Go from a binary distribution or from source.
  2. Configure the GOPATH environment variable.

    $ mkdir $HOME/go
    $ export GOPATH=$HOME/go
    $ export PATH=$PATH:$GOPATH/bin
  3. Extract DIABDAT.MPQ using Ladislav Zezula's MPQ Editor.
  4. Fix the two faulty files unravw.cel and banner2.dun as specified here.
  5. Download and compile the img_dump, min_dump, til_dump and dun_dump commands by running:

    $ go get github.com/mewrnd/blizzconv/images/cmd/img_dump
    $ go get github.com/mewrnd/blizzconv/configs/cmd/min_dump
    $ go get github.com/mewrnd/blizzconv/configs/cmd/til_dump
    $ go get github.com/mewrnd/blizzconv/configs/cmd/dun_dump
  6. Set up the environment required by img_dump, min_dump, til_dump and dun_dump:

    $ mkdir dump
    $ cd dump
    $ ln -s /path/to/extracted/diabdat_mpq/ mpqdump
    $ ln -s $GOPATH/src/github.com/mewrnd/blizzconv/mpq/mpq.ini mpq.ini
    $ ln -s $GOPATH/src/github.com/mewrnd/blizzconv/images/imgconf/cel.ini cel.ini
    $ ln -s $GOPATH/src/github.com/mewrnd/blizzconv/images/imgconf/cl2.ini cl2.ini
    $ ln -s $GOPATH/src/github.com/mewrnd/blizzconv/configs/dunconf/dun.ini dun.ini
  7. Convert all CEL images to PNG images. The following command creates 12045 PNG images (57 MB) and takes about 1m20s to complete on my computer.

    $ time img_dump -imgini=cel.ini -a
  8. Convert all CL2 images to PNG images. The following command creates 373967 PNG images (1.8 GB) and takes about 1h45m to complete on my computer.

    $ time img_dump -imgini=cl2.ini -a
  9. Convert all MIN files to PNG images. The following command creates 3286 PNG images (19 MB) and takes about 1m to complete on my computer.

    $ time min_dump l1.min l2.min l3.min l4.min town.min
  10. Convert all TIL files to PNG images. The following command creates 1001 PNG images (14 MB) and takes about 40s to complete on my computer.

    $ time til_dump l1.til l2.til l3.til l4.til town.til
  11. Convert all DUN files to PNG images. The following command creates 45 PNG images (62 MB) and takes about 4m20s to complete on my computer.

    $ time dun_dump -a

Note: Step 8 takes ages to finish.

wheybags commented 10 years ago

I would prefer to keep support for diablo image files in freeablo instead of converting,but then also support proper inages as well On 24 Aug 2014 03:07, "Robin Eklind" notifications@github.com wrote:

I'm also very interested in the support of modern image formats with open specification. The following steps can be taken to convert all CEL and CL2 images to PNG images. The commands are meant to facilitate the debugging and implementation of modern image support for freeablo. Please let me know if any of the steps require further explanation.

  1. Install Go from a binary distribution http://golang.org/doc/install or from source http://golang.org/doc/install/source. 2.

    Configure the GOPATH environment variable http://golang.org/doc/code.html#GOPATH.

    $ mkdir $HOME/go $ export GOPATH=$HOME/go $ export PATH=$PATH:$GOPATH/bin

    3.

    Extract DIABDAT.MPQ using Ladislav Zezula's MPQ Editor http://www.zezula.net/en/mpq/download.html. 4.

    Download and compile the img_dump, min_dump, til_dump and dun_dump commands by running:

    $ go get github.com/mewrnd/blizzconv/images/cmd/img_dump $ go get github.com/mewrnd/blizzconv/configs/cmd/min_dump $ go get github.com/mewrnd/blizzconv/configs/cmd/til_dump $ go get github.com/mewrnd/blizzconv/configs/cmd/dun_dump

    5.

    Set up the environment required by img_dump, min_dump, til_dump and dun_dump:

    $ mkdir dump $ cd dump $ ln -s /path/to/extracted/diabdat_mpq/ mpqdump $ ln -s $GOPATH/src/github.com/mewrnd/blizzconv/mpq/mpq.ini mpq.ini $ ln -s $GOPATH/src/github.com/mewrnd/blizzconv/images/imgconf/cel.ini cel.ini $ ln -s $GOPATH/src/github.com/mewrnd/blizzconv/images/imgconf/cl2.ini cl2.ini $ ln -s $GOPATH/src/github.com/mewrnd/blizzconv/configs/dunconf/dun.ini dun.ini

    6.

    Convert all CEL images to PNG images. The following command creates 12045 PNG images (57 MB) and takes about 1m20s to complete on my computer.

    $ time img_dump -imgini=cel.ini -a

    7.

    Convert all CEL images to PNG images. The following command creates XXX PNG images (XXX MB) and takes about XXX to complete on my computer.

    $ time img_dump -imgini=cl2.ini -a

    8.

    Convert all MIN files to PNG images. The following command creates 3286 PNG images (19 MB) and takes about 1m to complete on my computer.

    $ time min_dump l1.min l2.min l3.min l4.min town.min

    9.

    Convert all TIL files to PNG images. The following command creates 1001 PNG images (14 MB) and takes about 40s to complete on my computer.

    $ time til_dump l1.til l2.til l3.til l4.til town.til

    10.

    Convert all DUN files to PNG images. The following command creates 45 PNG images (62 MB) and takes about 4m20s to complete on my computer.

    $ time dun_dump -a

Note: Step 7 takes ages to finish, so I'll fill in the missing details (e.g. XXX) once it has completed.

— Reply to this email directly or view it on GitHub https://github.com/wheybags/freeablo/issues/23#issuecomment-53174426.

mewmew commented 10 years ago

I can understand that. Since freeablo is currently capable of rendering the world using CEL and CL2 images with the specific tilsets and image provided by diabdat.mpq, it would in some ways be easier to add support for modern image formats using the same tilests and images (but in PNG format). This way it would be possible to focus on adding support for PNG images while not having to worry about finding new tilesets, character animations, and making sure that they fit together and have the correct size, etc... Even if freeablo doesn't end up converting the original game assets to PNG images, I hope that having them available will be helpful.

tilkinsc commented 6 years ago

Due to the massive size introduced, I would recommend JPEG files, however lossy it may be, that can be user choice. I think the file format CEL/CL2 is perfectly fine. Let's actually create a tool to help modders generate the files they need.

mewmew commented 6 years ago

Due to the massive size introduced, I would recommend JPEG files, however lossy it may be, that can be user choice. I think the file format CEL/CL2 is perfectly fine. Let's actually create a tool to help modders generate the files they need.

We ran a quick test to see the overhead of using PNG, and converting the frames into spritesheets (so one PNG image per CEL or CL2 file), and using a tool such as optipng you get roughly the same size of the game assets, while keeping the assets in a lossless image file format.

tilkinsc commented 6 years ago

Neat! Back in the day of PS1 era The Legends of Dragoon used additive images blending to not only do clipping but also to do colorizations. I wonder if we could develop such a method having the base characters and using additive colorations. That would be legendary, especially because we can keep the modern formats without much hassle of maintaining spritesheets with limited xy pixels. I also know that http://www.synthetic-reality.com/wosHome.htm well of souls does something like this, but not the additive part, just the spritesheet and image stuff we are talking about.

mewmew commented 6 years ago

Neat! Back in the day of PS1 era The Legends of Dragoon used additive images blending to not only do clipping but also to do colorizations. I wonder if we could develop such a method having the base characters and using additive colorations.

That sounds really cool! Was this done from the original 3d-models, or from greyscale images with palettes?

That would be legendary, especially because we can keep the modern formats without much hassle of maintaining spritesheets with limited xy pixels.

Do you mean the restrictions of width and height for GPU textures? To reduce wasted space in the sprite sheets, we can also use Bin packing. This is the approach taken by Flare: https://github.com/stefanbeller/RectangleBinPack

wheybags commented 6 years ago

Tbh my long term plan for freeablo is to just dump the entire games assets into a few atlas textures and call it a day. With modern gpus, we can actually afford to just do that. Also, as for what format will be supported, I have an open source image loading library I developed in my last job ( https://github.com/Artomatix/ArtomatixImageLoader) that I'm going to use (probably needs some work before then though). That supports multiple formats, so we'll probably support multiple formats too.

On Dec 22, 2017 11:25 AM, "Robin Eklind" notifications@github.com wrote:

Neat! Back in the day of PS1 era The Legends of Dragoon used additive images blending to not only do clipping but also to do colorizations. I wonder if we could develop such a method having the base characters and using additive colorations.

That sounds really cool! Was this done from the original 3d-models, or from greyscale images with palettes?

That would be legendary, especially because we can keep the modern formats without much hassle of maintaining spritesheets with limited xy pixels.

Do you mean the restrictions of width and height for GPU textures? To reduce wasted space in the sprite sheets, we can also use Bin packing https://en.wikipedia.org/wiki/Bin_packing_problem. This is the approach taken by Flare: https://github.com/stefanbeller/RectangleBinPack

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/wheybags/freeablo/issues/23#issuecomment-353579428, or mute the thread https://github.com/notifications/unsubscribe-auth/ABCumhlL-EzKYg3U_Zj4XbPXMVyvHSpbks5tC5G0gaJpZM4BkL_d .

tilkinsc commented 6 years ago

Depends on whatever it comes out to.

@mewmew Well not all of them did this. I know TLOD did it and how they did it was morphing an underlying color to the pixels it needs. For example, green pixels overlayed with an image would represent how late the pixels would draw on top of combined color palettes or bitmaps which are probably averaged together or something idk (yunno fake lighting and stuff). And this clipping stuff was done probably by switching buffers iterating over the pixels of the background and detecting the pixel type. Something procedural. Grune is behind, purpurrot is front.

grantramsay commented 5 years ago

@wheybags - I had a play with making a runtime texture atlas and batching all the level textures/sprites into one draw call. Not quite what's needed but a bit of a proof of concept and some re-usable stuff at least. Was mostly interested in learning a bit about opengl. Have a look / run it if your interested: https://github.com/grantramsay/freeablo/pull/1/files

Increases my idle FPS from ~50 up to ~180. I think that's because previously each frame was making ~2000 -> 3000 calls to glDrawArrays, now it just makes one call to glDrawArraysInstanced for the whole frame.

Issues:

Again this was just me playing around with opengl, and trying to increase the FPS a bit. If I could get some clearer direction on how everyone would like this implemented I could have a more in depth look into it

tilkinsc commented 5 years ago

It looks like a new texture file format isn't really what is needed. Moreso a texture container.

New textures can be made via exporting as an opengl compressed file. This makes it so decompression happens on the GPU. I am not sure how yall are rendering the paletted forms of enemies, but that can be handled at load time, as it is fairly trivial to do AND CACHE.

My file container I made supports any file you throw at it with minimal load time.

wheybags commented 5 years ago

@grantramsay That sounds great! I have some more plans in thsi regard, but starting with texture atlases is 100% the right way to go. Sorry I haven't had the time lately to look at your PRS. I'm away for a few days at the moment, but I'll definitely get back to you properly ASAP once I get home.

@tilkinsc We can just use a shader to do palette swaps. it can be a simple LUT packed into a texture, and since they're only 256 colors we don't need interpolation, so we can pack multiple palettes into one texture and just pass a palette index in as part of the vertex. Or we could pregenerate, yeah :v

On Fri, Feb 1, 2019, at 2:18 AM, grantramsay wrote:

@wheybags - I had a play with making a runtime texture atlas and batching all the level textures/sprites into one draw call. Not quite what's needed but a bit of a proof of concept and some re-usable stuff at least. Was mostly interested in learning a bit about opengl. Have a look / run it if your interested: https://github.com/grantramsay/freeablo/pull/1/files

Increases my idle FPS from ~50 up to ~180. I think that's because previously each frame was making ~2000 -> 3000 calls to glDrawArrays, now it just makes one call to glDrawArraysInstanced for the whole frame.

Issues:

  • Chews up a lot of video/GPU memory (>1GB if you walk through all the levels)
  • Large textures are not currently added to atlas. It uses a simple scan line implementation to write textures into atlas, this falls over a bit when you get weird font textures that are 32x7000.. Limiting height/width to under 512 gives ~91% efficiency.
  • Increase opengl version from 3.2 to 3.3. Used for glVertexAttribDivisor and GLSL layout (location ..., these could probably be done differently if increasing GL version isn't an option
  • Currently just duplicates all sprites into atlas

Again this was just me playing around with opengl, and trying to increase the FPS a bit. If I could get some clearer direction on how everyone would like this implemented I could have a more in depth look into it

-- You are receiving this because you were mentioned. Reply to this email directly or view it on GitHub: https://github.com/wheybags/freeablo/issues/23#issuecomment-459570174

grantramsay commented 5 years ago

No worries @wheybags. Thanks for mentioning compression @tilkinsc, I set the compression flag for the atlas texture and works much better. FPS is around the same but video memory usage is reduced. Can now add all the large textures (fonts) etc to the atlas as well which makes this much more viable.

tilkinsc commented 5 years ago

Please add a commit to the change @grantramsay

grantramsay commented 5 years ago

FYI I've just done a bit more work on this:

Current issues:

https://github.com/grantramsay/freeablo/pull/1/files

tilkinsc commented 5 years ago

Could it be render order? By compression I mean load all the assets from the diablo files, cache them cached for target with OpenGL compression algorithm.

wheybags commented 5 years ago

Sweet, that sounds really great!

  • Added support for GUI/nuklear stuff to also use atlas texture I wouldn't worry too much about this, since it's just the gui. maybe it should use the atlas for textures from the game (eg sprite sheets for buttons), but there's no need for stuff like the textures it generates itself for fonts and the like. Anyway, it should probably use a separate atlas if so, since we don't ever want texture compression on gui elements.

As for the game assets proper, I would like to render whole TIL sections as one piece, so the atlas could stire those, instead of the thousands of tiny level chuncks straight from the CEL files. This would require a bunch of changes though, so it's fine without for now. Eventually, I would like to use the TMX format, so we can get an editor for free from tiled. I would throw out the abstraction of DUN/MIN/TIL and just have single isometric tiles as the foundation unit, and have some code to convert the existing maps in diablo to the tmx format.

As for texture compression, it would be nice, but again, I wouldn't worry too much about it for now, we can alweays enable it later, and 1gb vram usage is fine, it's 2019 :v I would also like to preload all the sprites, so we don't get that nasty stutter when we encounter a new enemy, or change level.

Anyway, let me know when you feel it's getting ready to go in master, I'd love to see this in!

grantramsay commented 5 years ago

Ok sounds good, I'll add a PR when I get those last issues ironed out and given it a tidy up. I might have to try some opengl forums as I'm struggling to figure out what's going wrong..