How to achive these in ORX?

jimjim
edited January 2012 in General discussions
Hi everyone,

I am new to ORX and this forum, I was doing some experiment with SDL and OpenGL a few weeks ago, then I found ORX and now I am going to develop 2D games using ORX. I think this is a fantastic 2D engine for C++ lovers. I have checked the basic tutorials and I am impressed. I am not very good in OpenGL, i just learned OpenGL from nehe site, so my OpenGL knowledge is very outdated. I have couple of question regarding ORX.

1. Does ORX support only 3 kind of blending (add,alpha and multiply)?
If not then how to do other kind of blending?
If yes, then is it possible for me to add OpenGL blending function in ORX without building it from source?

2. How to apply this blending function in ORX?

glBlendFunc(GL_DST_ALPHA,GL_ZERO);

3. Is alpha test possible in ORX? I have not found anything about alpha test or discarding fragments in ORX like
glEnable(GL_ALPHA);
glAlphaFunc(GL_GEQUAL,.01);

I know that this kind of things is possible with shader but I don't know shader and my current hardware does not support shader. If these are not possible without shader then it is okay, I will still continue with ORX but then the project I was working with (SDL + OpenGL) will have to be postponed until I learn shader or buy new hardware. But I want to finish the project as soon as possible with ORX because ORX provide almost everything I need to develop this game, other wise I have to work a lot on low level things, I am making this game for Linux and Windows.

One more request I would be very grateful if anybody could show me how to add custom OpenGL rendering code in ORX, I have found a post on the forum regarding this but I didn't get it, as my OpenGL knowledge is very poor. Please forgive me if my I have written anything wrong.

Thank you.

Comments

  • edited January 2012
    jim wrote:
    Hi everyone,

    Hi jim and welcome here!
    I am new to ORX and this forum, I was doing some experiment with SDL and OpenGL a few weeks ago, then I found ORX and now I am going to develop 2D games using ORX. I think this is a fantastic 2D engine for C++ lovers. I have checked the basic tutorials and I am impressed. I am not very good in OpenGL, i just learned OpenGL from nehe site, so my OpenGL knowledge is very outdated. I have couple of question regarding ORX.

    Thanks for the appreciation and good choice on NeHe tutorials: they are probably the most understandable OpenGL tutorials out there.
    1. Does ORX support only 3 kind of blending (add,alpha and multiply)?
    If not then how to do other kind of blending?
    If yes, then is it possible for me to add OpenGL blending function in ORX without building it from source?

    So yes, orx explicitly supports only 1+3 blending types:
    - none: blending disabled
    - alpha: glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    - add: glBlendFunc(GL_SRC_ALPHA, GL_ONE)
    - multiply: glBlendFunc(GL_DST_COLOR, GL_ZERO)

    That being said you can use any blend combination yourself by listening to render events and calling the OpenGL code yourself before an object is rendered. Just make sure that the object is using the same blending as other objects in the scene otherwise orx will override your blending settings.

    So technically add an event listener for orxEVENT_TYPE_RENDER/orxRENDER_EVENT_OBJECT_START.
    When it's your object that has sent this event, first make sure orx finishes its current rendering batch by calling:
    orxFLOAT fWidth, fHeight;
    
    orxDisplay_GetScreenSize(&fWidth, &fHeight); // To get the actual display size, but you can cache it somewhere else
    orDisplay_SetBitmapClipping(orxDisplay_GetScreenBitmap(), 0, 0, orxF2U(fWidth), orxF2U(fHeight)); // This will reset the scissor on your screen but will render the current batch beforehand
    
    then you can call your own glBlendFunc() and return orxSTATUS_SUCCESS (if you return orxSTATUS_FAILURE the object won't be rendered, that's the way to bypass the rendering of a given object).

    You also need to listen to the orxRENDER_EVENT_OBJECT_STOP so that you can reinitialize the blend function (as orx has no idea of what you changed). Depending on which blending it was (add, multiply or alpha) use the above formula to set the blending back.

    It's a bit tricky but at least it gives you the option of using any blending mode without having to modify orx yourself.
    2. How to apply this blending function in ORX?

    glBlendFunc(GL_DST_ALPHA,GL_ZERO);

    Cf above. :) Also, for what purpose do you want to use this blending combination? I'm asking as there might be other ways to achieve what you want without having to temper with blending modes yourself. In 2D, the 3 blending modes defined in orx are the most commonly used to achieve most of the lighting/shading/masking effects.

    For example, your blend function is very close of the multiply one, except that instead of using the color channels it uses the alpha for the source multiplication.
    Maybe you could modify your bitmap so that the rgb channels will contain the same value as the alpha one and simply use the multiply blend?

    If you don't want to do it offline, you can even do it at runtime within orx by modifying this texture itself or by creating a brand new texture based on that one and that you would then use on your object. Also remember that you can modify config info at runtime (for replacing the original texture with the new one for the concerned objects).

    I could describe here in details how to do this (it's not very hard, really) but that post would get too long. Let me know if it's something you're interested in though. Maybe I could then write a tutorial for it on the wiki.

    Orx is very flexible this way and sometimes there are non obvious ways of pre-processing data at load time for then using orx without having to do any hand written custom rendering that could be worth it. I'm currently doing something very similar to simulate the color bleeding of the ZX Spectrum without having to preprocess the data manually offline.
    3. Is alpha test possible in ORX? I have not found anything about alpha test or discarding fragments in ORX like
    glEnable(GL_ALPHA);
    glAlphaFunc(GL_GEQUAL,.01);

    Alpha testing is disabled by default as it's painfully slow on some OpenGL ES devices. You can enable/disable it on the fly when needed by listening to the render events as described above.
    I know that this kind of things is possible with shader but I don't know shader and my current hardware does not support shader. If these are not possible without shader then it is okay, I will still continue with ORX but then the project I was working with (SDL + OpenGL) will have to be postponed until I learn shader or buy new hardware. But I want to finish the project as soon as possible with ORX because ORX provide almost everything I need to develop this game, other wise I have to work a lot on low level things, I am making this game for Linux and Windows.

    Writing shaders is actually very easy (I actually learned them when adding their support to orx). There's a tutorial (#12) about that. :)

    As for shader support on your hardware, orx needs only version 1.0 support of shaders which are now pretty common. That reminds me that I should soon add a orxDisplay_HasShaderSupport() for that purpose on the svn. :)
    One more request I would be very grateful if anybody could show me how to add custom OpenGL rendering code in ORX, I have found a post on the forum regarding this but I didn't get it, as my OpenGL knowledge is very poor. Please forgive me if my I have written anything wrong.

    Remember how we hooked your custom blending at the beginning of this post? Well, it's very similar. You create a dummy object (it needs a graphic otherwise it won't be considered by the renderer). When receiving the orxRENDER_EVENT_OBJECT_START event for it, you ask orx to end its current rendering batch (as mentioned above), you then do whatever custom OpenGL rendering you need, and finally you return orxSTATUS_FAILURE which means orx won't do any rendering itself for that object. That's about it!

    Just out of curiosity, which kind of custom rendering do you want to do? I'm asking as there might be workaround to achieve what you want without having to actually write custom rendering code yourself. :)
    Thank you.

    You're welcome. Don't hesitate to let us know if you have any other questions or if there are things that you don't find very clear in my post. :)
  • jimjim
    edited January 2012
    Hi iarwain,

    First thank you very very much for replying so soon and replying so beautifully. I know you are very busy but yet you invest some of your time to reply my post, thanks once again. I think ,I now can add my custom rendering function if needed (I think that won't be needed once I learn ORX).

    I am so stupid not mentioning what I am trying to achieve. I was trying to achieve some of these effects in ORX

    011_blending.jpg

    Specially, glBlendFunc(GL_SRC_COLOR,GL_ZERO);
    glBlendFunc(GL_SRC_COLOR,GL_DST_COLOR);
    glBlendFunc(GL_ONE,GL_DST_COLOR);

    I have seen in counter strike 2D that only player viewing area is lit, so I achieved this in SDL + OpenGL.

    screenshot.jpg

    where multiple light, I mean lightmap can overlap on each other. I have used two texture for 2 lightmap but they overlap quite comfortable without showing rectangle while rendering. Here when I move my mouse only the portion of the screeen with lightmap is lit. I wanted this to make a simple shooting game in a dark arena where soldiers have light in front of their weapon. I also used this effect when the bullet hit in a wall to create sparks, also enlighting a small area around the player, when the palyer fires a heavy machine gun, which kind of effects (which are 3D) we see in 3D shooting games.

    How I can achieve this (what is shown in myscreenshot) in ORX? I would be very happy to achieve this in ORX.

    When I apply multiply blending in ORX, the transparent pixels of the image become black and it shows that the images are rectangle. So I thought that Alpha test might eliminate the transparent pixel which renders black.

    So, is there any way I can apply multiply blending and discard the transparent pixel of the image from drawing black?

    And thanks a lot once again. Sorry I first did not know how to post image here, so I may have double post my image. English is not my native so I might have some mistakes pardon me for that.

    Thank you.
  • edited January 2012
    Hi jim,

    Thanks for the details. I'm flying back home tomorrow so I won't be able to reply before another day but I think I'll post a working example on how to achieve that (and later add it to the wiki). The solution I'm thinking of is: compositing. Back in a day or two with a complete answer, sorry for the delay! :)

    PS: Your English is at least as good as mine, no worries!
  • jimjim
    edited January 2012
    Hi iarwain,
    No problem, I am ready to wait for it :)
  • edited January 2012
    I coded something quickly during my flight today. Here's a simple screenshot. Does it look like it'd fit the bill for you?

    compositing_0001.png

    I'll add a msvs project tonight and will explain all the details on the wiki if I get the time. There isn't much code, most of it is for creating the textures programmatically (I didn't have internet access nor any suitable bitmap on my machine so...).
    The top left corner is a extra viewport showing what's exactly rendered to the lightmap texture (it's using the same camera).

    If you have any questions, please let me know.
  • jimjim
    edited January 2012
    Yeah, I think this what I need, thank you very much, I was able to add custom OpneGL rendering though :) all of your replay was very helpful, thanks once again.

    Edit: I forgot to ask one thing, to get this effects, do I need to build ORX from source or the existing ORX build will do the job?
  • edited January 2012
    Ok, I added windows binaries and a project file for msvs2008.

    I'm too tired to update the wiki tonight, hopefully I'll do that before next week.

    You don't need to modify orx in order to do compositing. You actually don't need to do any custom rendering at all. Everything can be driven from config.

    However I've been using multi-line config lists which require the svn version of orx (which is much more recent than the release package and I strongly recommend to use it).

    You can find the whole project, including the sources, here: https://bitbucket.org/iarwain/compositing

    Let me know if you have any questions.
  • jimjim
    edited January 2012
    Can't get the file, I think bitbucket server is currently down so I will try later

    Edit: Now the server is available, I got the source as I use Codelite+mingw. And now only I need to understand the code. Thanks iarwain.
  • edited January 2012
    No problem!

    As for a quick explanation:

    In the code (src/compositing.cpp):
    - InitTextures():
    . creates BackgroundTexture (256x256) and sets a XOr pattern on it
    . creates LightMapTexture (display size)
    . creates SpotLightTexture (config defined size) and sets a soft alpha faded white spot on it

    Usually InitTextures() would only create the LightMapTexture as we'd have external data for our spot lights and objects. But this shows how easily all this can be created on the fly programmatically.

    - Init():
    . calls InitTextures()
    . creates all viewports
    . creates a scene

    - Run():
    . Listen to inputs to take a screenshot or quit

    That's all. Now how everything works is defined in config (data/compositing.ini).

    We have 3 viewports:

    - ControlViewport is a simple vignette that shows what is rendered by the LightMapCamera onto the LightMapTexture

    - MainViewport is the game viewport, linked to the MainCamera that "sees" all objects with a depth satisfying -1 < Z <= 1. That's where your world objects should be (here there's only a background).
    It's also where we had our LightMap object, very close to the camera so that it's rendered last with a multiply blend. It's using the LightMapTexture that has been filled by the LightMapViewport/LightMapCamera.

    - LightMapViewport is the viewport which camera will only "see" the lights as it's looking for objects with a depth satisfying -11 < Z <= -9. That's where I added 4 spot lights with additive blend, 3 colored ones and a white one.

    How it works is that the viewport are rendered in reverse order:

    - First, LightMapViewport is rendered, all the spot lights are rendered onto a black texture with a blend mode "add".
    - MainViewport is then rendered with all regular objects (none/alpha blended) and lastly with the LightMap object that's using the LightMapTexture where all the spots have been rendered. This object is using a multiply blend mode so it'll light/darken what has previously been rendered under it.

    For a game we'd be done, but for the sake of the tutorial we're rendering a last viewport, ControlViewport, using the same camera as LightMapViewport, but this time we render directly on screen instead of rendering to a texture. We also scale the viewport to make it a vignette in the upper left corner.

    Let me know if anything is unclear! :)
  • jimjim
    edited January 2012
    Hi iarwain and all,

    First of all, thanks iarwain, for his effort I am now able to do simple lightmaping without using shader :) I can continue my project again. Now I can do this, I have used a spotlight image and a background image
    compositing.jpg

    And it is way more easy than I thought. I have some questions though,

    1. I know what should be spotlight texture, but I am little confused about lightmap texture I mean what should be lightmap texture if I want to use regular image?

    2. So, do I need two viewport to work with lightmap, one for spotlights and other for game objects?

    My project is also a topdown shooting game, looks like many people are making a shooting game, it will be a real fun to see who does the best game, but as I work alone, my one will be quite a bit late, also my exam is starting at the end of this month, so the project will go very slow, but I am not concerned about deadline, it will be a good learning process for me.

    Thanks iarwain, long live ORX :)
  • edited January 2012
    jim wrote:
    Hi iarwain and all,

    First of all, thanks iarwain, for his effort I am now able to do simple lightmaping without using shader :) I can continue my project again. Now I can do this, I have used a spotlight image and a background image
    compositing.jpg

    My pleasure. I'm glad to see that it's working for you! :)
    And it is way more easy than I thought. I have some questions though,

    1. I know what should be spotlight texture, but I am little confused about lightmap texture I mean what should be lightmap texture if I want to use regular image?

    It's only an intermediate texture where we render all the spots and then use on the final scene. Its content is thus defined at runtime only and you don't need to import data from a file so I suggest to still create this one programmatically instead of using an external file.
    You can use different resolution depending on the precision you need on the lightmap. In my example I used the display resolution to be as precise as possible as the expense of more video memory.
    2. So, do I need two viewport to work with lightmap, one for spotlights and other for game objects?

    That's definitely the easiest way of doing it, as creating cameras and viewports only require a few lines of config. You could hack your way differently to avoid the need of having two viewports, but it'd result in a lot of code and I don't think it's worth it.

    If you don't want the two cameras though there's an easy trick you can do: have your camera see everything, including objects and spot lights. Link it to two different viewports (same camera). When you get the event orxRENDER_EVENT_VIEWPORT_START, if it's the lightmap viewport only accept the spotlights to be rendered (by returning orxSTATUS_SUCCESS for the orxRENDER_EVENT_OBJECT_START when you get them for spot lights and orxSTATUS_FAILURE otherwise). When you get the event orxRENDER_EVENT_VIEWPORT_START for the main viewport, it's now time to only allow normal object rendering and not spot lights anymore.
    My project is also a topdown shooting game, looks like many people are making a shooting game, it will be a real fun to see who does the best game, but as I work alone, my one will be quite a bit late, also my exam is starting at the end of this month, so the project will go very slow, but I am not concerned about deadline, it will be a good learning process for me.

    Thanks iarwain, long live ORX :)

    Best of luck for your project *and* your exams! Hope to see more of your project in the future, maybe in the projects section of the forum? :)
  • edited February 2012
    Just had some quick fun last night by modifying some config in the tutorial.
    If you get it from bitbucket, there's a new file names spaceship.ini.
    If you edit data/compositing.ini and uncomment the last line (the inclusion of spaceship.ini), you'll get a much different result, without having to change any line of code or recompile. :)

    compositing_0002.png
Sign In or Register to comment.