c++openglpixeltracegldrawpixels

Why is glDrawPixels not working in here?


Here's the code. The output is a greyish square - all the time, no matter what the input is and its clearly wrong. My objective is to be able to have all the pixels stored somewhere and display them so I can move on to a simple ray tracer and I can't seem to figure out this glDrawPixels thing.

#include <stdlib.h>
#include <GL/glut.h >

using namespace std;

struct RGBType {

    float r;
    float g;
    float b;
    //float a;
};


void display(void)
{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    RGBType *pixels = new RGBType[250*250];

    for (int x = 0; x < 250; x++) {
        for (int y = 0; y < 250; y++) {

               pixels->r = 0;
               pixels->g = 1;
               pixels->b = 1;
               //pixels->a = 200;
          }
     }


    glTexSubImage2D(GL_TEXTURE_2D,0,0,0,250,250,GL_RGB,GL_UNSIGNED_BYTE,pixels);


    //glColor3f(1.0,1.0,1.0);
    glBegin(GL_POLYGON);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(1.0, 0.0, 0.0);
        glVertex3f(1.0, 1.0, 0.0);
        glVertex3f(0.0, 1.0, 0.0);
    glEnd();


    glutSwapBuffers();
}

void init(void)
{
    //select clearing (background) color
    glClearColor(0.0, 0.0, 0.0, 0.0);

    //initialize viewing values 
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}


int main(int argc, char** argv)
{
    //Initialise GLUT with command-line parameters. 
    glutInit(&argc, argv);

    //Set Display Mode
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

    //Set the window size
    glutInitWindowSize(250,250);

    //Set the window position
    glutInitWindowPosition(100,100);

    //Create the window
    glutCreateWindow("Ray Tracer");

    //Call init (initialise GLUT
    init();

    //Call "display" function
    glutDisplayFunc(display);

    //Enter the GLUT event loop
    glutMainLoop();

    return 0;
}

Solution

  • struct RGBType {
        float r;
        float g;
        float b;
        ^^^^^^^^ all floats here...
        //float a;
    };
    
    ...
    
    RGBType *pixels = new RGBType[250*250];
    
    ...
    
    glTexSubImage2D(GL_TEXTURE_2D,0,0,0,250,250,GL_RGB,GL_UNSIGNED_BYTE,pixels);
                                                       ^^^^^^^^^^^^^^^^ wat
    

    You're telling OpenGL to interpret pixels as an array of unsigned chars, read them in groups of four bytes, and use the first three bytes of each four as RGB channels.

    Don't lie to OpenGL. Rarely works out for you in the end.

    Try GL_FLOAT instead.

    And create an actual texture object first.

    And bind that texture object before you try to upload data to it.

    And specify some texture coordinates for your polygon.

    And enable texturing before your draw your polygon.

    Something like this:

    #include <GL/glut.h>
    
    struct RGBType 
    {
        float r;
        float g;
        float b;
    };
    
    GLuint tex = 0;
    void init()
    {
        RGBType pixels[ 250*250 ];
    
        RGBType* temp = pixels;
        for (int x = 0; x < 250; x++) 
        {
            for (int y = 0; y < 250; y++) 
            {
                temp->r = 0;
                temp->g = 1;
                temp->b = 1;
                temp++;
            }
        }
    
        glGenTextures( 1, &tex );
        glBindTexture( GL_TEXTURE_2D, tex );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 250, 250, 0, GL_RGB, GL_FLOAT, NULL );
        glTexSubImage2D(GL_TEXTURE_2D,0,0,0,250,250,GL_RGB,GL_FLOAT,pixels);
    }
    
    void display(void)
    {
        glClearColor(0, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT);
    
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-2, 2, -2, 2, -1, 1);
    
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    
        glColor3ub( 255, 255, 255 );
        glEnable( GL_TEXTURE_2D );
        glBindTexture( GL_TEXTURE_2D, tex );
        glBegin(GL_QUADS);
        glTexCoord2i( 0, 0 );
        glVertex2i( 0, 0 );
        glTexCoord2i( 1, 0 );
        glVertex2i( 1, 0 );
        glTexCoord2i( 1, 1 );
        glVertex2i( 1, 1 );
        glTexCoord2i( 0, 1 );
        glVertex2i( 0, 1 );
        glEnd();
    
        glutSwapBuffers();
    }
    
    int main(int argc, char** argv)
    {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
        glutInitWindowSize(250,250);
        glutCreateWindow("Ray Tracer");
        init();
        glutDisplayFunc(display);
        glutMainLoop();
        return 0;
    }