Coloring pixels with OpenGL.

Started by
5 comments, last by asdfg__12 15 years, 10 months ago
Hi guys, I'm an OpenGL beginner, and am trying to write a program that colors individual pixels, based off of a data structure. I start with a 2D array (named "canvas") of same dimensions as the rendering window (640x480). This 2D array is filled with "color" structs (that represent an RGB color). The idea is to read this 2D array, and use the color information within each of its structs to paint each pixel. In my program below, I fill canvas with structs of the same color ( 0.3 , 0.1 , 0.2 ) and use GL_POINTS to render them on the window. Intuition says that the result should be a window of *solid* color. However, the final render just shows a series of spread out pixels... and I don't understand why. Only shrinking the window will produce a solid color. Some help would be appreciated... thanks :) PS: And for those wondering, canvas will contain the pixel color info of a ray-traced image... so this is the first step in getting the framework working :) ======================= #include <stdlib.h> #include <stdio.h> #include <GL/glut.h> struct color { float r; float g; float b; }; const int windowSize_x = 640; const int windowSize_y = 480; color canvas[windowSize_x][windowSize_y]; void init (void) { /* background color (white) */ glClearColor( 1.0, 1.0, 1.0, 0.0 ); /* mapping of vertices to display */ glMatrixMode (GL_PROJECTION); gluOrtho2D (0.0, 200.0, 0.0, 150.0); } void display (void) { /* clear window to background color */ glClear( GL_COLOR_BUFFER_BIT ); /* render on the window by reading in canvas */ glBegin(GL_POINTS); for ( int i = 0 ; i < windowSize_x ; i++ ) { for ( int j = 0 ; j < windowSize_y ; j++ ) { glColor3f( canvas[j].r, canvas[j].g, canvas[j].b ); glVertex2i(i,j); } } glEnd(); /* ensure the display is updated */ glFlush(); } int main( int argc, char** argv ) { /* fill canvas with a solid color */ struct color test; test.r = 0.3; test.g = 0.1; test.b = 0.2; for ( int i = 0 ; i < windowSize_x ; i++ ) { for ( int j = 0 ; j < windowSize_y ; j++ ) { canvas[j] = test; } } /* configure and open window */ glutInit( &argc, argv ); glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE ); glutInitWindowPosition( 50, 100 ); glutInitWindowSize( windowSize_x , windowSize_y ); glutCreateWindow( "Fill pixels" ); /* set up OpenGL state */ init(); /* register callbacks */ glutDisplayFunc( display ); glutMainLoop(); /* enter event loop */ return( 0 ); /* not reached! */ }
Advertisement
You're going about this backwards.

(1) First have your ray tracer render the complete image in CPU memory.

(2) Create a texture object whose pixels are those of the image your ray tracer just rendered.

(3) Use that new texture object to texture map a screen aligned quad.
Yep, I understand what you're saying.

Now I'm just trying to make a framework that will let me incrementally develop the ray tracer. When the ray tracer is finished, the complete image (in CPU memory) would be stored in my 2D array that contains window pixel data.

If I tried your approach for (2) and (3)... the data flow would be:

2D array ---> texture object ---> screen-aligned quad

Unfortunately I don't know how to do that. My code just tries to use GL_POINTS to go directly from 2D array to the screen.
Have a look here: (first google result for "OpenGL Texturing")

http://www.gmonline.demon.co.uk/cscene/CS8/CS8-02.html

It requires no more than 10 lines of code.

Alternatively you can use the glDrawPixels function to directly copy the pixels to OpenGL's backbuffer.
Thanks for making me aware of glDrawPixels! I found some help on it here: http://www.gamedev.net/community/forums/topic.asp?topic_id=489283

And for reference, here's the updated code that takes a 2D color array from CPU memory, straight to the screen:

#include <stdlib.h>#include <stdio.h>#include <GL/glut.h> struct color {    float r;    float g;    float b;}; const int windowSize_x = 640;const int windowSize_y = 480;color ** canvas; void init (void) {    // background color (white)    glClearColor( 1.0, 1.0, 1.0, 0.0 );     // mapping of vertices to display    glMatrixMode (GL_PROJECTION);    gluOrtho2D (0.0, 200.0, 0.0, 150.0);} void display (void) {    // clear window to background color    glClear( GL_COLOR_BUFFER_BIT );	// fill canvas with a solid color    struct color test;    test.r = 0.3;    test.g = 0.1;    test.b = 0.2;    for ( int i = 0 ; i < windowSize_x ; i++ ) {        for ( int j = 0 ; j < windowSize_y ; j++ ) {			canvas[j] = test;            }    }     // Dynamically create a big one-dimensional array for the pixels    color *pixels = new color[windowSize_x*windowSize_y];    for ( int i = 0 ; i < windowSize_x ; i++ ) {        for ( int j = 0 ; j < windowSize_y ; j++ ) {			int idx = windowSize_x*(j)+(i);			pixels[idx].r = canvas[j].r;			pixels[idx].g = canvas[j].g;			pixels[idx].b = canvas[j].b;        }    } 	    glDrawPixels(windowSize_x,windowSize_y,GL_RGB,GL_FLOAT,pixels);    glutSwapBuffers();    // Remember to delete any dynamically created stuff!    delete[] pixels;     // ensure the display is updated    glFlush();} int main( int argc, char** argv ) {     canvas = new color * [windowSize_x];     for (int i=0; i<windowSize_x; i++)	canvas = new color[windowSize_y] ;         // configure and open window    glutInit( &argc, argv );    glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE );    glutInitWindowPosition( 50, 100 );    glutInitWindowSize( windowSize_x , windowSize_y );    glutCreateWindow( "Fill pixels" );     // set up OpenGL state    init();     // register callbacks    glutDisplayFunc( display );     glutMainLoop();     // enter event loop    for (int i=0; i<windowSize_x; i++) delete [ ] canvas ;     return( 0 );        // not reached!}


Lastly, is it possible to make an OpenGL window non-resizable?
Quote:Original post by Xenrock
Thanks for making me aware of glDrawPixels! I found some help on it here: http://www.gamedev.net/community/forums/topic.asp?topic_id=489283

And for reference, here's the updated code that takes a 2D color array from CPU memory, straight to the screen:

*** Source Snippet Removed ***

Lastly, is it possible to make an OpenGL window non-resizable?




Probably an attribute in the windows createwindow call since the resizing comes down from that outer level.

--------------------------------------------[size="1"]Ratings are Opinion, not Fact
You can't do it directly in GLUT, but you can try calling
void glutReshapeWindow(int width, int height);
within your glutReshapeFunc callback.

It might not be the perfect solution (you should probably write OS specific code if you want one), but it should do the job :)

This topic is closed to new replies.

Advertisement