Spellcaster Studios

Make it happen…

OpenGL Porting – Part 8

Well, I promised no more screenshots of just my development environment… Sorry…

screen349

This is the first run of the OpenGL port… All code is in, but (obviously enough) it’s not working properly…

If I had Pix, I could just go in and see what variable is badly set, or what’s the state of the vertex buffers, etc…

Apparently, the only thing that’s working is the “clear screen” thing, but the thing with 3d graphics is that you go from this to working condition with just a couple of changes…

Now I need to go find a OpenGL debugger or something similar… No idea if such a thing exists or not, but I recall seeing something about one of those some time ago, need to search for the link…

Anyway, it feels good just to have the whole code, and I’m pretty sure 90% of it is actually correct (the shader part, mainly)… This is probably a Z-Buffer issue (the reversed Z thing, maybe?), or a “vertex load” issue…

Now listening to “Under the Same Sky” by “Sleeping Pulse”

Now playing “The Last Door”… A great indie pixel-art Lovecraftian graphical adventure… It’s a good example that the best terror is the one inside. You don’t nee fancy graphics to scare the player (and I think they actually would detract from the experience, imagination is a powerful thing!)

Link of the Day: This is another of those games that I don’t see myself playing (I like more “driven” games), but this last trailer for “No Man’s Sky” is impressive. It uses some of the techniques I’ve been using for “Gateway”, but they do it right! Smile

OpenGL Porting – Part 7

Almost, but not quite there…

Basically, only one thing remaining: finding out what are the vertex/pixel constants required for the shader in question…

I should be able to iterate them with glGetProgramiv(program_id,GL_ACTIVE_UNIFORMS…), but this always returns 1, which can’t be…

After I solve this one, I’m golden! Smile Then it’s debug time to know why the great code I have is not doing anything!

No screenshot today, I’m sick of Visual Studios shots! Confused smile

Now listening to “The Mystery of Time” by “Avantasia”

OpenGL porting – Part 6

I swear I’m almost done with the development environment screenshots!

screen348

Today I did a lot of progress on the OpenGL porting, hopefully tomorrow I’ll be able to finally display something on the screen beyond the yellow screen I have currently!

There’s a lot of stuff that OpenGL works differently from DirectX (most of it is because of DirectX’s fixed function pipeline compatibility, that I was using until a few months ago), so I have to reverse the way some stuff works… Textures used to be something rather fixed on Cantrip (not on Spellbook, though), so a specific texture name (“map0”, for example) was going to be bound to sampler 0. On OpenGL, there is no independence of “vertex/pixel constants” and “samplers”, so I have to ask the shader where does he want me to place stuff for it.

It’s a simple change, but it makes me have to reverse the way I build certain stuff…

Now listening to “The Skrillex Remixes”

Link of the Day: I’ve been following the development of this one for some time now, and although the game doesn’t seem to be my kind of thing, it has terrific ambiance… Here’s the new trailer for it:

OpenGL porting – Part 5

Christmas season, so not much time to work on the game (not even browsing the net, if you’ve noticed the lack of link of the day)!

So…. New texture class (to abstract the OpenGL texture, which is a bit more important than in the case of DirectX). The code became prettier…

screen347

That is all…

Now listening to “Nightfall in Middle-Earth” by “Blind Guardian”

OpenGL porting – Part 4

Today I really got into the OpenGL porting… It will take a while, but it’s going nicely…

Nothing to show for it (3d graphics usually require a lot of different stuff in place before they can actually produce results), although it will be a case of “nothing to show” to “everything to show”…

3d rendering is based on few primitives:

  • Vertex buffers
  • Index buffers
  • Textures
  • Vertex Programs
  • Pixel Shaders

 

That’s mainly it… After you implement those, you can do most stuff!

screen346

Yep, I know, screenshots lately have been terrible! Smile

Now listening to “Design Your Universe” by “Epica”

OpenGL porting – Part 3

Today was a wasted day… :\

Decided to see if my changes screwed up the D3D renderer, and boy did they!

This is what I had waiting for me, instead of the main menu:

screen343

Booted up Pix, and found out that I had a the declaration of the alpha test reversed, so no big deal… Menu was back and going into the game, I had this waiting:

screen344

It seemed the Z-buffer wasn’t working, but all the sets were there, and Pix wasn’t reporting anything wrong…

After a lot of scrounging around, I finally figured out… I have a function to set renderstates (so that it checks for redundant sets, etc), but in the function that set the z-state, instead of using that function, I was using directly the device function… That wouldn’t be a problem, if I didn’t read from another variable… Which meant the setting I was placing wasn’t being acknowledged by the system, which meant that basically setting the state to true wasn’t working, but setting it to false was…

So, I got this working:

screen345

But, when working on the last issue, I noticed that Pix was still just showing the yellow screen… Everything seems to be correct, the output color of the shaders for specific functions was set correctly, etc, but no display…

After loads more time (also due to the fact that I used the wrong DirectX control panel to turn on debug mode), I figured out I had a define with the wrong name (_USE_D3D9 instead of USE_D3D9), which meant index buffers weren’t being unlocked, which led to the weird behavior on Pix (although it didn’t cause problems running the game stand-alone).

So, today was pretty much a waste… Disappointed smile

Now listening to “Somewhere in Time” by “Iron Maiden”

OpenGL porting – Part 2

Finally finished the “compile” part of the work…

The system now compiles in a OpenGL executable, and the amazing results is:

screen342

Which is to be expected, since I didn’t actually place any OpenGL code in it anymore, just breakpoints for when the code reaches that position… Smile

So, coding time!

Now listening to “The Sinister Urge” by “Rob Zombie”

OpenGL porting – Part 1

Well, nothing blog-worthy today, really…

It was mostly just clearing the D3D code (or more precisely, putting it behind the #defines that shut it down), and replacing structures and enums (like primitive type) by more cross-platform ones…

So, very boring, and very necessary…

screen341

I’ll probably spend the next few days working on this OpenGL porting, wish me luck! Smile

Now listening to “The Dark Ride” by “Helloween”

GLSL Optimizer

Today I integrated GLSL Optimizer to my shader code…

It had some quirks:

  • Doesn’t accept #line directives with name of the files, so I have to strip that when feeding it
  • Doesn’t accept OpenGL 3.30 shaders

 

This last one isn’t that bad, although I was using 3.30 shaders (the tutorials I was using were using them as well).

The problem with that I had some difficulty understanding the bindings between the actual vertex shader and the vertex buffer.

Previously I had something like this on the shader:

layout(location = 0) in vec3 vPos;
layout(location = 1) in vec4 vColor;
layout(location = 2) in vec2 vTex0;

And this on the code:

glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
    0,                  // attribute 0. 
    3,                  // size
    GL_FLOAT,           // type
    GL_FALSE,           // normalized?
    sizeof(float)*9,    // stride
    (void*)0            // array buffer offset
    );
glVertexAttribPointer(
    1,                  // attribute 1. 
    4,                  // size
    GL_FLOAT,           // type
    GL_FALSE,           // normalized?
    sizeof(float)*9,                  // stride
    (void*)(3*sizeof(float))            // array buffer offset
    );
glVertexAttribPointer(
    2,                  // attribute 2. 
    2,                  // size
    GL_FLOAT,           // type
    GL_FALSE,           // normalized?
    sizeof(float)*9,                  // stride
    (void*)(7*sizeof(float))            // array buffer offset
    );

So, it was explicit on the declaration of the shader which part of the VBO would be fed to which variable…

With 1.50 shaders, I have now:

attribute vec3 vPos;
attribute vec4 vColor;
attribute vec2 vTex0;

Which mean I should have to do something like:

glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
    glGetAttribLocation(program_id, "vPos"),
    3,                  // size
    GL_FLOAT,           // type
    GL_FALSE,           // normalized?
    sizeof(float)*9,    // stride
    (void*)0            // array buffer offset
    );
glVertexAttribPointer(
    glGetAttribLocation(program_id, "vColor"),
    4,                  // size
    GL_FLOAT,           // type
    GL_FALSE,           // normalized?
    sizeof(float)*9,                  // stride
    (void*)(3*sizeof(float))            // array buffer offset
    );
glVertexAttribPointer(
    glGetAttribLocation(program_id, "vTex0"),
    2,                  // size
    GL_FLOAT,           // type
    GL_FALSE,           // normalized?
    sizeof(float)*9,                  // stride
    (void*)(7*sizeof(float))            // array buffer offset
    );

But this seems awfully slow (there’s a text lookup there somewhere), or it means I have to make the vertex declaration part of the material, instead of part of the mesh (as it is currently).

But when I ran the program without that, it worked fine… So there must be some way the system is doing the actual binds with indexes…

After mucking around, I found out that it seems the system uses the sequential order.

So, if I declare it like above, I get:

screen338

But if I instead declare:

attribute vec3 vPos;
attribute vec2 vTex0;
attribute vec4 vColor;

I get:

screen340

Which is what I expected if I swap the texture with the color…

So, the order is important (which is what I assume in the rest of the engine, so no problems there)…

I’m still worried that on other devices/video cards this will work in another way which screws up my system, but I’ll implement it like this for now and wait for testing to see if I should swap things around…

There’s a lot of stuff on OpenGL I don’t understand yet… Especially because I feel there’s a whole lot of stuff that shouldn’t work, but works perfectly… So I really need to get some tests going, at least in the 3 main vendors (ATI, nVidia, Intel).

The good part is that GLSL Optimizer works like a charm, it builds a nice optimized shader as I wanted. The only inconvenience is that it doesn’t have proper line numbers (so there’s no match between the original shader and the optimized one, in case there’s problems), but I built a work around on that for development purposes, which compiles the un-optimized shader first (detects syntax errors, etc), and if that succeeds, then it builds the optimized… Under the release version, I can remove this, of course…

Tomorrow I’ll start working on putting the OpenGL into Cantrip, see if I can do it in the next few days… At the time of writing, next week I’m going to the Netherlands for work, so I wanted to have this done by then… At the time of reading, I came back yesterday! Smile

Now listening to “Believe in Nothing” by “Paradise Lost”

Preprocessor

Today I worked on building a preprocessor for GLSL…

Well, I didn’t exactly built a preprocessor, GLSL has one (contrary to what I understood previously), but it doesn’t work like the Direct3D one. On the D3D one, when I ask him to compile a shader, I give him a series of preprocessor macros and he uses that set. On OpenGL, I have to actually include in the text of the shader the macros so he’ll expand them.

So, basically, what I’ve built is a system to handle this (without screwing up line numbers in case of errors), and to deal with including other files (again, considering the line numbers and such).

screen338

This is the result of compiling conditionally on a #define… The above is with texturing enabled (“#define texture0_enabled true”), below is with that define set to false:

screen339

Now, on the shader I have something like:

in     vec4 fragmentColor;
in    vec2 fragmentUV;

out vec4 color;

void main()
{
    if (texture0_enabled)
    {
        color.rgba=texture(texture0,fragmentUV).rgba*fragmentColor.rgba;
    }
    else
    {
        color.rgba=fragmentColor.rgba;
    }
}

When expanded, it becomes internally something like:

in     vec4 fragmentColor;
in    vec2 fragmentUV;

out vec4 color;

void main()
{
    if (false)
    {
        color.rgba=texture(texture0,fragmentUV).rgba*fragmentColor.rgba;
    }
    else
    {
        color.rgba=fragmentColor.rgba;
    }
}

We know the system will never go into the first branch of the if, but the compiler doesn’t necessarily remove that piece of code, which means that there is a possibility (especially on mobile devices) that it will put in both branches in the compile shader and use some math to shift between one and the other (although it will always select the second one), which is inefficient. This is another place where D3D does a superb job…

Anyway, I have three different solutions to this issue. One is not use an actual if, but use something like:

in     vec4 fragmentColor;
in    vec2 fragmentUV;

out vec4 color;

void main()
{
#if (texture0_enabled)
    color.rgba=texture(texture0,fragmentUV).rgba*fragmentColor.rgba;
#else
    color.rgba=fragmentColor.rgba;
#endif
}

Which is ugly as hell and is harder to work with in normal cases. But after macro expansion, this should behave as expected.

Second, I could build a simple GLSL parser that can detect these cases and remove them… Shouldn’t be that hard, but I have solution 3, which is to use GLSL Optimizer, which is actually part of Unity 3.0+.

Hopefully, that will do all that I require (with some additional bonuses)…

Now listening to “Balls to Picasso” by “Bruce Dickinson”

Link of the Day: I have very fond memories of the ZX Spectrum (well, more accurately, the Timex 2048, but it’s of the same ilk), so this project looks awesome… So remember, Christmas is coming! Smile