Category Archives: Tutorials

Lessons, snippets, proceedings and everything required to complete a task or improve your knowledge.

How to parse gl.xml and produce your own loading library

In the previous article I emphasized the importance of not having a third-party loading library like glew because OpenGL is too complex and unpredictible. For example, if you want to implement a videogame with an average graphics and a large audience of users, probably OpenGL 2.1 is enough. At this point, you may need to load only that part of the library and make the right check of the extensions or just use the functions that have been promoted to the core of the current version. Remember that an extension is not guaranteed to be present on that version of OpenGL if it's not a core feature and this kind of extensions has been introduced after 3.0 to maintain the forward compatibility.

For instance, it's useful to check the extension GL_ARB_vertex_buffer_object only on OpenGL 1.4 (in that case you may want to use glBindBufferARB instead of glBindBuffer) but not on superior versions because it has been promoted to the core from the version 1.5 onward. The same applies to other versions of the core and extensions. If you target OpenGL 2.1, you have to be sure that the extensions tipically used by 2.1 applications have not been promoted to the latest OpenGL 4.5 version and to check the extenions on previous versions of the library, making sure to use the appropriate vendor prefix, like ARB. Even if with glew you can make this kind of check before using the loaded functions, I don't recommend it because glewInit() is going to load also parts that you don't want to use and you run the risk to understimate the importance of checking the capabilities.

Anyway, reading the OpenGL spec and add manually the required extensions is a time expensive job that you may don't have the time to do. Recently, the Khronos group has released an xml file where there is a detailed description of the extensions and the functions for every version of the library, it is also used to generate the gl.h and the glext.h header files with a script in Python. In the same way, you can program a script that parses the gl.xml file to generate your own loading library, making the appropriate check of the extensions and including only the part that you really need to load on your project. You can find the gl.xml file here:

Continue reading

Why loading libraries are dangerous to develop OpenGL applications

OpenGL is not so easy to use. The API exposes thousand of functions that are grouped into extensions and core features that you have to check for every single display driver release or the 3D application may not work. Since OpenGL is a graphics library used to program cool gfx effects without a serious knowledge of the underlying display driver, a large range of developers is tempted to use it regardless of the technical problems. For example, the functions are loaded "automagically" by an external loading library (like glew) and they are used to produce the desired effect, pretending that they are available everywhere. Of course this is totally wrong because OpenGL is scattered into dozens of extensions and core features that are linked to the "target" version that you want to support. Loading libraries like glew are dangerous because they try to load all the available OpenGL functions implemented by the display driver without making a proper check, giving you the illusion that the problem doesn't exist. The main problem with this approach is that you cannot develop a good OpenGL application without taking the following decision:

- How much OpenGL versions and extensions I have to support?

From this choice you can define the graphics aspect of the application and how to scale it to support a large range of display drivers, including the physical hardware and the driver supported by the virtual machines. For example, VirtualBox with guest addictions uses chromium 1.9 that comes with OpenGL 2.1 and GLSL 1.20, so your application won't start if you programmed it using OpenGL 4.5, or even worse you won't start also on graphics cards that support maximum the version 4.4 (that is very recent). For this reason, it's necessary to have a full awareness of the OpenGL scalability principles that must be applied to start on most of the available graphics cards, reducing or improving the graphics quality on the base of the available version that you decided to target. With this level of awareness, you will realize that you don't need any kind of loading library to use OpenGL, but only a good check of the available features, that you can program by yourself. Moreover, libraries like glew are the worst because they are implemented to replace the official gl.h and glext.h header files with a custom version anchored to the OpenGL version supported by that particular glew version.

Continue reading

How the deprecated OpenGL matrix model works

Even if nowadays everybody seems to drop OpenGL methods when they are deprecated on the core profile, it doesn't mean that you don't need to use them in compatibity profile or that you don't want to know how they work. I searched on the web to find more information on how the old and deprecated OpenGL matrices are implemented and I didn't find anything (except tutorials on how to use them!). My doubt was mainly about the operations order, because I needed to make a C++ implementation of them, maintaining the same exact behavior. I used OpenGL matrices In the past without worrying about how they were implemented, I had a precise idea but now I have to be 100% sure. Even if we know how to implement operations between matrices, the row-column product doesn't have the commutative property so the internal implementation can make the difference. At the end, my question is:

- What is the matrix row-column order and how the product is implemented on OpenGL?

Tired of finding pages saying how they are useless and deprecated now, I had to check by myself the Mesa source code to find what I was searching for:

P = A * B;

P[0] = A[0] * B[0] + A[4] * B[1] + A[8] * B[2] + A[12] * B[3];
P[4] = A[0] * B[4] + A[4] * B[5] + A[8] * B[6] + A[12] * B[7];
P[8] = A[0] * B[8] + A[4] * B[9] + A[8] * B[10] + A[12] * B[11];
P[12] = A[0] * B[12] + A[4] * B[13] + A[8] * B[14] + A[12] * B[15];

P[1] = A[1] * B[0] + A[5] * B[1] + A[9] * B[2] + A[13] * B[3];
P[5] = A[1] * B[4] + A[5] * B[5] + A[9] * B[6] + A[13] * B[7];
P[9] = A[1] * B[8] + A[5] * B[9] + A[9] * B[10] + A[13] * B[11];
P[13] = A[1] * B[12] + A[5] * B[13] + A[9] * B[14] + A[13] * B[15];

P[2] = A[2] * B[0] + A[6] * B[1] + A[10] * B[2] + A[14] * B[3];
P[6] = A[2] * B[4] + A[6] * B[5] + A[10] * B[6] + A[14] * B[7];
P[10] = A[2] * B[8] + A[6] * B[9] + A[10] * B[10] + A[14] * B[11];
P[14] = A[2] * B[12] + A[6] * B[13] + A[10] * B[14] + A[14] * B[15];

P[3] = A[3] * B[0] + A[7] * B[1] + A[11] * B[2] + A[15] * B[3];
P[7] = A[3] * B[4] + A[7] * B[5] + A[11] * B[6] + A[15] * B[7];
P[11] = A[3] * B[8] + A[7] * B[9] + A[11] * B[10] + A[15] * B[11];
P[15] = A[3] * B[12] + A[7] * B[13] + A[11] * B[14] + A[15] * B[15];

where A and B are 4x4 matrices and P is the result of the product. As you can see, this snippet clarifies how rows and columns are internally ordered and how the product is implemented. In conclusion, the OpenGL methods to modify the current matrix are implemented by Mesa in this way:

Continue reading

How to create photorealistic textures (Ita)

Le texture fotorealistiche vengono usate per migliorare l'impatto visivo di molte simulazioni tridimensionali nei motori grafici moderni. Le texture non sono altro che immagini digitali con la caratteristica peculiare di fornire all'osservatore un'impressione di continuità se accostate ripetutamente l'una accanto all'altra in orizzontale e in verticale.

Lo scopo di questo tutorial è quello di capire come è possibile creare immagini del genere, usando come base di partenza dei temi fotografati nella vita reale (muri, pavimenti, roccie, etc...) ed effettuare le trasformazioni necessarie con pochi strumenti e senza ricorrere a particolari software per la generazione procedurale (che in questo caso non servono proprio a niente).   (screenshot preso dal sito http://cgtextures.com/)

Continue reading

Get Ascii code from keyboard on windows/c++ (Ita)

Gli eventi windows per la gestione dell'input della tastiera non restituiscono direttamente un codice ascii ma uno molto più intrippato chiamato Virtual Key, studiato per consentire anche la gestione di quei tasti che non fanno parte del testo (come i cursori, il tasto stampa, etc...) o la conversione diretta in formati più avanzati, come l'unicode.

Continue reading

Graphics effects using chunky-to-planar on amiga/c (Ita)

Il cosiddetto modo planar è sempre stato un impedimento per quei programmatori che avevano intenzione di creare effetti grafici tridimensionali sull'Amiga, cosa che invece riusciva facilissima sui pc perchè supportavano nativamente il modo chunky. Esiste infatti una famosa disputa tra chi difendeva le peculiarità del planar (utile per i giochi 2d) e chi invece ne esaltava i difetti (inutile per i giochi 3d), resta comunque una verità indiscutibile: senza chunky non è possibile lavorare direttamente con i pixel, e questa è una gravissima limitazione per chi vuole realizzare effetti grafici di qualsiasi tipo, cioè non ancorati a certe particolari caratteristiche dell'hardware, come rotazioni di immagini, motori in texture mapping, bump mapping, etc.

Fortunatamente esistono delle tecniche di conversione che permettono di minimizzare queste differenze e rendere la vita più facile ai programmatori che tutt'ora, per scopi puramente hobbystici, hanno intenzione di sviluppare qualche piccolo lavoro grafico su questa macchina del passato. Anch'io mi ci sono cimentato con esiti positivi e dato che in rete il materiale scarseggia ho deciso di pubblicare in questo articolo un piccolo progetto che incorpora le tecniche di conversione c2p e p2c più veloci (programmate in assembler) con un esempio di utilizzo all'interno di un listato in c per la visualizzazione degli effetti grafici in tempo reale.

Continue reading

Image scaling with subsampling technique (Ita)

Il sottocampionamento, noto anche come subsampling, è un algoritmo che permette di ridurre il numero di campioni di un segnale digitale oppure di un'immagine senza andare incontro, durante l'inevitabile perdita di informazione, al famoso difetto di aliasing. E' importante ridurre il più possibile questo difetto, perchè l'aliasing potrebbe provocare nei suoni un fastidioso brusio oppure nelle immagini una percezione di forme imprecise o addirittura totalmente alterate.

Continue reading

Fast Fourier Transform with Digital Images (Ita)

All'interno dello zip potete trovare un articolo che tratta il filtraggio delle immagini digitali mediante trasformata FFT 2D (Fast Fourier Transform - Trasformata di Fourier Veloce). Viene fatta un'ampia introduzione sulla teoria che sta alla base di questa tecnica ed analizzate nel dettaglio le diverse strategie implementative dal punto di vista della programmazione in c.

Nel pacchetto sono inclusi i sorgenti completi in c, alcune immagini in formato pgm per fare delle prove e l'eseguibile nel caso abbiate subito voglia di vedere qualcosa di pratico. Oltre alla realizzazione della trasformata di fourier veloce, per poter lavorare in modo completo sullo spettro delle frequenze, sono stati presi in esame tre tipi di filtri diversi: ideale, butterworth e gaussiano. Viene affrontato anche il tema dell'uso dei filtri passabanda come soluzione per correggere eventuali disturbi periodici all'interno di un'immagine.

©2008 Gianpaolo Ingegneri