Thread: OpenGL/Glut problems.

  1. #1
    Registered User
    Join Date
    Oct 2011
    Location
    Derby, UK
    Posts
    8

    OpenGL/Glut problems.

    Hi All,

    I've tried the first tutorial on this excellent website (although some of the OpenGL stuff there now seems to be depreciated).

    I've made some amendments to the first tutorial so that it displays a picture of my daughter in the cube, and also I may use the keys Z and X to rotate the cube (simple stuff really). Now what I'm trying to do is to use space to chance the image of my daughter which is displayed.

    I have two files 'Ruby1.bmp' and 'Ruby2.bmp'; by default, it loads the first mentioned, but although I know the condition works, it won't load a new image on the spacebar being pressed.

    I've commented the relevant code in the following:

    Code:
    #include <iostream>
    #include <string>
    #include <stdlib.h>
    #include <GL/glut.h>
    #include "imageloader.h"
    using namespace std;
    const float BOX_SIZE = 7.0f; // The length of each side of the cube
    float _angle = 0;            // The rotation of the box
    // Okay, we're going to attempt to change images here... Here goes:
    char picture1[]="Ruby1.bmp";
    char picture2[]="Ruby2.bmp";
    // This should track of the picture in the cube, ie, 0=Ruby1.bmp, 1=Ruby2.bmp:
    short int pic=0;
    // This will tell another part of the programme that space has been pressed:
    short int space=0;
    // This is just to check that the first default picture is only loaded onces:
    short int once=0;
    // Here is our global variable of image
    // If only this would update dynamically!!!
    Image* image;
    GLuint _textureId;           // The OpenGL id of the texture
    // This routine or sub-routine or method or function checks for key events:
    void handleKeypress(unsigned char key, int x, int y)
    {
        switch (key)
        {
            if (pic>1)
            {
                pic=0;
            }
            case 0x20:  //Space key
                pic=pic+1;
                space=1;
                break;
            case 0x58:  // X key
                _angle=_angle+0.75f;
                break;
            case 0x5a:  // Z key
                _angle=_angle-0.75f;
                break;
            case 0x1b:  //Escape key
                exit(0);
                break;
            default:
                space=0;
                break;
        }
    }
    // Makes the image into a texture, and returns the id of the texture
    GLuint loadTexture(Image* image)
    {
        GLuint textureId;
        glGenTextures(1, &textureId);
        glBindTexture(GL_TEXTURE_2D, textureId);
        glTexImage2D(GL_TEXTURE_2D,
                0,
                GL_RGB,
                image->width, image->height,
                0,
                GL_RGB,
                GL_UNSIGNED_BYTE,
                image->pixels);
        return textureId;
    }
    // Here is the rendering routine.../function/whatever that sets everything up:
    void initRendering()
    {
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
        glEnable(GL_NORMALIZE);
        glEnable(GL_COLOR_MATERIAL);
        // This should only load the default picture once:
        if(once==0)
        {
            image=loadBMP(picture1);
            ++once;
        }
        _textureId = loadTexture(image);
        delete image;
    }
    // What the following is trying to do is to load another BMP image in, or flip the
    // pictures, as Image* image is declared as a global as far as I can tell.
    void loadImage()
    {
        // We'll also check if Space has actually been depressed too, just to stop
        // any unnecessary switching of pictures - if it worked that is:
        if(pic==0 && space==1)
        {
            image=loadBMP(picture1);
            space=0;
        }
        else
            if(pic==1 && space==1)
            {
                image=loadBMP(picture2);
                space=0;
            }
        delete image;
    }
    // Presumabely, this handles windows resizing:
    void handleResize(int w, int h)
    {
        glViewport(0, 0, w, h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(45.0, (float)w / (float)h, 1.0, 200.0);
    }
    // This draws the filled vector that we has set up:
    void drawScene()
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(0.0f, 0.0f, -20.0f);
        GLfloat ambientLight[] = {0.3f, 0.3f, 0.3f, 1.0f};
        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
        GLfloat lightColor[] = {0.7f, 0.7f, 0.7f, 1.0f};
        GLfloat lightPos[] = {-2 * BOX_SIZE, BOX_SIZE, 4 * BOX_SIZE, 1.0f};
        glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
        glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
        glRotatef(-_angle, 1.0f, 1.0f, 0.0f);
        glBegin(GL_QUADS);
        // Top face
        glColor3f(1.0f, 1.0f, 0.0f);
        glNormal3f(0.0, 1.0f, 0.0f);
        glVertex3f(-BOX_SIZE / 2, BOX_SIZE / 2, -BOX_SIZE / 2);
        glVertex3f(-BOX_SIZE / 2, BOX_SIZE / 2, BOX_SIZE / 2);
        glVertex3f(BOX_SIZE / 2, BOX_SIZE / 2, BOX_SIZE / 2);
        glVertex3f(BOX_SIZE / 2, BOX_SIZE / 2, -BOX_SIZE / 2);
        // Bottom face
        glColor3f(1.0f, 0.0f, 1.0f);
        glNormal3f(0.0, -1.0f, 0.0f);
        glVertex3f(-BOX_SIZE / 2, -BOX_SIZE / 2, -BOX_SIZE / 2);
        glVertex3f(BOX_SIZE / 2, -BOX_SIZE / 2, -BOX_SIZE / 2);
        glVertex3f(BOX_SIZE / 2, -BOX_SIZE / 2, BOX_SIZE / 2);
        glVertex3f(-BOX_SIZE / 2, -BOX_SIZE / 2, BOX_SIZE / 2);
        // Left face
        glNormal3f(-1.0, 0.0f, 0.0f);
        glColor3f(0.0f, 1.0f, 1.0f);
        glVertex3f(-BOX_SIZE / 2, -BOX_SIZE / 2, -BOX_SIZE / 2);
        glVertex3f(-BOX_SIZE / 2, -BOX_SIZE / 2, BOX_SIZE / 2);
        glColor3f(0.0f, 0.0f, 1.0f);
        glVertex3f(-BOX_SIZE / 2, BOX_SIZE / 2, BOX_SIZE / 2);
        glVertex3f(-BOX_SIZE / 2, BOX_SIZE / 2, -BOX_SIZE / 2);
        // Right face
        glNormal3f(1.0, 0.0f, 0.0f);
        glColor3f(1.0f, 0.0f, 0.0f);
        glVertex3f(BOX_SIZE / 2, -BOX_SIZE / 2, -BOX_SIZE / 2);
        glVertex3f(BOX_SIZE / 2, BOX_SIZE / 2, -BOX_SIZE / 2);
        glColor3f(0.0f, 1.0f, 0.0f);
        glVertex3f(BOX_SIZE / 2, BOX_SIZE / 2, BOX_SIZE / 2);
        glVertex3f(BOX_SIZE / 2, -BOX_SIZE / 2, BOX_SIZE / 2);
        glEnd();
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, _textureId);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glColor3f(1.0f, 1.0f, 1.0f);
        glBegin(GL_QUADS);
        // Front face
        glNormal3f(0.0, 0.0f, 1.0f);
        glTexCoord2f(0.0f, 0.0f);
        glVertex3f(-BOX_SIZE / 2, -BOX_SIZE / 2, BOX_SIZE / 2);
        glTexCoord2f(1.0f, 0.0f);
        glVertex3f(BOX_SIZE / 2, -BOX_SIZE / 2, BOX_SIZE / 2);
        glTexCoord2f(1.0f, 1.0f);
        glVertex3f(BOX_SIZE / 2, BOX_SIZE / 2, BOX_SIZE / 2);
        glTexCoord2f(0.0f, 1.0f);
        glVertex3f(-BOX_SIZE / 2, BOX_SIZE / 2, BOX_SIZE / 2);
        // Back face
        glNormal3f(0.0, 0.0f, -1.0f);
        glTexCoord2f(0.0f, 0.0f);
        glVertex3f(-BOX_SIZE / 2, -BOX_SIZE / 2, -BOX_SIZE / 2);
        glTexCoord2f(1.0f, 0.0f);
        glVertex3f(-BOX_SIZE / 2, BOX_SIZE / 2, -BOX_SIZE / 2);
        glTexCoord2f(1.0f, 1.0f);
        glVertex3f(BOX_SIZE / 2, BOX_SIZE / 2, -BOX_SIZE / 2);
        glTexCoord2f(0.0f, 1.0f);
        glVertex3f(BOX_SIZE / 2, -BOX_SIZE / 2, -BOX_SIZE / 2);
        glEnd();
        glDisable(GL_TEXTURE_2D);
        glutSwapBuffers();
    }
    // Called every 25 milliseconds - I wonder how many cycles to the ms?
    void update(int value)
    {
        // Commented out as this is now handled elsewhere:
        //_angle += 0.5f;
        if (_angle>360)
        {
            _angle-=360;
        }
        glutPostRedisplay();
        glutTimerFunc(25, update, 0);
    }
    // And here is our main bit:
    int main(int argc, char** argv)
    {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
        glutInitWindowSize(640, 400);
        glutCreateWindow("Donkeysoft MMXI");
        loadImage();
        initRendering();
        glutDisplayFunc(drawScene);
        glutKeyboardFunc(handleKeypress);
        glutReshapeFunc(handleResize);
        glutTimerFunc(25, update, 0);
        glutMainLoop();
        return 0;
    }


    If anyone can provide any clues as to why I can't load a new bitmap into image and display that please?

    Once I've worked this out, I'll work out rotating with mouse events.

    Many thanks in advanced,

    S.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > delete image;
    Why do you keep doing this almost immediately after loading the image?

    Perhaps delete the old one just BEFORE you load a new one.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Oct 2011
    Location
    Derby, UK
    Posts
    8
    That's how it was written in the framework - thanks, I'll try your tip :-)

    Cheers,

    S.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Hmm, if "loadImage()" is supposed to do the work, I do not see how. It is only called once, in main(). I think you want to call it directly from "handleKeyPress()", perhaps. Or else check the "space" variable somewhere in update() or drawScene().
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    Oct 2011
    Location
    Derby, UK
    Posts
    8
    Quote Originally Posted by MK27 View Post
    Hmm, if "loadImage()" is supposed to do the work, I do not see how. It is only called once, in main(). I think you want to call it directly from "handleKeyPress()", perhaps. Or else check the "space" variable somewhere in update() or drawScene().
    Okay, but it only seems to like calling the loadImage() method from within the main() - I get this sort of thing when calling it elsewhere:

    main.cpp:78:15: error: ‘loadImage’ was not declared in this scope

    I know, I'm dumb.

    S.

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by New_To_C++ View Post
    I know, I'm dumb.
    No, you are just apparently very new to C/C++. I dunno if openGL is a great place to start,* but you can try and slug it out for a while .

    main.cpp:78:15: error: ‘loadImage’ was not declared in this scope

    78 is the line number. The error occurs because loadImage is not declared or defined until line 84. Main() is after that, so it works. Try placing a function prototype at the top:

    Code:
    void loadImage();
    * also, jumping straight into textures and 3D is a recipe for frustration. Have you done stuff in 2D, sans textures and lighting, yet? I would get a program working with features like user controls (such as your space bar thing) there first. Maybe get comfortable in this order:

    1) Basic 2D
    2) Basic 3D (no textures, no lighting)
    3) 3D with lighting
    4) 3D with lighting and texture

    All using the "depreciated" immediate mode API, then you can start looking at stuff like VBO's and GLSL. Even once you are confident with #4, I think you will find most projects begin best with #2, then you add in the lighting and textures after the geometry, movement, and interface functionality are sound.

    But even before that, you might want to work your way through some C++ tutorials and write some stuff without using any big external API. The "out of scope"/undeclared error is very basic. Getting hung up on stuff like that is going to continuously cause you a lot of trouble, and the more complex the material, the harder "simple" problems are to locate and solve. In other words, you may think doing basic stuff is a waste of time and you might as well to just get going with what you really want to do and learn there, but you are wrong: it will save you time in the long run if you begin more modestly. Honestly. You shouldn't be getting stuck with stuff like this for 4 hours. If so, you are in a little over your head at the moment.

    It is much more rewarding, at the end of the day, to have someting simple that you understand, and that works, than something very ambitious and very incomplete that you are baffled by (and that may never work...).
    Last edited by MK27; 10-02-2011 at 11:50 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    Oct 2011
    Location
    Derby, UK
    Posts
    8
    Quote Originally Posted by MK27 View Post
    No, you are just apparently very new to C/C++. I dunno if openGL is a great place to start,* but you can try and slug it out for a while .

    main.cpp:78:15: error: ‘loadImage’ was not declared in this scope

    78 is the line number. The error occurs because loadImage is not declared or defined until line 84. Main() is after that, so it works. Try placing a function prototype at the top:

    Code:
    void loadImage();
    Okay thanks :-)

    * also, jumping straight into textures and 3D is a recipe for frustration. Have you done stuff in 2D, sans textures and lighting, yet? I would get a program working with features like user controls (such as your space bar thing) there first. Maybe get comfortable in this order:

    1) Basic 2D
    2) Basic 3D (no textures, no lighting)
    3) 3D with lighting
    4) 3D with lighting and texture
    The problem is that I've gone from one degree to another because I don't like Database stuff and I wanted something significantly more challenging in terms of real programming. I've done Java, and in the past Basic and some assembly. Depending on the target hardware, I find assembly quite easy, but none of this - except for the Java - is relevant in the modern world. So, I've kind of jumped into the deep end!

    All using the "depreciated" immediate mode API, then you can start looking at stuff like VBO's and GLSL. Even once you are confident with #4, I think you will find most projects begin best with #2, then you add in the lighting and textures once the basic geometry, movement, and functionality is sound.

    But even before that, you might want to work your way through some C++ tutorials and write some stuff without using any big external API. The "out of scope"/undeclared error is very basic. Getting hung up on stuff like that is going to continuously cause you a lot of trouble, and the more complex the material, the harder "simple" problems are to locate and solve. In other words, you may think doing basic stuff is a waste of time and you might as well to just get going with what you really want to do and learn there, but you are wrong: it will save you time in the long run. Honestly.
    Yeah, I've got an introductory book to C and a C++ pocket reference. I'm half way through the C book, but as one of my modules is 3D graphics using C++, I need to get cracking on something before things start to get a bit hairy.

    6502 seems so simple now...!

    Many thanks for the help and advice.

    S.

    Edit: I've added some simple stuff, like zooming in/out on the vector, but I still can't get the blummin' image to change! Ah well!
    Last edited by New_To_C++; 10-02-2011 at 12:48 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problems with OpenGL(glut) in C++
    By Abood in forum Windows Programming
    Replies: 27
    Last Post: 11-16-2007, 08:09 PM
  2. openGL problems (glut)
    By c_young in forum C++ Programming
    Replies: 2
    Last Post: 01-04-2007, 01:27 PM
  3. SDL or GLUT for Opengl?
    By drdroid in forum Game Programming
    Replies: 1
    Last Post: 07-17-2003, 01:54 AM
  4. Problems with glut/opengl.
    By drdroid in forum Game Programming
    Replies: 4
    Last Post: 05-28-2003, 02:19 PM
  5. Problems with rotations with OpenGL and GLUT
    By darcome in forum Game Programming
    Replies: 13
    Last Post: 07-05-2002, 12:12 AM

Tags for this Thread