als ik met glReadPixels een blok image data ophaal om vervolgens weg re schrijven naar een bitmap file, krijg ik steevast een een bitmap met correcte size, maar wel helemaal zwart. ben bang dat ik voordat ik de glReadPixels functie aanroep ergens iets fout doe. iemand die dit probleem kent?
En dit moeten we in onze glazen bol kunnen bevestigen/ontkrachten zonder dat je relevante code meepost?ben bang dat ik voordat ik de glReadPixels functie aanroep ergens iets fout doe.
mensen zouden dit probleem misschien kunnen herkennen vandaar, aangezien de store_bitmap functie aan wordt geroepen vanuit de user interface is dit geen relevante code. het zou ergens mis kunnen gaan in de render_scene, maar die code is veel te omvangrijk. dus zou iemand kunnen bedenken wat er tijdens een rendercyclus mis zou kunnen gaan waardoor de buffer waaruit glReadPixels leest, leeg zou kinnen raken ofzo (tenminste ik denk dat dat is wat er gebeurt). ik zal kijken of ik misschien nuttige code kan vinden, maar misschien kan iemand hier al iets mee
Uhm, wat dacht je van de aanroep van glReadPixels zelf, post dat eens. Dan kunnen we de meegestuurde argumenten eens onder de loep nemen
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
als je de readpixels direct na een clearbuffer (ie Color of course) dan is ie zwart.
dit doe ik
is wel bottom up het resultaat...
edit:
als je op W32 zit kun je VEEL beter een GDI call doen (honderden! keren zo snel)
zie op flipcode.com...
dit doe ik
C++:
1
| glReadPixels(0,0,width,height,GL_BGRA_EXT,GL_UNSIGNED_BYTE,(void*)pixels); |
is wel bottom up het resultaat...
edit:
als je op W32 zit kun je VEEL beter een GDI call doen (honderden! keren zo snel)
zie op flipcode.com...
[ Voor 20% gewijzigd door hobbit_be op 27-06-2003 16:34 ]
Moet je dan niet ipv height juist -height opgeven? Tenminste, zo werkt het bij BitBlt enzo....
Reden voor de bottom-up orientatie van Windows bitmaps is OS/2 backwards compatility (don't ask), dus het lijkt me sterk dat een platformonafhankelijk iets als OpenGL daar support voor heeft.
Huh? de reden waarom in windows alles bottom-up is is doodsimpel omdat nu eenmaal de normale wiskunde manier is(Cartesiaans) (staat ergens in MSDN). Tis gewoon door de jaren terug gegroeit dat het eenvoudiger was om top-bottom (ie VRAM memory enzovoorts). OpenGL zet die trend (helaas) door. Maar het verhaal (yeah i know don't ask) ivm OS/2 wil ik best wel wetencurry684 schreef op 27 juni 2003 @ 22:30:
Reden voor de bottom-up orientatie van Windows bitmaps is OS/2 backwards compatility (don't ask), dus het lijkt me sterk dat een platformonafhankelijk iets als OpenGL daar support voor heeft.
als je -heigth opgeeft? geen idee - ik denk dat OpenGL dan een ENORME screenshot wil gaan pakken
Petzold, pagina's 724 en 728hobbit_be schreef op 27 juni 2003 @ 23:14:
Maar het verhaal (yeah i know don't ask) ivm OS/2 wil ik best wel weten.
Wat wil je doen, render to texture? Daar zijn verschillende examples voor.Krooswijk.com schreef op 27 June 2003 @ 15:46:
mensen zouden dit probleem misschien kunnen herkennen vandaar, aangezien de store_bitmap functie aan wordt geroepen vanuit de user interface is dit geen relevante code. het zou ergens mis kunnen gaan in de render_scene, maar die code is veel te omvangrijk. dus zou iemand kunnen bedenken wat er tijdens een rendercyclus mis zou kunnen gaan waardoor de buffer waaruit glReadPixels leest, leeg zou kinnen raken ofzo (tenminste ik denk dat dat is wat er gebeurt). ik zal kijken of ik misschien nuttige code kan vinden, maar misschien kan iemand hier al iets mee
Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com
Curry wil het boek weer opruimen dus typt ff snel de relevante stukken over, alleerst pagina 724:
Daarna een apart hoofdstuk op 728:<H4>The DIB File Format</H4> Interestingly enough, the DIB format did not originate in Windows. It was first defined in version 1.1 of OS/2, the operating system originally developed by IBM and Microsoft beginning in de mid-1980s. OS/2 1.1 was released in 1988 and was the first version of OS/2 to include a Windows-like graphical user interface, known as the Presentation Manager (PM). The Presentation Manager included the Graphics Programming Interface (GPI), which defined the bitmap format.
That OS/2 bitmap format was then used in Windows 3.0 (released in 1990), where it came to be known as the DIB. Windows 3.0 also included a variation of the original DIB format that under Windows has come to be the standard. Additional enhancements were defined in Windows 95 (and Windows NT 4.0) and Windows 98 (and Windows 2000).
Zo leer je nog eens wat hier<H4>Bottoms up!</H4>Like most bitmap formats, the pixel bits in the DIB are organized in horizontal rows, sometimes also called "scan lines" from the terminology of video display hardware. The number of rows is equal to the bcHeight field of the BITMAPCOREHEADER structure. However, unlike most bitmap formats, the DIB begins with the bottom row of the image and proceeds up through the image.
(...)
So, in DIBs, the bottom row of the image is the first row of the file, and the top row of the image is the last row in the file. This is called a bottom-up organization. Because this organization is counter-intuitive, you may ask why it's done this way.
Well, it all goes back to the OS/2 Presentation Manager. Someone at IBM decided that all coordinate systems in PM - including those for windows, graphics and bitmaps - should be consistent. This provoked a debate: Most people, including programmers who have worked with full-screen text programming or windowing environments, think in terms of vertical coordinates that increase going down the screen. However, hardcore computer programmers approach the video display from a perspective that originates in the mathematics of analytic geometry. This involves a rectangular (or Cartesian) coordinate system where increasing vertical coordinates go up in space.
In short, the mathematicians won. Everything in PM was saddled with a bottom-left origin, including window coordinates. And that's how DIBs came to be this way.
Hey bedankt voor die post - heb Petzold niet hier en kon hem ook niet 'vinden'curry684 schreef op 28 June 2003 @ 17:27:
[...]
Curry wil het boek weer opruimen dus typt ff snel de relevante stukken over, alleerst pagina 724:
sorry mensen het heeft effe geduurd, maar dan hier een reactie:
mijn control bestaat zeg maar uit de klasse genaamd egine.cpp. in de constructor hiervan worden de nodige variabelen gezet, wat display listst gevuld, en de opengl scene geinitialiseerd. deze initialisatie als volgt (van NeHe):
hier wordt de achtergrond kleur dus al gezet, maar de buffer zelf nog niet gecleared.
daarna wordt er van die klasse constact de render functie aangeroepen als er een actie op het control wordt uitgevoerd, globaal als volgt:
dus op een gegeven moment wordt er dus data geladen. dan tekent ie naast de achtergrond ook nog het model. en zet ie opnieuw de orthogonale view vanwege de evt veranderde model omvang.
voor zover werkt het dus, als ik dus op een gegeven moment een glReadPixels doet, krijg ik echter alleen een zwarte bitmap, ook als bv in de initialisatie functie de kleur op geel heb gezet. ik denk dan ook dat het aan de glClear functies ergens ligt (zie ook 1st post hobbit_be). maar heb al van alles geprobeerd, vrnl de volgorde van de functie aanroepen te veranderen, soms zelfs tegen beter weten in, maar niets veranderde het resultaat.
hieronder volgt het mechanisme dat de bitmap file aanmaakt, dat in principe op elk moment kan worden aangeroepen:
in de engine klasse staat deze functie:
die wordt aangeroepen vanuit de interface die de control gebruikt:
of het model nou geladen is of niet er komt dus altijd een zwart plaatje uit.
op flipcode kan ik absoluut niet fatsoenlijk zoeken, heeft iemand misschien een alternatieve site over GDI calls?
mijn control bestaat zeg maar uit de klasse genaamd egine.cpp. in de constructor hiervan worden de nodige variabelen gezet, wat display listst gevuld, en de opengl scene geinitialiseerd. deze initialisatie als volgt (van NeHe):
C++:
1
2
3
4
5
6
7
8
| initialize_scene() bestaat uit: glShadeModel(GL_SMOOTH); glClearColor(0.0f,0.0f,0.0f,0.0f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); |
hier wordt de achtergrond kleur dus al gezet, maar de buffer zelf nog niet gecleared.
daarna wordt er van die klasse constact de render functie aangeroepen als er een actie op het control wordt uitgevoerd, globaal als volgt:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
| void render_scene( ) { render_background( ); if ( dataset_loaded ) { resize_scene( ); render_model( ); } SwapBuffers( device_context ); } |
dus op een gegeven moment wordt er dus data geladen. dan tekent ie naast de achtergrond ook nog het model. en zet ie opnieuw de orthogonale view vanwege de evt veranderde model omvang.
C++:
1
2
3
4
| render_background() bestaat uit: glClearColor(0.0f,0.0f,0.0f,0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
C++:
1
2
3
4
5
6
7
8
| resize_scene() bestaat uit: glViewport(0,0,width,height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(a,b,c,d,e,f); // met de juiste waarden glMatrixMode(GL_MODELVIEW); glLoadIdentity(); |
voor zover werkt het dus, als ik dus op een gegeven moment een glReadPixels doet, krijg ik echter alleen een zwarte bitmap, ook als bv in de initialisatie functie de kleur op geel heb gezet. ik denk dan ook dat het aan de glClear functies ergens ligt (zie ook 1st post hobbit_be). maar heb al van alles geprobeerd, vrnl de volgorde van de functie aanroepen te veranderen, soms zelfs tegen beter weten in, maar niets veranderde het resultaat.
hieronder volgt het mechanisme dat de bitmap file aanmaakt, dat in principe op elk moment kan worden aangeroepen:
in de engine klasse staat deze functie:
C++:
1
2
3
4
5
6
7
| get_rendered_output( GLshort left, GLshort top, GLshort width, GLshort height, GLvoid *rendered_output ) { glReadPixels( left, top, width-1, height-1, GL_RGB, GL_UNSIGNED_BYTE, rendered_output ); } |
die wordt aangeroepen vanuit de interface die de control gebruikt:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
| unsigned char *rendered_output; write_bmp() { rendered_output = malloc(width*height*3); memset(rendered_output,0,width*height*3); engine->get_rendered_output(0,0,600,400,&rendered_output); write_bitmap_file("file.bmp",width,height,(unsigned char *)rendered_output); free(rendered_output); } |
of het model nou geladen is of niet er komt dus altijd een zwart plaatje uit.
op flipcode kan ik absoluut niet fatsoenlijk zoeken, heeft iemand misschien een alternatieve site over GDI calls?
hmm je zegt dus niet wanneer je glReadPixels gebeurt he.
ik raad je aan om:
a) je drukt op een knop die zegt: 'capture frame'
b) als dit gebeurt doe je: bool capture_next_frame = true;
c) na je render
de sneller methode + links + source staat trouwens hier (GDI calls)
http://www.delphi3d.net/
ik zie trouwens GL_RGB dit moet Vast GL_BGRA_EXT zijn. (blijkbaar niet gezien naar mijn code). En maak er zeker van dat je wel degelijk de juiste res hebt he - ik zie daar hardcoded die width/height - beter effe kijken of ie wel degelijk zo groot is...
ik raad je aan om:
a) je drukt op een knop die zegt: 'capture frame'
b) als dit gebeurt doe je: bool capture_next_frame = true;
c) na je render
C++:
1
2
3
4
5
| if (c_n_f) { savebuffertodisk(); c_n_f = false; } |
de sneller methode + links + source staat trouwens hier (GDI calls)
http://www.delphi3d.net/
ik zie trouwens GL_RGB dit moet Vast GL_BGRA_EXT zijn. (blijkbaar niet gezien naar mijn code). En maak er zeker van dat je wel degelijk de juiste res hebt he - ik zie daar hardcoded die width/height - beter effe kijken of ie wel degelijk zo groot is...
inderdaad de control kan elk moment na opstarten een message get_rendering_ouput krijgen, na de druk op een button, zodat glReadPixels wordt aangeroepen. ik zal bovenstaande eens proberen.hobbit_be schreef op 01 July 2003 @ 22:32:
hmm je zegt dus niet wanneer je glReadPixels gebeurt he.
ik raad je aan om:
a) je drukt op een knop die zegt: 'capture frame'
b) als dit gebeurt doe je: bool capture_next_frame = true;
c) na je render
C++:
1 2 3 4 5 if (c_n_f) { savebuffertodisk(); c_n_f = false; }
ok, ik zal dit proberen, in mijn voorbeeld had ik nl GL_RGB staan...ik zie trouwens GL_RGB dit moet Vast GL_BGRA_EXT zijn. (blijkbaar niet gezien naar mijn code).is...
Het formaat van glReadPixels hoeft niet het formaat van de buffer te matchen. Het is puur het gevraagde pixelformaat, intern wordt het geconverteerdhobbit_be schreef op 01 July 2003 @ 22:32:
ik zie trouwens GL_RGB dit moet Vast GL_BGRA_EXT zijn. (blijkbaar niet gezien naar mijn code). En maak er zeker van dat je wel degelijk de juiste res hebt he - ik zie daar hardcoded die width/height - beter effe kijken of ie wel degelijk zo groot is...
Wat geeft glReadPixels trouwens voor error? Ik zie dat je dat nergens opvraagt... Doe dat met glGetError () direct na de call van glReadPixels ()
Roep je een glReadPixels () tussen een glBegin () en een glEnd () aan? Dat mag namelijk niet. En is de juiste buffer wel geselecteerd? Dit kun je doen met glReadBuffer () met als parameter GL_FRONT of GL_BACK. De frontbuffer is degene die op dat moment op het scherm te zien is, en de backbuffer is de buffer waar je momenteel naar het renderen bent.
Maar goed, ik vermoed dat er gewoon iets fout gaat. De reden dat het zwart is is omdat je de buffer eerst op 0 initializeerd... Vandaar dat de huidige clearcolor er ook niets mee te maken heeft. glReadPixels () leest dus geen zwarte buffer, maar gewoon simpelweg helemaal niets. Dit kun je natuurlijk makkelijk controleren door de buffer bijvoorbeeld met een witte kleur te initializeren
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
ik heb wel al geprobeerd een glGetError voor de aanroep van SwapBuffers, dan krijg ik altijd code 0 terug, dus geen probleem. Ik zal verder morgen kijken of het ligt aan het feit dat de juiste buffer niet is geselecteerd..oisyn schreef op 02 July 2003 @ 14:13:
Wat geeft glReadPixels trouwens voor error? Ik zie dat je dat nergens opvraagt... Doe dat met glGetError () direct na de call van glReadPixels ()
Roep je een glReadPixels () tussen een glBegin () en een glEnd () aan? Dat mag namelijk niet. En is de juiste buffer wel geselecteerd? Dit kun je doen met glReadBuffer () met als parameter GL_FRONT of GL_BACK. De frontbuffer is degene die op dat moment op het scherm te zien is, en de backbuffer is de buffer waar je momenteel naar het renderen bent.
zoals ik al zei in mijn lange post, als ik bv een glClearColor doe met de kleur geel dan krijg ik ook gewoon een zwarte bitmap. ik zal eens verder gaan stoeien en mijn verdere bevindingen posten..oisyn schreef op 02 July 2003 @ 14:13:
Maar goed, ik vermoed dat er gewoon iets fout gaat. De reden dat het zwart is is omdat je de buffer eerst op 0 initializeerd... Vandaar dat de huidige clearcolor er ook niets mee te maken heeft. glReadPixels () leest dus geen zwarte buffer, maar gewoon simpelweg helemaal niets. Dit kun je natuurlijk makkelijk controleren door de buffer bijvoorbeeld met een witte kleur te initializeren
[ Voor 3% gewijzigd door Krooswijk.com op 02-07-2003 22:56 ]
ik heb nu geprobeerd voor het aanroepen van de glRadPixels functie de buffer met glReadBuffer zowel op GL_FRONT als GL_BACK te zetten, bij beide krijg ik gewoon een zwarte bitmap, na de glReadPixels ook een glGetError gedaan, en beide keren code 0.
verder wil ik dit eerst werkend hebben, voordat ik me in GDI calls verdiep. wat betreft die GL_BGRA_EXT, ik gebruik dus de GL_RGB en converteer bij het wegschrijven naar de bitmap.
ik vraag me dus af of mijn render functie wel klopt, is dit wel de goeie opzet? heeft eimand daar ervaring mee?
verder wil ik dit eerst werkend hebben, voordat ik me in GDI calls verdiep. wat betreft die GL_BGRA_EXT, ik gebruik dus de GL_RGB en converteer bij het wegschrijven naar de bitmap.
ik vraag me dus af of mijn render functie wel klopt, is dit wel de goeie opzet? heeft eimand daar ervaring mee?
maar wanneer doe je de readpixels nu?
.
oisyn: hmm ik heb toen ook geprobeert met GL_RGB maar dat deed nooit niets en ergens (is al 3 jaar (oh my G!) geleden ) gevonden dat daar toch iets niet klopte... Wat ik wel gek vind is dat je een 100% zwarte bitmap hebt:
als je namelijk je memory niet zero-ed (wat meeste C/C++ niet doen en ook niet hoeven te doen) dan krijg je een meer ruisachtig effect. Dat ie zwart is wil alvast zeggen dat er iets gecopiert word(?t).
oisyn: hmm ik heb toen ook geprobeert met GL_RGB maar dat deed nooit niets en ergens (is al 3 jaar (oh my G!) geleden ) gevonden dat daar toch iets niet klopte... Wat ik wel gek vind is dat je een 100% zwarte bitmap hebt:
als je namelijk je memory niet zero-ed (wat meeste C/C++ niet doen en ook niet hoeven te doen) dan krijg je een meer ruisachtig effect. Dat ie zwart is wil alvast zeggen dat er iets gecopiert word(?t).
nadat de dataset is geladen, kan deze op ieder moment plaatsvinden, dor het klikken op de button. zodat op de moment de buffer wordt uitgelezen en de bitmap wordt geschreven...
ik denk dus dat er iets misgaat met de volgorde van de aanroepen binnen de resize, initialize en render functies, alleen zou ik echt niet meer weten waar? heb alles al een keer gecontroleerd...hobbit_be schreef op 03 July 2003 @ 17:24:
...
als je namelijk je memory niet zero-ed (wat meeste C/C++ niet doen en ook niet hoeven te doen) dan krijg je een meer ruisachtig effect. Dat ie zwart is wil alvast zeggen dat er iets gecopiert word(?t).
...
daarom zei ik ook al in één van m'n eerste posts, dat het naar mijns inziens met een glClear te maken had. zou iemand mijn structuur kunnen checken?
[ Voor 10% gewijzigd door Krooswijk.com op 03-07-2003 18:06 ]
en je doet dit NA glSwapBuffers? - heb je mijn truukje nu geimplementeerd dat als je op de button drukt niet direct gaat uitlezen maar flag zet zodat ie na de volgende render en dus na SWAP het saved?.Krooswijk.com schreef op 03 July 2003 @ 18:04:
[...]
nadat de dataset is geladen, kan deze op ieder moment plaatsvinden, dor het klikken op de button. zodat op de moment de buffer wordt uitgelezen en de bitmap wordt geschreven...
Overgigens zie ik net dat je wel je mem cleared - maak het eens rood ipv black (dus memset met 0xFF). Kun je effe checken of we wel uberhaupt iets wordt gedaan door OGL...
en is dat dan direct NA glReadPixels () ?Krooswijk.com schreef op 02 July 2003 @ 17:15:
[...]
ik heb wel al geprobeerd een glGetError voor de aanroep van SwapBuffers, dan krijg ik altijd code 0 terug, dus geen probleem.
Nee, niet met glClearColor (). Ik heb het over de initializatie van het geheugenzoals ik al zei in mijn lange post, als ik bv een glClearColor doe met de kleur geel dan krijg ik ook gewoon een zwarte bitmap. ik zal eens verder gaan stoeien en mijn verdere bevindingen posten.
C++:
1
2
3
4
5
6
7
8
9
10
11
| write_bmp() { rendered_output = malloc(width*height*3); memset(rendered_output,0,width*height*3); // <-- HIERZO!!! engine->get_rendered_output(0,0,600,400,&rendered_output); write_bitmap_file("file.bmp",width,height,(unsigned char *)rendered_output); free(rendered_output); } |
die memset zorgt dat je buffer zwart is.
met 0xff wordt het dus withobbit_be schreef op 03 July 2003 @ 18:46:
Overgigens zie ik net dat je wel je mem cleared - maak het eens rood ipv black (dus memset met 0xFF). Kun je effe checken of we wel uberhaupt iets wordt gedaan door OGL...
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
heb dit nu inderdaad uitgevoerd, en inderdaad wordt het plaatje nu wit gekleurd, dus het ligt dan niet aan de buffers zoals ik dacht, maar opebgl vult dan gewoon niet image_data. ik heb nu eht volgende stukje code direct achter mijn SwapBuffers( ) staan:.oisyn schreef op 04 July 2003 @ 00:00:
met 0xff wordt het dus witEn dit is nou precies wat ik in mijn vorige post voorstelde
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| SwapBuffers( device_context ); if( retrieving_output ) { void *rendered_output; char *file_name = "output//output.bmp"; rendered_output = malloc( width * height * 3 ); memset( rendered_output, 0xFF, width * height * 3 ); engine->get_rendered_output( 0, height, width, height, &rendered_output ); if ( write_bitmap_file( file_name, width, height, (unsigned char*)rendered_output ) ) { free( rendered_output ); return( false ); } retrieving_output = false; } |
waarbij retrieving_output dus op true wordt gezet als er op de button wordt geklikt. ik heb overigens ook de glGetError direct na de glReadPixels gedaan, ook dan krijg ik error code 0 terug.
[ Voor 10% gewijzigd door Krooswijk.com op 04-07-2003 11:00 ]
engine->get_rendered_output( 0, height, width, height, &rendered_output ); ?
die 1st height moet toch 0 zijn niet?
die 1st height moet toch 0 zijn niet?
[ Voor 7% gewijzigd door hobbit_be op 04-07-2003 12:32 ]
hmmm, ik meende dat ie in de linkerbenedenhoek de origin nam. maar je hebt volkomen gelijk, die moet inderdaad 0 zijn. dit is mijn functie:
hij geeft alleen keiveel access violations bij het uitvoeren van de glReadPixels... effe verder kijken
twee posts hierboven staat:
eigenlijk moet rendered_output van het type unsigned char * zijn, maar dan krijg ik een error bij regel 2, omdat malloc een void * retourneert. ik denk dat het daar aan ligt, effe uitzoeken hoe ik die evt om kan zetten, want casten mag niet.
C++:
1
2
3
4
5
6
7
8
9
10
11
| GLvoid ENGINE :: get_rendered_output( GLshort left, GLshort top, GLshort width, GLshort height, GLvoid *rendered_output ) /* * Returns the pixel data currently rendered to the screen. */ { glReadPixels( left, top, width-1, height-1, GL_RGB, GL_UNSIGNED_BYTE, rendered_output ); } |
hij geeft alleen keiveel access violations bij het uitvoeren van de glReadPixels... effe verder kijken
twee posts hierboven staat:
C++:
1
2
3
| void *rendered_output; rendered_output = malloc( width * height * 3 ); memset( rendered_output, 0xFF, width * height * 3 ); |
eigenlijk moet rendered_output van het type unsigned char * zijn, maar dan krijg ik een error bij regel 2, omdat malloc een void * retourneert. ik denk dat het daar aan ligt, effe uitzoeken hoe ik die evt om kan zetten, want casten mag niet.
[ Voor 28% gewijzigd door Krooswijk.com op 04-07-2003 13:32 ]
nou het werkt allemaal goed nu, de gebruiker van de control kan aan de control zijn 3d output vragen om er vervolgens zelf mee een bitmap of van een serie een movie file te maken. echter de rode en de blauwe kleur worden steevast omgedraaid. ok dit probleem heeft waarschijnlijk iedereen meegemaakt. maarrr...dit is wat ik doe:
in de setup_pixelformat_descriptor:
in de get_rendered_output:
ïk krijg bij het gebruik van GL_RGBA veel access violations en bij GL_RGBA_EXT juist dat 'ruis' beeld waar hobbit_be het over had.
voordat ik de bitmap data weg ga schrijven, dus na de headers, converteer ik per drie waardes, steeds de 1e en de 3e. Dus de rode en de blauwe, dit zou goed moeten werken toch? Als volgt:
zo zouden toch de juiste RGB waarden naar de bitmap geschreven worden? ik zie niet wat er mis gaat, maar het is iig zeker dat de blauwe en de rode values worden omgedraaid...
in de setup_pixelformat_descriptor:
C++:
1
| PFD_TYPE_RGBA |
in de get_rendered_output:
C++:
1
| glReadPixels(0,0,width,height,GL_RGB,GL_UNSIGNED_BYTE,rendered_output) |
ïk krijg bij het gebruik van GL_RGBA veel access violations en bij GL_RGBA_EXT juist dat 'ruis' beeld waar hobbit_be het over had.
voordat ik de bitmap data weg ga schrijven, dus na de headers, converteer ik per drie waardes, steeds de 1e en de 3e. Dus de rode en de blauwe, dit zou goed moeten werken toch? Als volgt:
C++:
1
2
3
4
5
6
7
8
| unsigned char temp; ... for ( short i = 0 ; i < bitmapInfoHeader.biSizeImage ; i += 3 ) { temp = rendered_output[i]; rendered_output[i] = rendered_output[i+2]; rendered_output[i+2] = temp; } |
zo zouden toch de juiste RGB waarden naar de bitmap geschreven worden? ik zie niet wat er mis gaat, maar het is iig zeker dat de blauwe en de rode values worden omgedraaid...
yow dude - als ik .oisyn mag geloven gaat die readcall de native bitdepth (meestal 32bit) omzetten naar 24bit (32bit) - maar het hangt ervan af hoe ie die gaat omzetten natuurlijk.
Kroos: je beseft dat als je GL_RGBA (_EXT) je dan 4 bytes / pixel hebt dus dan moet je de malloc ook zo veranderen. Aan te raden voor jouw is dat je een struct gebruik:
of RGBA met een extra a. Normaal zul je een beetje moeten spelen (ahem) of je nu r,g,b of bgr (meestal deze) volgorde van bytes krijgt.
Kroos: je beseft dat als je GL_RGBA (_EXT) je dan 4 bytes / pixel hebt dus dan moet je de malloc ook zo veranderen. Aan te raden voor jouw is dat je een struct gebruik:
C:
1
2
3
4
5
6
7
8
9
| struct RGB { unsigned char b,g,r; } RGB* image = malloc(w*h*sizeof(RGB)); readpizels(......., (void*)image); OpenGL is C dus casten naar een void* is heus niet vies en een noodzaak hier... |
of RGBA met een extra a. Normaal zul je een beetje moeten spelen (ahem) of je nu r,g,b of bgr (meestal deze) volgorde van bytes krijgt.
het wordt RGBhobbit_be schreef op 05 July 2003 @ 13:46:
yow dude - als ik .oisyn mag geloven gaat die readcall de native bitdepth (meestal 32bit) omzetten naar 24bit (32bit) - maar het hangt ervan af hoe ie die gaat omzetten natuurlijk.
Dus de eerste byte wordt de rode kleur, die daarna de groene kleur, en de derde de blauwe kleur. De 4e wordt vervolgens weer rood, etc.
En idd, windows gebruikt altijd een BGR layout, niet RGB, dus je zal het of handmatig moeten omzetten, of idd gewoon een andere layout op moeten geven (da's het makkelijkst
Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.
dat is inderdaad precies wat ik wil. zoals ik hierboven beschreven heb, verander ik ze dus handmatig. op de een of andere manier wil het dus niet werken, als ik voor RGB kies, dien ik dus ook voor 24 bits bitmaps te kiezen, toch? en bij RGBA voor 32 bit?.oisyn schreef op 07 July 2003 @ 13:07:[...]
het wordt RGB
Dus de eerste byte wordt de rode kleur, die daarna de groene kleur, en de derde de blauwe kleur. De 4e wordt vervolgens weer rood, etc.
als ik dan een andere layout opgeef, dan is het dus al GL_RGBA_EXT, nu moet ik dus bij alloceren/wegschrijven en aanmaken pixelformatdescriptor rekening houden met 32 bits toch?.oisyn schreef op 07 July 2003 @ 13:07:
En idd, windows gebruikt altijd een BGR layout, niet RGB, dus je zal het of handmatig moeten omzetten, of idd gewoon een andere layout op moeten geven (da's het makkelijkst)
wat ik ga uitproberen vrijdag is igg het volgende, alles met 24bits initialiseren, de bitmap data met GL_RGB binnenhalen en voor het wegschrijven converten naar de BGR. (als ik dit nog niet eerder had uitgeprobeerd
Pagina: 1