• Hey! Guest! The 39th GMC Jam will take place between November 26th, 12:00 UTC and November 30th, 12:00 UTC. Why not join in! Click here to find out more!

GM Community DLL Collection/Discussion

Joe Ellis

Member
Hi everyone, I've started this thread as a way for people to share and discuss dll's they've made with everyone. I started the thread a couple of weeks ago to share my anisotropic filtering and external texture loader dll, but I've changed the title as I wanted it to be a more general thread where everyone can share dll's they've made. So here it is!
If you have a dll you want to share(as long as it's for gm), feel free to do so here, by either posting a download link or a link to another thread, and a description of what it does.
All the best everyone :)

Here is my texture dll:

Test.png

There has always been a problem in gm where any textures loaded externally, or during gameplay don't have mipmaps generated for them, which results in anisotropic filtering not worked properly.
For the past few years I've been using a dll to fix this issue, and I didn't realise it was something that many people have been looking for until the other day in a conversation in the RenderTech thread: https://forum.yoyogames.com/index.php?threads/rendertech.63893/
So I've decided to release the dll and source code here.

It works by bypassing gm's built in texture system\functions, and doing it all through directx independently.
It mainly uses 2 functions: texture_load(filename) (which returns the texture's pointer into gm) and texture_set(sampler_id, texture_pointer).

Mipmaps automatically get generated for each texture loaded, and when anisotropic filtering is enabled, everything looks exactly how it should.

The dll also has functions for enabling\disabling anisotropic filtering\mipmapping, setting min\mag\mip filter modes.

Note- Gm's built in texture_set_stage doesn't work with the pointers returned from the load function, so you have to use the texture_set function, and you can't use the gm_basetexture, you have to create a uniform sampler.

The dll is currently only compatible with gms1.4, and uses the direct9c sdk. If you want to use and compile the source code you'll need to get the dx9c sdk.
It will be quite easy to convert to gms2\dx11, it'll be the exact same process for each function, just using the dx11 sdk functions instead.

I've made a very basic project which shows the anisotropic filtering working on an externally loaded texture, where you can toggle it on and off by pressing A. I picked a texture that would look particularly bad when anisotropic filtering is off so you can see the difference it makes ;)

https://drive.google.com/open?id=1SQLmujDQwOIK9X84qRbfI_JKFa5eTodM

And here's the source code:

https://drive.google.com/open?id=1zvdUorPE8jwwHR0UJ88xCo2f8_Y04S2J


If you have any question or problems, feel free to ask here, it would be better if you posted here instead of a pm so other people can read it if they have the same problem.

Also if anyone else has made dll that's related to expanding gm's graphics, it would be great if you posted a link to it here :D

All the best everyone and I hope this can help you out with your projects
 
Last edited:
So this is using mipmapping as well?

I was expecting that a different kind of texture sampling function (apart from texture2D) would be necessary for this to work. How would you get mipmapping and anistropic filtering to work with textures that aren't necessarily mapped by geometry? For example: I've got a shader that draws a planet onto a 2d quad, and I'm trying to figure out how mipmapping and anistropic filtering could be applied to it.
 

Joe Ellis

Member
Yeah it uses mipmapping, I think they get generated when a texture is loaded by default, and they turned this off for sprite_add & background_add. They didn't turn it off for sprite or background resources with used for 3d checked though, cus it works on these fine. So you don't have to use the dll's texture load and set functions if your using textures from the resource tree.

I'm not sure about if it would work for the planet shader, maybe it can, cus the depth of the pixels don't seem to be taken into account with the anisotropic filtering cus it still works with 2d stuff or if you manually set the gl_position depth to 0 or something, and also if the uvs are calculated inside the pixel shader it still works, so it mustn't be done during the interpolation from vertex to pixels. It seems it's done during texture reading and takes into account texture reads from other pixels, I don't know how it does this though or even if it does, but I could try and test doing this on a quad and see if it works, or if you wanna download the example project you can just import the dll extension into your project, and like I said if your using textures from sprite or background resources, you won't have to change any of your code, just put d3dx_enable_anisotropic at the start of the draw event.

Note- Once the dll is enabled using d3dx_init(window_device) and you enable anisotropic filtering, you have to call d3dx_enable_anisotropic each frame.
If you don't, mipmapping is still enabled but anisotropic filtering isn't, and it makes textures look very blurry on surfaces that aren't pointing much toward the camera. (This is the part that the anisotropic filtering sorts out)
I'm not sure why it has to be enabled every frame, maybe something in gm overrides it at the start or end of the draw event. Maybe someone else will know if they see the source code
 
Well, mipmapping seems to work well enough out of the box. It's hard to tell whether the anisotropic filtering works correctly.

There is one obvious flaw though. At the boundary between the left and right sides of the texture, there is an obvious seam. I thought turning on texture repeating would solve the problem, but it did not.



EDIT: Okay, clearly I have to find a way to disable it for certain textures or else to change the way the filtering works for those textures. Look what it does to the lighting/scattering look up table texture. This is somehow related to texture repeating, because it only happens when both texture repeating and d3dx_enable_anisotropic_filtering are used at once. Actually, I can turn texture repeating on or off for specific textures, so I guess this isn't actually a big problem. I'd still like to know why it happens when those two things are used together. It would probably also be a good idea to figure out how to turn on/off anisotropic filtering on a per texture basis.


For anyone looking at these images, bear in mind that this is probably an unusual use case.
 
Last edited:

Joe Ellis

Member
Ah sorry there is a problem with the dll automatically enabling texture repeating, and for some reason texture_set_repeat(false) has no effect once the dll has been initialized, and I don't know how to stop this. I'll have to do some reading and find out how to fix it. Sorry for not mentioning that, I forgot cus I always have repeating on and never had a situation where I needed it off.
I've never seen that seam thing happen before either, I don't know why that's happening, sorry. If I find out why I'll let you know.

When I've found out how to fix it I'll hopefully add a function for toggling repeating. Also I just remembered, in the texture set function it turns repeating on every time it's called, and this probably isn't necessary.
 

Lewa

Member
Nice! Will experiment with it in the next few days.
Have you by any chance looked into surface support? (if this technique can be applied to dynamically created surfaces)
 

Joe Ellis

Member
@Lewa I looked into it a bit but unfortunately I don't know how to do it yet. But might not be plausible to do cus it'd require recreating the mipmaps and anisotropic probes every step and there'd be a serious limit on how many surfaces you can do that with simultanuously. (Even loading a single 1024x1024 texture causes a couple steps of lag)
I plan on doing some research over the next few weeks to find more out about this kind of stuff, and I also want to add a few things to the dll at some point, like enabling front face culling, and view frustum culling
 

Apapappa

Member
So, this took a bit more than "a few days".
(reference: https://forum.yoyogames.com/index.php?threads/rendertech.63893/#post-414786)

But I said I was going to post my DLL here as well so here it is -

GMEx:

Compatible with GMS 1.4, tested on v1.4.1763.

This DLL basically does the same thing as Joe Ellis's DLL +/- a few functions, but it might still be useful for someone.
Big thanks to Joe Ellis for the external texture part since that part of my DLL is pretty much copy pasted from his source.

Functions:

GMEx_InitDevice() - stores the dx9 interface for use in all other functions, should be called first.
GMEx_SetPointSprite() - enable / disable "hardware" point sprite support.
GMEx_SetFillMode() - sets fill mode: point, wireframe, solid.
GMEx_SetCullMode() - sets culling mode: none, clockwise, counterclockwise.
GMEx_SetViewPort() - sets the current view port allowing you to render multiple projections to a single surface.
(GMS automatically sets the view port to the entire surface without using this function, but it might possible be doable with matrix manipulation)
GMEx_SetTexAddress() + GMEx_SetTexAddressSampler() - sets texture address mode: wrap, mirror, clamp, border, mirroronce.
GMEx_SetTexFilter() + GMEx_SetTexFilterSampler() - sets texture filtering mode: none, point, linear, anisotropic.
GMEx_SetTexMipFilter() + GMEx_SetTexMipFilterSampler() - sets mipmap filter.
GMEx_SetTexMagFilter() + GMEx_SetTexMagFilterSampler() - sets magnification filter.
GMEx_SetTexMinFilter() + GMEx_SetTexMinFilterSampler() - sets minification filter.
GMEx_SetTexAnisoLevel() + GMEx_SetTexAnisoLevelSampler() - sets anisotropic filtering level.
GMEx_SetMaxMipLevel() + GMEx_SetMaxMipLevelSampler() - set the maximum mip level.

GMEx_ExternalTextureLoad() - loads an external texture with mipmapping support.
GMEx_ExternalTextureFree() - frees an externally loaded texture.
GMEx_ExternalTextureSet() - sets an external texture to a sampler slot.
(thanks again Joe Ellis for these 3!)

Download:
https://www.dropbox.com/s/lev1cacbi0t7pfe/GMEx_Example.zip?raw=1
(includes: example .exe, GMS project source, importable extension and DLL source)
 

Apapappa

Member
There are some other things I'm interested in seeing attempted with dll's.

vertex shader texture sampling.

gpu instancing. Probably a long shot.
I'm interested in these two things as well.
And I'd do it myself, but to no surprise, I'm not really an expert on this matter.
But if no one else comes along that has done this, I'll probably try and fiddle around with it at some point.
So I'll let this post serve as a bump to this topic in hopes of this subject gaining more traction.
 

Joe Ellis

Member
I managed to find the dll with vertex texture sampling included.


I made a demo which reads an rgb heightmap which is essentially 3 grayscale heightmaps combined into the rgb channels.
The shader then reads each channel using separate uv offsets which are moved at different speeds and directions,
then pushes the vertex position outwards using the normal multiplied by the total amount read from the 3 heightmaps.
It outputs the 3 values into the rgb color to show you what parts of the heightmaps it's reading.

There are a few requirements that I should note here:
  • The shaders that sample vertex textures must be in hlsl 9
  • The vertex textures must be sampled using tex2Dlod
  • The uvs must be a float4 eg. val = tex2Dlod(vertex_texture, float4(u, v, 0.0, 0.0));
  • Loading vertex textures must use the function d3dx_vertex_texture_load(string_filename\path) and set using d3dx_set_vertex_texture(vertex_texture_sampler_id, vertex_texture)
  • Currently only works with gms1.4
The demo shows all of these things aswell, so will hopefully be easy to follow.

You can get the demo & dll here: https://drive.google.com/open?id=1HlRCuP85CkMbOqMneHF2L8qvF3oWNiGA

I haven't uploaded a new version of the dll source code because the vertex sampling functions are already in there, they just weren't put into the gm extension.

If anyone has any questions or problems leave a message here and I'll try my best to help.

Also if anyone has any ideas of what this could be used for in a game it'll be cool to hear\see!
 
Last edited:

Joe Ellis

Member
No, unfortunately cus gpu usage doesn't affect framerate unless it makes the whole game choke up. I expect it will have some hit, but then again, it's only reading a fraction of what the pixel shader does, so I really don't know.
It's impossible to test things on the gpu like you can with cpu stuff, (without an extension like lonewolff's gpu usage monitor) cus if you measure how many microseconds have gone by since the last frame, it'll always be 16000 cus of the syncing
 
Top