Yksinkertainen sulatusefekti. Perustuu tuliefektin blur filtteriin. Sisällytin tähän kaksi efektin versiota. Toisessa sulatus on jatkuvaa ja toisessa se tapahtuu vain kerran.
tarvitsee SDL -kirjastot.
Linkki valmiiseen exeen molemmista efekteistä: http://koti.mbnet.fi/peku1/melter.zip
#include "SDL.h"
#include <stdlib.h>
enum {
  SCREENWIDTH = 640,
  SCREENHEIGHT = 480,
  SCREENBPP = 32,
  SCREENFLAGS = SDL_ANYFORMAT
};
SDL_Surface* pkuva;
Uint32 buffer[SCREENWIDTH][SCREENHEIGHT];  // puskuri 1
Uint32 buffer2[SCREENWIDTH][SCREENHEIGHT]; // puskuri 2
/*
 * Pikseli kohdasta x ja y
 */
Uint32 _fastcall getpixel(SDL_Surface *surface, int x, int y)
{
    int bpp = surface->format->BytesPerPixel;
    /* Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
    switch(bpp) {
    case 1:
        return *p;
    case 2:
        return *(Uint16 *)p;
    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
            return p[0] << 16 | p[1] << 8 | p[2];
        else
            return p[0] | p[1] << 8 | p[2] << 16;
    case 4:
        return *(Uint32 *)p;
    default:
        return 0;       /* shouldn't happen, but avoids warnings */
    }
}
void DrawScene(SDL_Surface* surface, SDL_Event* event)
{
    // Lukitse pinta, jotta voimme käsitellä pikseleitä suoraan
    if ( SDL_MUSTLOCK(surface) ) {
        if ( SDL_LockSurface(surface) < 0 ) {
            fprintf(stderr, "Can't lock the screen: %s\n", SDL_GetError());
            return;
        }
    }
    // KOMMENTOI TÄMÄ, JOS HALUAT KOKEILLA Melter2:N KÄÄNTÖÄ
    // haetaan 10 pikselin pituisia viivoja kuvasta 600 kappaletta
    for (int i=0; i<600; i++)
    {
        int xrand, yrand;
        xrand = rand() % (SCREENWIDTH - 10);
        yrand = rand() % (SCREENHEIGHT - 1);
        for (int x=0; x<10; x++)
        {
            buffer[xrand + x][yrand] = getpixel(pkuva, xrand + x, yrand);
        }
    }
    Uint32 c1, c2, c3, c4;
    unsigned int cfr, cfg, cfb;
    int siirto;
    // käydään koko ruutu läpi
    for (int x=1;x<SCREENWIDTH-1;x++)
    {
        siirto = (int)rand() % 6;
        for (int y=1;y<SCREENHEIGHT-siirto;y++)
        {
            // ympäröivien pikselien keskiarvo
            c1 = buffer[x+1][y];
            c2 = buffer[x-1][y];
            c3 = buffer[x][y+1];
            c4 = buffer[x][y-1];
            // funktiot, jotka ottavat jokaisen komponentin värin keskiarvon
            cfr = (((c1 >> 16) & 0xff) + ((c2 >> 16) & 0xff) + ((c3 >> 16) & 0xff) + ((c4 >> 16) & 0xff)) / 4;
            cfg = (((c1 >> 8) & 0xff) + ((c2 >> 8) & 0xff) + ((c3 >> 8) & 0xff) + ((c4 >> 8) & 0xff)) / 4;
            cfb = ((c1 & 0xff) + (c2 & 0xff) + (c3 & 0xff) + (c4 & 0xff)) / 4;
            // kootaan taas yhteen
            buffer2[x][y+siirto] = cfr << 16 | cfg << 8 | cfb;
        }
    }
    // piirretään ruudulle
    for (int x=1;x<SCREENWIDTH-1;x++)
        for (int y=1;y<SCREENHEIGHT-1;y++)
            {
                // pointteri oikeaan pikseliin
                Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * 4; // 4 * 8 = 32(tavut->bitit)
                // pikseli ruudulle
                *(Uint32 *)p = buffer2[x][y];
                // vaihdetaan bufferit
                buffer[x][y] = buffer2[x][y];
            }
    // poistetaan lukitus
    if ( SDL_MUSTLOCK(surface) ) {
        SDL_UnlockSurface(surface);
    }
    //päivitä pinta
    SDL_UpdateRect(surface, 0, 0, 0, 0);
}
int main(int argc, char* argv[])
{
  //initialize systems
  SDL_Init(SDL_INIT_VIDEO);
  //set our at exit function
  atexit(SDL_Quit);
  //create a window
  SDL_Surface* pSurface = SDL_SetVideoMode ( SCREENWIDTH, SCREENHEIGHT, SCREENBPP, SCREENFLAGS );
  pkuva = SDL_LoadBMP("kuva.bmp");
  // OTA TÄMÄ POIS KOMMENTEISTA, JOS HALUAT KOKEILLA Melter2:STA
  /*for (int x=0;x<=SCREENWIDTH-1;x++)
        for (int y=0;y<=SCREENHEIGHT-1;y++)
            buffer[x][y] = getpixel(pkuva, x, y);*/
  // normi sdl-looppi
  SDL_Event event;
  for (;;)
  {
    if ( SDL_PollEvent ( &event ) )
    {
      if ( event.type == SDL_QUIT ) break;
    }
    DrawScene(pSurface, &event);
  }
  // vapautellaan
  SDL_FreeSurface(pSurface);
  SDL_FreeSurface(pkuva);
  return(0);
}Ihan hieno efekti.
// haetaan 10 pikselin pituisia viivoja kuvasta 400 kappaletta
for (int i=0; i<400; i++)
{
   for (int x=0; x<10; x++)
   {
       int xrand, yrand;
       xrand = rand() % (SCREENWIDTH - 10) + x;
       yrand = rand() % (SCREENHEIGHT - 1);
       buffer[xrand][yrand] = getpixel(pkuva, xrand, yrand);
   }
}Tuossa on kuitenkin joko kommentissa tai koodissa vikaa. Pisteet ei takuulla osu samalle viivalle, jos kutsut jokaiselle pisteelle uudelleen rand() funkiota :)
Olenpas ollut ajattelematon!
Korjaan tuon heti!
Edit: Sekä koodi, että binaari on nyt päivitetty
Ihan hieno.
Koska (SCREENWIDTH - 1) on nähdäkseni reunimmainen pikseli, pitäisi siinä "// käydään koko ruutu läpi" -kohdassa varmaankin olla (SCREENWIDTH - 2).
for (int x = 1; x <= SCREENWIDTH - 1; x++)
=>
for (int x = 1; x <= SCREENWIDTH - 2; x++)
=> Vielä helpompi näin kokonaisluvuilla mutta täysin samoin toimiva
for (int x = 1; x < SCREENWIDTH - 1; x++)
Lisäksi kriittinen huomautus koodin ulkoasusta: Noihin looppeihin voisi jättää välejä, niinkuin minulla tuossa yllä; OnHyvinVaivalloistaLukeaNoitaPutkeenKirjoitettujaLooppejaKutenEsimerkiksi "for (int x=1;x<=SCREENWIDTH-1;x++)" :D
eniten kyllä huolestuttaa toi kuvan koira, jonka päähän on tungettu laskettelulasit (mitä luultavammin ilman lupaa!) pipokin sillä on.
Hihii, tuo koira on söpö nuo lasit päässä ^^
Hieno efekti. Pitää mun varmaankin vaihtaa vb c++:ssaan jos sillä tollasta saa aikaan.
Wanha kuva :D Hieno efekti.
Se vinee Dll-tiedoston puuttmisesta... (MSVCR70)
http://www.dll-files.com täältä saat :)
Tuo on kyllä ihan perus dll-tiedostoja, jotka kannattaa hankkia. Yleensä ne laitetaan mukaan pakettiin isommissa ohjelmissa, mutta jätin tuon pois tilan säästämiseksi.
Aihe on jo aika vanha, joten et voi enää vastata siihen.