Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 8 of 8

Thread: Drawing a sphere and recoloring and/or deleting it

  1. #1
    Junior Member Newbie
    Join Date
    Sep 2013
    Location
    Berlin
    Posts
    20

    Drawing a sphere and recoloring and/or deleting it

    Hey all,
    for an university project I am trying to write a program that shows a couple of white spheres that turn red one by one, each time the mouse is clicked. However, I can't get it to work properly. Specifically, the spheres just won't recolor.
    I am writing in c++ using the Qt framework and Qt Creator. Also, I use glut.
    The (I believe relevant) principle of my code is as follows:
    - I have the functions initializeGL(), resizeGL() and paintGL(). These are part of my GLWidget (responsible for the 3D Window). The names are pretty straightforward, I think.
    - In the paintGL() function, I instantiate an array of objects of the type "sphere" (custom type). The constructor of "sphere" calls my function sphere::drawsphere().
    - drawsphere() uses glutsolidsphere() to do its job. It gets input on position and color of the glutsolidsphere from "sphere"'s constructor, which is called from paintGL(). If the variable "colo" is 'w', it's supposed to draw a white sphere. 'r' is for red. It uses an if/else construct for that.
    - Also in paintGL, I count the clicks from the mouse. If it has been clicked, say, 2 times, I give the command sphaere[1]->colo='r'; . However, nothing changes, which is my primary problem.
    I hope I have made myself clear enough (English is not my first language).
    I'm new to OpenGL and still have poblems figuring out how it all works. If anyone could help me simply based on principle, I would greatly appreciate it. Thanks.
    ps. I tried to post some of my code alongside this question, but it just denied me the post.

  2. #2
    Junior Member Regular Contributor
    Join Date
    Apr 2012
    Location
    Los Angeles
    Posts
    189
    If the variable "colo" is 'w', it's supposed to draw a white sphere. 'r' is for red.
    A simple experiment I would do first is to initialize 'colo' to 'r' (i.e. no mouse clicks required). Does this make the sphere red? This should help you narrow down the problem. Good luck.

  3. #3
    Junior Member Newbie
    Join Date
    Sep 2013
    Location
    Berlin
    Posts
    20
    Thanks for the tip! However, if I call the constructor with an 'r', it does produce a red sphere.
    I also attached a qDebug to the drawSphere() function to see which color sphere is drawn when.
    It appears that since the sphere is already drawn when I use setSphereColor() the change doesn't affect it in the next iteration of paintGL().

    paintGL
    Code :
    void GLWidget::paintGL() {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();
        glTranslatef(0.0f, 0.0f, 0.0f); //Placeholder
        sphere **sphaere = new sphere*[10];
        for(iii=0;iii<MyWindow::N-1;iii++) {
            sphaere[iii] = new sphere(MyWindow::fX[iii], MyWindow::fY[iii], MyWindow::fZ[iii], 'w', true);
            qDebug() << "sphaere[" << iii << "].colo ist: " << sphaere[iii]->getSphereColor();
        }
        switch(klick) {
            case 1:
                    sphaere[0]->setSphereColor('r');
                    qDebug() << "sphaere[0].colo ist: " << sphaere[0]->getSphereColor();
                    qDebug() << "sphaere[1].colo ist: " << sphaere[1]->getSphereColor();
                    break;
            case 2: sphaere[1]->setSphereColor('r');
                    qDebug() << "sphaere[0].colo ist: " << sphaere[0]->getSphereColor();
                    qDebug() << "sphaere[1].colo ist: " << sphaere[1]->getSphereColor();
                    break;
            default:break;
        }
     
        //glFlush();  //necessary?
        //glutSwapBuffers(); //necessary?
        qDebug() << "paintGL fertig in Durchlauf Nr." << counter; // Zum Debuggen.
        counter ++;
    }

    sphere.cpp
    Code :
    #include "glwidget.h"
    #include "sphere.h"
    char colo = 'w';
     
    sphere::sphere() {
        qDebug() << "Sphere init.";
        colo = 'w';
    }
     
    sphere::sphere(float fX, float fY, float fZ, char colo, bool zeichne) {
        drawsphere(fX, fY, fZ, colo, zeichne);
        qDebug() << "drawsphere ausm constructor gecalled";
    }
     
    void sphere::drawsphere(float fX, float fY, float fZ, char colo, bool zeichne) {
        if(zeichne==true){
            if(colo == 'w') {
                glColor3f(1.0f, 1.0f, 1.0f);
                glPushMatrix();
                glTranslatef(fX, fY, fZ);
                glutSolidSphere(0.5,16,16);
                qDebug() << "weiße Sphäre gedrawed";
                glPopMatrix();
                glFlush();
            }
     
            else if(colo == 'r') {
                glColor3f(1.0f, 0.2f, 0.2f);
                glPushMatrix();
                glTranslatef(fX, fY, fZ);
                glutSolidSphere(0.5,16,16);
                qDebug() << "rote Sphäre gedrawed";
                glPopMatrix();
                glFlush();
            }
            else {
                qDebug() << "colo ist weder w noch r!!!";
            }
        }
    }
     
    void sphere::setSphereColor(char col) {
        sphere::colo = col;
        qDebug() << "sphere::colo ist" << sphere::colo << "und col ist" << col << "in setSphereColor";
    }
     
    char sphere::getSphereColor() {
        qDebug() << colo << "ist colo in getSphereColor";
        return sphere::colo;
    }
    Apologies if it's messy.

  4. #4
    Senior Member OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,217
    Single buffered context on Windows Vista or higher? Try using double buffered instead (with the appropriate SwapBuffers call at the end of your paint function).

  5. #5
    Junior Member Newbie
    Join Date
    Sep 2013
    Location
    Berlin
    Posts
    20
    Thank you. A swapBuffers() call as well as a SwapBuffers(hDC) call will result in a completely black background (as opposed to my default glClearColor() grey). I think I'm only drawing in one buffer as opposed to two. How do I draw into the second buffer as well?
    ps. I'm using Windows 7 via BootCamp on a MacBook.

  6. #6
    Senior Member OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,217
    Using GLUT, look for your glutInitDisplayMode call, and either replace the GLUT_SINGLE parameter with GLUT_DOUBLE, or if neither are specified just add GLUT_DOUBLE. Then add glutSwapBuffers at the end of your display function.

    There is a way of getting single-buffered contexts to work (just adding a glFlush) but to be honest double-buffered is so easy - just one changed parameter and one extra line of code - that you're better off doing it right. It's puzzling that so much GLUT material still creates a single-buffered context; one would almost think that double-buffered was seen as some kind of advanced topic, whereas it's clearly not (and has more robust support too).

  7. #7
    Junior Member Newbie
    Join Date
    Sep 2013
    Location
    Berlin
    Posts
    20
    Okay, thanks for the tip, but adding
    glutInitDisplayMode(GLUT_DOUBLE);
    in my initializeGL() function and
    glutSwapBuffers();
    in my paintGL() function simply causes the program to crash.
    After that, I tried glDrawBuffer(GL_BACK) at the beginning of my paintGL() function and swapBuffers() at the end as well as several places for makecurrent(), but nothing has worked so far. I get the debug error "QOpenGLContext::swapBuffers() called without corresponding makeCurrent()" and don't know what to make of it. I simply get a flickering screen (normally black, just my drawings when paintGL() is called, for example while resizing). Thank you so much for taking your time.

  8. #8
    Junior Member Newbie
    Join Date
    Sep 2013
    Location
    Berlin
    Posts
    20
    Well, for now I decided to not focus on the double buffering (might as well do it as soon as I get the "simpler" way to work, I think).
    My problem is still that I'm initializing the array of spheres in my paintGL function. Since I'm doing this, the recoloring to red has no effect (it's already drawn in this iteration of paintGL and when drawn the next time it's initalized in white).
    So basically I (think I) know what my problem is. I just don't know how to fix it! Does anyone have any idea where I could initialize the array? I tried in the constructor of my GLWidget and in the initalizeGL function, but it either doesn't compile (constructor) or just crashes when it's supposed to draw (initializeGL).
    Help me please, I'm desparate you guys

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •