Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: RGB Pikseli

Sivun loppuun

FaCo [01.09.2006 14:20:33]

#

Moikka kaikki

Voisiko joku kertoa miten voin asettaa pikselille värit RGB:nä? eli (255,0,0); ? osaan piirtää sen vain 0xFF0000

kayttaja-4976 [01.09.2006 14:23:38]

#

0xrrggbb jos tuota hait?

FaCo [01.09.2006 14:32:21]

#

En.. vaan sitä ,että miten sen voi suoraan pistää RGB:nä

Koska teen paintin tyylistä piirto ohjelmaa ja laitan värit muuttumaan RGB:nä. Eli värit tulisi syttää RGB:nä syöttö box:hin. R,G,B; Eli miten sen pikselin värin voisi asettaa RGB:nä ??

kayttaja-4976 [01.09.2006 14:50:21]

#

WinApi-komennolla Setpixel(hdc, x, y, double color);. Se on vain jälleen kerran luvattoman hidas, joten kannattaa tutustua OpenGL:än ja SDL:n tarjoamiin funktioihin.

Edit: OpenGL:n ratkaisu menee jotakuinkin näin:

int x=1;
int y=1;
int z=0;

glBegin(glPoints);
    glColor3f(1.0f, 1.0f, 1.0f); // Tulostetaan valkoista
    glVertex3f(x, y, z);         // Piirretään pikseli
glEnd();
return 0; // Programmers don't die, they end themselves by return 0;.

FaCo [01.09.2006 15:05:20]

#

Entäs SDL?

kayttaja-4976 [01.09.2006 15:09:41]

#

En ole perehtynyt asiaan, mutta http://www.ferzkopp.net/Software/SDL_gfx-2.0/ löytyi seuraavaa:

   int boxColor(SDL_Surface * dst, Sint16 x1, Sint16 y1,
			    Sint16 x2, Sint16 y2, Uint32 color);
   int boxRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2,
			   Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a);

Väri annetaan ilmeisesti 32-bittisenä etumerkittömänä kokonaislukuna, 0xrrggbb.

FaCo [01.09.2006 15:14:32]

#

eli siis eikö sitä voi syöttää RGB:nä näin (255,0,0)
vai pitääkö se aina syöttää 0xrrggbb meinaa tuo on aika huono jos pitää tehdä koodi joka esim plussaa koko ajan punaista..

kayttaja-4976 [01.09.2006 15:18:39]

#

unsigned int vari;
vari = 0x306219;
vari += 0x12000; //Lisätään variin yksi arvo punaista ja kaksikymmentä vihreää. Vari on nyt 0x318219.

Näinkö?

Edit: Sitten kanssa voit tehdä näin:

int r;
int g;
int b;
int rgb;

//Sitten konverttaat ne heksamuotoon, mikähän se math.h:n funktio olikaan

r = r * 10000;
g = g * 100;

rgb = r + g + b;

//Ja loppuun vaikka näin:
r++;

FaCo [01.09.2006 15:28:47]

#

Entäs jos int punainen = 20; ja vari = 0x000000;
miten tuon punaisen saisi syötettyä väriin niin että vari olisi vari = 0x200000;

kayttaja-4976 [01.09.2006 15:31:09]

#

Lasket heksa-arvon 20 ja sitten listäät sen variin * 10000.

FaCo [01.09.2006 15:34:07]

#

Voisitko näyttää miten :)???

kayttaja-4976 [01.09.2006 15:36:24]

#

Tässä juuri etsin sitä sulle, mutta ei onnistanut. :( Kokeile vaikka hex(int); funktiota tietenkin math.h includettuna. Kannattaa katsoa https://www.ohjelmointiputka.net/oppaat/opas.php?tunnus=luvut

kayttaja-3842 [01.09.2006 16:09:10]

#

HEX:in saa laskettua aikasta helpostikkin..Tässä olisi tälläinen koodi pätkä joka laskee hex arvon.

#include <math.h>

 char *GetHEX(unsigned long x)
 {
   if(!x)
     return("0");

 short len=short(ceil(log(x+1)/log(16))-1);
 char *HEX="0123456789ABCDEF";
 char *result=new(char[len+2]);
 result[len+1]='\0';

   for(;len>=0;len--,x/=16)
     result[len]=HEX[x%16];

 delete []HEX;
 return(result);
 }

FaCo [01.09.2006 16:15:44]

#

Noh jos kerran mulla on nyt arvo hex:nä miten voin syöttää sen väri muuttujaan??

kayttaja-4976 [01.09.2006 16:23:49]

#

Jos r on vaikka A5, g on DD ja b on 0, silloin kerrot r:n 10000 ja g:n 100 kuten tuossa aiemmin jo sanoin. Lopuksi ynnäät kaikki yhteen.

FaCo [01.09.2006 16:33:00]

#

niin mut enhän minä voi tallentaa int:hen HEX:aa :D. Tulee virhe ja jos laitan sen char:na sitten en voi kertoa sitä 10000.

kayttaja-4976 [01.09.2006 16:36:22]

#

int = kokonaisluku
hex = 16-lukujärjestelmä
int != char
int <3 hex
char != hex!

kayttaja-3842 [01.09.2006 16:58:34]

#

En kyl tajuu miksi haluat tehä tuon noin vaikeasti?
Laita värin kohtaan näin:

SDL_MapRGB(pinta->format,0,255,0);

kayttaja-4976 [01.09.2006 16:59:32]

#

kayttaja-3842 kirjoitti:

En kyl tajuu miksi haluat tehä tuon noin vaikeasti?
Laita värin kohtaan näin:

SDL_MapRGB(pinta->format,0,255,0);

Jaa siellä oli tuollainenkin :o En ole guru SDL:ssä ja taisin johtaa FaCo:n väärille jäljille. Sori.

kayttaja-3842 [01.09.2006 17:27:59]

#

Noh eihän kukaan kaikkea osaa.. :)

rndprogy [01.09.2006 19:12:10]

#

Optimaalisemmin.
color = R<<16|G<<8|B;

Legu [01.09.2006 22:30:55]

#

Uint32 RGB(Uint8 R, Uint8 G, Uint8 B)
{
   return R << 16 | G << 8 | B;
}

//tai sitten ehkäpä nopeampi?
#define RGB(r,g,b) (r << 16 | g << 8 | b)

Tollasta tarkotit?

kayttaja-4976 [01.09.2006 22:49:42]

#

Paljonko noilla on nopeuseroa? Siis jos tekee sellasen vaikka pelin niin itseänikin kiinnostaa tietää montako millisekuntia säästetään?

Legu [01.09.2006 22:57:20]

#

No käytännössä nopeus molemmissa on kuitenkin niin suuri ettei sillä niin ole väliä.

Metabolix [02.09.2006 12:59:38]

#

Nopeuseroa on niin paljon, että makromuotoinen tekee tasan nuo operaatiot eli kolme muistilukua, kaksi bittisiirtoa ja kaksi tai-operaatiota, kun taas funktiomallisessa mahdollisesti työnnetään arvot pinoon (kolme push-käskyä), kutsutaan funktiota, funktiossa sählätään pino-osoittimella ainakin kolmen tai neljän käskyn verran ja lopuksi vielä palataan kutsuntapaikkaan. Eli tuossa tapauksessa makro on kannattavampi, vaikka ei tuo ero nykykoneella varmastikaan ole se ohjelman suurin ongelma.

Legu [02.09.2006 13:04:27]

#

Metabolix kirjoitti:

Eli tuossa tapauksessa makro on kannattavampi, vaikka ei tuo ero nykykoneella varmastikaan ole se ohjelman suurin ongelma.

Tuota juuri tarkoitin. Kun koitin jotain mittailla niin eroa ei meinannut syntyä millään.

Metabolix [02.09.2006 14:19:23]

#

Jaa, kyllä minä saan tuosta aivan helposti näkyviin eron, ainakin kaksinkertainen aika kuluu funktiolla. Mitä nyt gcc:n assembly-tulosteesta katselin seuraavan koodin tuloksia, funktion sisältö ja kutsuminen yhdessä aiheuttavat kolminkertaisen määrän käskyjä makroon verrattuna:

#define m1(r,g,b) ((uint8_t)r << 16 | (uint8_t)g << 8 | (uint8_t)b)

inline uint32_t f1(uint8_t r, uint8_t g, uint8_t b)
{
    return r << 16 | g << 8 | b;
}

int main(void)
{
    uint32_t i,j,k,l;
    l = m1(i,j,k);
    l = f1(i,j,k);
    return 0;
}

Optimointilippu -O2 ilmeisesti pelastaa tilanteen, mutta juuri tuohon nimenomaiseen koodiin sitä ei voi soveltaa, koska se poistaa koko toimitukset turhina, ja en nyt jaksa sen enempää asiaa analysoida. Assemblyllä kirjoittettasessa tuosta operaatiosta taitaisi tulla vain kolme muistilukua ja -kirjoitusta, tavu kerrallaan alimmat tavut kohdalleen. C:llä tuo onnistuisi muuttamalla kohde-Uint32 osoittimeksi ja tyypinmuunnoksella edeleen Uint8-osoittimeksi, jolloin siihen voisi taulukon tapaan laittaa väriarvot.

Deewiant [02.09.2006 18:31:09]

#

Kannattaa muistaa, että joillain koneilla väriarvojen järjestys 32-bittisessä kokonaisluvussa ei ole RGBA vaan ABGR. Huomautus tästä löytyy SDL:n wikistä kohtaa SDL_CreateRGBSurface.

Metabolix [02.09.2006 18:38:23]

#

... joten kannattaa joko pakottaa SDL käyttämään tiettyä järjestystä (onnistuu) tai shiftailla vakioiden sijaan pintojen formaatista löytyvillä arvoilla (hitaampaa) tai tehdä makrot kummallekin tapaukselle ja tarkistaa SDL:n vakioista, kumpaa tulee käyttää.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta