glUniform1f() is working!

I faced this problem for the first time a year ago, while working for my parallax mapping demo, and I met it again these days, in which I’m busy to fine tune my depth of field demo to permit keyboard driven parameters tweaking.

Bug

The issue I’m talking about is quite seriuos, on my machine it is impossible to pass a float uniform variable to a shader, and I’m not the only one reporting it:

The first link is a forum thread from GameDev written by a girl whose applications suffer from this annoying issue, he has written a proof of concept which works perfectly on my box, i.e. float uniforms are NOT passed. ๐Ÿ™‚
But it has been the third one which made me think about how to fix the problem: it has been reported that, after calling glewInit(), glUniform*f() functions work again.

The first thing I did, of course, was to download and investigate inside GLEW sources to see what was happening inside that magic function. What it does, actually, is redefining all the GL function pointers calling glXGetProcAddress() for everyone of them, I thought it would have been a good thing to try to replicate this behaviour in my programs, and I was right! ๐Ÿ˜€

This is what I added to my sources for the incriminated function to work:

PFNGLUNIFORM1FPROC glUniform1f = NULL;
glUniform1f = (PFNGLUNIFORM1FPROC)glXGetProcAddress((const GLubyte*)"glUniform1f");

This also seems to explain why my Python shader demo didn’t suffer from all of this, I think that PyOpenGL initializes itself retrieving the addresses for all the GL functions it needs.

IMPORTANT UPDATE
M3xican, the shader master came with THE solution, just add -DGL_GLEXT_PROTOTYPES to CFLAGS.
Hail to the master! ๐Ÿ˜€

Image post-processing with shaders

I’m back to work after many months, university exams take really a lot of time…
For I am a bit rusty on GLSL programming, but willing to learn new things anyway, I have decided to begin with a simple yet interesting topic, image processing.

GLSL_imgpro

The whole thing, actually, needs two rendering passes and relies heavily on Frame Buffer Objects because:

  1. You render the scene to an off-screen texture.
  2. You render a quad covering the entire screen and binded to the previously written texture.
  3. You make a shader process the fragments resulted from rendering this textured quad, i.e. post-processing the original scene.

In this program post-processing is demanded to convolution matrices calculated with these kernels:

GLfloat kernels[7][9] = {
    { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f}, /* Identity */
    { 0.0f,-1.0f, 0.0f,-1.0f, 5.0f,-1.0f, 0.0f,-1.0f, 0.0f}, /* Sharpen */
    { 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f}, /* Blur */
    { 1.0f, 2.0f, 1.0f, 2.0f, 4.0f, 2.0f, 1.0f, 2.0f, 1.0f}, /* Gaussian blur */
    { 0.0f, 0.0f, 0.0f,-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f}, /* Edge enhance */
    { 1.0f, 1.0f, 1.0f, 1.0f, 8.0f, 1.0f, 1.0f, 1.0f, 1.0f}, /* Edge detect */
    { 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,-1.0f}  /* Emboss */
};

The final fragment color is calculated by a simple shader which, at the core, just performs the following:

for(i = -1; i <= 1; i++) for(j = -1; j <= 1; j++) { coord = gl_TexCoord[0].st + vec2(float(i) * (1.0/float(Width)) * float(Dist), float(j) * (1.0/float(Height)) * float(Dist)); sum += Kernel[i+1][j+1] * texture2D(Tex0, coord.xy); contrib += Kernel[i+1][j+1]; } gl_FragColor = sum/contrib; [/sourcecode] When the user chooses a filter, the application updates the kernel currently in use with a call to: [sourcecode language='cpp'] loc = glGetUniformLocation(sh.p2, "Dist"); glUniform1i(loc, dist); loc = glGetUniformLocation(sh.p2, "Kernel"); glUniformMatrix3fv(loc, 1, GL_FALSE, &kernels[curker]); [/sourcecode] Dist is a user defined parameter (you can change it using arrows) that defines the distance in pixels from the center to the contributing sample. Since a month I have created a YouTube Channel, now you can have an idea of how this demo works without downloading and compiling the source code: have a look at this link! ๐Ÿ˜‰

GameCon 2007

GameCon is the only game and videogame showroom in Italy, and, fortunately for me, it is held in my city. ๐Ÿ˜‰
Last year it changed its name from N-joy to the current one and received much more advertising and public visibility, therefore me and M3xican decided to attend it. ๐Ÿ˜‰

GameCon Logo

We had the possibility to view, and what is more important, to test next-gen consoles the way they deserved, on huge LCDs! ๐Ÿ˜€
There were a lot of XBox 360 running the most recent games, like the first UE3 engine powered one, the stunning Gears of War, some Nintendo Wii made their first Italian apparition at the show and, last but not least, I have heard that the last day a Playstation 3 was previewed!
You could play with many Nintendo DS and some powerful PCs, subscribe to rewarded tournaments in many games, admire original Benoรฎt Sokal illustrations (which unfortunately couldn’t be there as scheduled), moreover some space had been dedicated to a lot of different board games and somebody was enjoying cosplaying.
However, something more interesting happened some weeks before the event, when I got in touch with its Cultural Director.
Our emails shared the common vision to evolve the current target of attendees to include game developers too, for example organizing interesting conferences and gathering the most influential Italian exponents of the industry.

This was what happened this very year, with the announce of Game in Italy 2007, thus on Saturday me and M3xican went there, loaded with great expectations (like the hope to assist to a little GDC wannabe ๐Ÿ˜‰ )!
Even if a lot of important Italian software houses were invited, even if Rasmus Poulsen (a concept artist working for IO Interactive) was present as a guest star, it has been a disappointment.
The event was too modest to even feature a fair-sized room, it was not only so small that just a dozen guys could sit inside, but so hot (damned lamps!) that you couldn’t stand at the entrance, ignoring for a while the fact that there was only one speaker and that you could barely hear what it was said by the participants.
It was interesting to notice that outside the room there was a big LCD showing what was happening inside, but we were surprised to discover that nothing was audible, it was mute! ๐Ÿ˜ฏ
I only hope they have recorded the speeches…

To draw a conclusion, it failed to meet our expectations, we couldn’t attend the conferences while the rest of the show wasn’t so extraordinary, it has been less interesting than the previous year, maybe because next-generation gaming is now current-generation… ๐Ÿ˜‰
I only hope that next year Game in Italy gains the space, the attention and the visibility it deserves!

Back in blog

My blog is back, at last!
I was starting to lose the hope for a data rescue and beginning from scratch (as a matter of fact I wrote the Photon post before this one), but, fortunately, it was not the case…

WordPress Logo

Our marsnomercy.org server has been down since the 31st of July for a stupid fan problem, the Mars site/wiki/bug tracker and my little blog have followed it. ๐Ÿ™
On that server, in my mailbox, I used to collect blog backups… yes, I’ve been so stupid to weekly archive database backups on the same machine running the DBMS… ๐Ÿ™‚
But now, thanks to Dekki, our great 3d artist and sysadmin, we have all the data back on a replacement server!

But, as you have probably noticed, the blog is now hosted on Netsons, a reliable and feature rich free hosting solution, which is also the home of my new Encelo’s Projectz site, now running on Drupal.

Today I’ve been busy with xml imports/exports, ftp uploads and tons of manual phpmyadmin updates, but it has been worth the effort.
I have installed the latest WordPress from scratch (welcome integrated tagging! ;)), updated all the plugins, imported the access statistics and made a Last.fm and a Ohloh widget.

The blog is back and it is here to stay! ๐Ÿ˜‰

Hail to the Photon

On Thursday I assembled Photon, my brand new workstation, the day after I received also the surround speakers set and the fantastic wide monitor.

For the detailed configuration you can have a look at the page written for this purpose. ๐Ÿ™‚

Photon

The specifications are not extraordinary (except for the monitor, maybe, which is a bit larger than usual, but you all know that the display area of a monitor is never enough ๐Ÿ˜‰ ), Photon was built with the aim to be cheap but effective, no bells and whistles, but a solid and balanced platform.
Moreover, buying from the entry level segment avoid the situation when you wake up a morning and discover that your hardware is worth 25% less than the previous day…

With Photon I have the possibility to be part of the next-gen gaming era, to exploit multi-threaded programming with a real performance gain, to explore the Shader Model 4 and OpenAL benefits… and to run a heavy Compiz Fusion configuration at 1680×1050! ๐Ÿ˜‰

PySoy, a month after

A bit more than a month of SoC work has passed now, PySoy is alive and getting better day after day, and since some days you can even get a taste of it!
After the release of the GPLv3 our SVN repository has been opened to the public, read more on Arc’s blog.

Textured Pyramid

About the point of view of my application the project is proceeding well and we can show you a textured pyramid at last (as usual I have to thank Arc for the huge help ๐Ÿ˜‰ )! ๐Ÿ™‚

I’ve left my normal mapping experiments behind for a moment (after having discovered how to create correct object space normal maps in Blender with the “six colored lights” hack ๐Ÿ˜€ ), and I’m now working on the lighting system which will represent the base for every non trivial texturing technique.

Much more is yet to come, stay tuned!

I’m 24 and I’m a gamedev :)

I turned 24 today!
It has been a year of studying, graphics/game programming and, of course, entertaining. ๐Ÿ™‚

The year that has just sterted will be characterized by a summer of work instead…
Working for the Summer of Code is hard, it is a real work after all, but also funny, and getting paid for enjoying writing Python (actually Pyrex) code and researching on graphics techniques is fantastic. ๐Ÿ™‚

It also legitimate my status, I’m a game developer. ๐Ÿ˜‰

A slighty smarter setup.py for PySoy r64

While working on PySoy I was really disappointed by the policy adopted by the setup.py script, anytime I launched it the result was a recompilation of *all* the sources, this was really annoying and slow.

Python transparent logo

What came after was just that I decided to hack it a bit and make it behave more like a standard build tool, that is to control the modification time of a source file in order to choose whether it is updated or need a fresh compilation.

The new policy for the script is very simple, but useful enough to save plenty of time.
It is aware of the following cases (thank you Arc for tips on how to deal with the last one):

  • a .c file is missing, pyrex should compile the .pyx file
  • a .pyx file is newer than the corresponding .c file, an update is needed
  • a .pxd file is newer than any .pyx file, a global recompile is needed

The last point is not optimal, of course, but it’s a lot simpler than specifying all the .pxd dependecies for any .pyx file, and, anyway, quite close to being optimal, because of the thick web of cross dependencies which actually exists in PySoy.

Here is the piece of code which performs the magic:

# Convert Pyrex sources to C if using Trunk
if version == 'Trunk' :
  import os
  from stat import *
  from Pyrex.Compiler import Main

  options = Main.CompilationOptions(defaults=Main.default_options, include_path=include_path)

  newestpxd = 0
  for dir in include_path:
    for pxdsource in os.listdir(dir):
      pxdsource_path = (os.path.join(dir, pxdsource))

      if os.path.isfile(pxdsource_path) and pxdsource.rsplit('.', 1)[1] == 'pxd':
        if os.stat(pxdsource_path)[ST_MTIME] > newestpxd:
          newestpxd = os.stat(pxdsource_path)[ST_MTIME]

  for pyxsource in pyrex_sources:
    compilation_needed = False

    if os.path.isfile(pyxsource.rsplit('.', 1)[0] + '.c'):
      ctime = os.stat(pyxsource.rsplit('.', 1)[0] + '.c')[ST_MTIME]
    else:
      ctime = 0

    if newestpxd > ctime:
      compilation_needed = True
    elif os.stat(pyxsource)[ST_MTIME] > ctime:
      compilation_needed = True

    if compilation_needed:
      Main.compile(pyxsource, options)

Well, actually Arc commited r65 too, simplifying the conditionals of the script even more, but this is another story. ๐Ÿ™‚
Anyway, I hope to have made another little step into making the life of our team a bit simpler. ๐Ÿ˜‰

My Summer of Code begins with PySoy r44

Summer of Code has started just today (even if currently it is only a “Spring of Code” ๐Ÿ˜€ ) but a little contribution of mine has already made his way inside the SVN repository of PySoy.

But let’s start from the beginning…
After having shown to Arc an early draft of an UML class diagram for the current code I decided to come back to work on some test code I had written in the afternoon.
It was just a classical spinning cube demo to actually compare PyOpenGL versus Pyrex speed, I don’t report the results here because they are quite identical, if I haven’t done any mistake it should be the absolute minimum complexity of the code which actually determined this result.
Anyway, even without this proof I firmly believe in the power and speed of Pyrex. ๐Ÿ˜‰

Going back to my commit, my changes affected a small yet important area of the code, I think we will remember it in the future. ๐Ÿ™‚

BEFORE
In src/windows-glx/soy.windows.pyx:

gl.glClear(0x4100)

AFTER
In include/gl.pxd:

[...]
# Constants
  ctypedef enum:
    [...]
    # glPush/PopAttrib bits
    GL_DEPTH_BUFFER_BIT
    GL_COLOR_BUFFER_BIT
[...]

In src/windows-glx/soy.windows.pyx:

gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)

Was it better before or now? ๐Ÿ˜‰

Python 2.5 support in globs r46

Yes, I should have written about it when I actually committed the revision, but I forgot completely. ๐Ÿ˜€
About two months after Python 2.5 has been moved to the current repository of Arch I begun to think that maybe it was time to support the new release of our beloved language/interpreter.

Python transparent logo

I don’t know if it can be called “support”, but at least GL O.B.S. is now aware of it. ๐Ÿ™‚
The changes are very simple yet of some importance.
First of all, pysqlite is not needed anymore if you have the integrated sqlite3 module:

if sys.version_info[:2] >= (2, 5):
  from sqlite3 import dbapi2 as sqlite
else:
  from pysqlite2 import dbapi2 as sqlite

Moreover I make use of the updated API of the webbrowser module:

if sys.version_info[:2] >= (2, 5):
  webbrowser.open_new_tab(Globs.BROWSE_URL)
else:
  webbrowser.Netscape('firefox').open(Globs.BROWSE_URL)

Another addition, not related with the support of Python 2.5, is the check_ver function, which checks if a particular version of OpenGL is available on the machine running GL O.B.S., this have opened the possibility to add an OpenGL 2 only test like GLSL_Parallax into benchmarks r47.

Python and GL O.B.S. are getting better and better. ๐Ÿ˜‰