Sign in to follow this  

Coloring pixels with OpenGL.

This topic is 3463 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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[i][j].r, canvas[i][j].g, canvas[i][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[i][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! */ }

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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[i][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[i][j].r;
pixels[idx].g = canvas[i][j].g;
pixels[idx].b = canvas[i][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[i] = 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[i] ;

return( 0 ); // not reached!
}





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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 :)

Share this post


Link to post
Share on other sites

This topic is 3463 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this