Placage de relief
A propos du code
Projecteur
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
int main(int argc, char* argv[])
{
// init the window
gfx.init("Bump", SCREEN_WIDTH, SCREEN_HEIGHT);
gfx.init2D();
gfx.clearScreen(Color(0, 0, 0, SDL_ALPHA_OPAQUE));
int width, height;
Color* background = tga.load("background.tga", &width, &height);
Color* lightImage = tga.load("light.tga", &width, &height);
Puis on boucle sur chaque pixel et on récupère la lumière.
while (sys.isQuitRequested() == false)
{
// draw the image
for (int y = 0; y < SCREEN_HEIGHT; ++y)
for (int x = 0; x < SCREEN_WIDTH; ++x)
{
// compute the light intensity
int light = lightImage[y * SCREEN_WIDTH + x].r;
On recupère la couleur du fond, on la multiplie par la lumière, et on dessine le pixel.
// get the background color
Color col = background[y * SCREEN_WIDTH + x];
// modulate the color by the light intensity
col.r = col.r * light / 255;
col.g = col.g * light / 255;
col.b = col.b * light / 255;
gfx.setPixel(x, y, col);
}
Télécharger le code source
Télécharger l'exécutable pour Windows
Le reste du programme est classique. On gère les évènements et on termine la boucle principale.
Faire bouger la lumière
int lightPosX, lightPosY;
float angle = 0.0f;
A l'intérieur de la boucle principale, on va calculer la position de la lumière
// move the light
lightPosX = 160 * sin(angle);
lightPosY = 120 * sin(2.0f * angle);
angle += 0.02f;
Et quand on lit le pixel de lumière, on va ajouter cette position et vérifier qu'on reste bien à l'intérieur de
int light = 0;
int lightX = x + lightPosX;
int lightY = y + lightPosY;
if (lightX >= 0 && lightX < SCREEN_WIDTH &&
lightY >= 0 && lightY < SCREEN_HEIGHT)
{
light = lightImage[lightY * SCREEN_WIDTH + lightX].r;
}
Télécharger le code source
Télécharger l'exécutable pour Windows
L'effet de relief
Color* bump = tga.load("bump.tga", &width, &height);
Maintenant pour chaque point de cette image, on a besoin d'avoir les "dérivées" suivant x et y.
// compute the bump disturbance
int deltaX = 0;
int deltaY = 0;
if (x < SCREEN_WIDTH - 1 && y < SCREEN_HEIGHT - 1)
{
int current = bump[ y * SCREEN_WIDTH + x ].r;
int right = bump[ y * SCREEN_WIDTH + (x + 1)].r;
int down = bump[(y + 1) * SCREEN_WIDTH + x ].r;
deltaX = right - current;
deltaY = down - current;
}
Puis on ajoute ces deltas à la position de la lumière.
int lightX = x + lightPosX + deltaX;
int lightY = y + lightPosY + deltaY;
Télécharger le code source
Télécharger l'exécutable pour Windows
Maintenant l'image semble sortir du bois.
Gravure sur bois
int lightX = x + lightPosX - deltaX;
int lightY = y + lightPosY - deltaY;
Télécharger le code source
Télécharger l'exécutable pour Windows
Et voilà à quoi ça ressemble:
int lightX = x + lightPosX - deltaX * 2;
int lightY = y + lightPosY - deltaY * 2;
Télécharger le code source
Télécharger l'exécutable pour Windows
Et maintenant ça a l'air vraiment profond.