"Bounce" example from SuperBible (3th)

Hello!

I am rewriting the second example (Bounce) of SuperBible (3th) in Qt. But my square doesn’t move! This is the original example from the disk of the book:


// Bounce.c
// Demonstrates a simple animated rectangle program with GLUT
// OpenGL SuperBible, 3rd Edition
// Richard S. Wright Jr.
// rwright@starstonesoftware.com

#include "../../Common/OpenGLSB.h"	// System and OpenGL Stuff



// Initial square position and size
GLfloat x = 0.0f;
GLfloat y = 0.0f;
GLfloat rsize = 25;

// Step size in x and y directions
// (number of pixels to move each time)
GLfloat xstep = 1.0f;
GLfloat ystep = 1.0f;

// Keep track of windows changing width and height
GLfloat windowWidth;
GLfloat windowHeight;

///////////////////////////////////////////////////////////
// Called to draw scene
void RenderScene(void)
	{
	// Clear the window with current clearing color
	glClear(GL_COLOR_BUFFER_BIT);

   	// Set current drawing color to red
	//		   R	 G	   B
	glColor3f(1.0f, 0.0f, 0.0f);

	// Draw a filled rectangle with current color
	glRectf(x, y, x + rsize, y - rsize);

    // Flush drawing commands and swap
    glutSwapBuffers();
	}

///////////////////////////////////////////////////////////
// Called by GLUT library when idle (window not being
// resized or moved)
void TimerFunction(int value)
    {
    // Reverse direction when you reach left or right edge
    if(x > windowWidth-rsize || x < -windowWidth)
        xstep = -xstep;

    // Reverse direction when you reach top or bottom edge
    if(y > windowHeight || y < -windowHeight + rsize)
        ystep = -ystep;

	// Actually move the square
    x += xstep;
    y += ystep;

    // Check bounds. This is in case the window is made
    // smaller while the rectangle is bouncing and the 
	// rectangle suddenly finds itself outside the new
    // clipping volume
    if(x > (windowWidth-rsize + xstep))
        x = windowWidth-rsize-1;
	else if(x < -(windowWidth + xstep))
		x = -windowWidth -1;

    if(y > (windowHeight + ystep))
        y = windowHeight-1; 
	else if(y < -(windowHeight - rsize + ystep))
		y = -windowHeight + rsize - 1;



     // Redraw the scene with new coordinates
    glutPostRedisplay();
    glutTimerFunc(33,TimerFunction, 1);
    }


///////////////////////////////////////////////////////////
// Setup the rendering state
void SetupRC(void)
    {
    // Set clear color to blue
    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    }


///////////////////////////////////////////////////////////
// Called by GLUT library when the window has chanaged size
void ChangeSize(int w, int h)
    {
    GLfloat aspectRatio;

    // Prevent a divide by zero
    if(h == 0)
        h = 1;
		
    // Set Viewport to window dimensions
    glViewport(0, 0, w, h);

    // Reset coordinate system
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // Establish clipping volume (left, right, bottom, top, near, far)
    aspectRatio = (GLfloat)w / (GLfloat)h;
    if (w <= h) 
        {
        windowWidth = 100;
        windowHeight = 100 / aspectRatio;
        glOrtho (-100.0, 100.0, -windowHeight, windowHeight, 1.0, -1.0);
        }
    else 
        {
        windowWidth = 100 * aspectRatio;
        windowHeight = 100;
        glOrtho (-windowWidth, windowWidth, -100.0, 100.0, 1.0, -1.0);
        }

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    }

///////////////////////////////////////////////////////////
// Main program entry point
int main(int argc, char* argv[])
	{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(800,600);
        glutCreateWindow("Bounce");
	glutDisplayFunc(RenderScene);
        glutReshapeFunc(ChangeSize);
	glutTimerFunc(33, TimerFunction, 1);

	SetupRC();

	glutMainLoop();
        
        return 0;
    }

This is my code in Qt:



#include "Scene.h"

Scene::Scene( QWidget *parent ) :
    QGLWidget( parent ),
    m_x( 0.0f ),
    m_y( 0.0f ),
    m_rsize( 25.0f )
{
    m_timer = new QTimer( this );
    connect( m_timer, SIGNAL( timeout() ),
             this, SLOT( slotMoveRect() ) );
    m_timer->start( 100 );
}

void Scene::slotMoveRect()
{
    // Reverse direction when you reach left or right edge
    if( m_x > m_windowWidth - m_rsize || m_x < -m_windowWidth ) {
        m_xstep = -m_xstep;
    }

    // Reverse direction when you reach top or bottom edge
    if( m_y > m_windowHeight || m_y < -m_windowHeight + m_rsize ) {
        m_ystep = -m_ystep;
    }

    // Actually move the square
    m_x += m_xstep;
    m_y += m_ystep;

    // Check bounds. This is in case the window is made
    // smaller while the rectangle is bouncing and the
    // rectangle suddenly finds itself outside the new
    // clipping volume
    if( m_x > ( m_windowWidth-m_rsize + m_xstep ) ) {
        m_x = m_windowWidth-m_rsize-1;
    } else if( m_x < -( m_windowWidth + m_xstep ) ) {
        m_x = -m_windowWidth - 1;
    }

    if( m_y > ( m_windowHeight + m_ystep ) ) {
        m_y = m_windowHeight-1;
    } else if( m_y < -( m_windowHeight - m_rsize + m_ystep ) ) {
        m_y = -m_windowHeight + m_rsize - 1;
    }

    updateGL();
}

void Scene::initializeGL()
{
    glClearColor( 0.0f, 0.0f, 1.0f, 1.0f );
}

void Scene::paintGL()
{
    // Clear the window with current clearing color
    glClear( GL_COLOR_BUFFER_BIT );

    // Set current drawing color to red
    glColor3f( 1.0f, 0.0f, 0.0f );

    // Draw a filled rectangle with current color
    glRectf( m_x, m_y, m_x + m_rsize, m_y - m_rsize );
}

void Scene::resizeGL( int w, int h )
{
    // Prevent a divide by zero
    if ( h == 0 ) {
        h = 1;
    }

    // Set Viewport to window dimensions
    glViewport( 0, 0, w, h );

    // Reset coordinate system
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    // Establish clipping volume (left, right, bottom, top, near, far)
    GLfloat aspectRatio = ( GLfloat ) w / ( GLfloat ) h;

    if ( w <= h ) {
        m_windowWidth = 100.0f;
        m_windowHeight = 100.0f / aspectRatio;
        glOrtho( -100.0, 100.0, -m_windowHeight, m_windowHeight, 1.0, -1.0 );
    } else {
        m_windowWidth = 100.0 * aspectRatio;
        m_windowHeight = 100.0;
        glOrtho( -m_windowWidth, m_windowWidth, -100.0, 100.0, 1.0, -1.0 );
    }

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
}

Thank you!

I do not see a call swapping the buffers after the rectangle is drawn ( at the end of Scene :: PaintGL(){…} ).

I see the blinking and this message:

QOpenGLContext::swapBuffers() called without corresponding makeCurrent()

Well, that is not a reason to avoid calling that function. :slight_smile:
It looks like window is not initialized properly (the call to wglMakeCurrent() is not made for the created OpenGL rendering context).

QGLWidget (the class of 8Observer8’s Scene class from) is supposed to take care of making the context current before calling paintGL and swapping buffers afterwards (unless explicitly disabled with setAutoBufferSwap(false)).

8Observer8: Since your original problem was that the square is not moving: is your slotMoveRect function actually called, i.e. set a breakpoint in it when running under a debugger. While there you can also check the coordinates to see if they are reasonable after the update.

I found mistake! I forgot to initialize m_xstep and m_ystep:


Scene::Scene( QWidget *parent ) :
    QGLWidget( parent ),
    m_x( 0.0f ),
    m_y( 0.0f ),
    m_rsize( 25.0f ),
    m_xstep( 1.0f ),
    m_ystep( 1.0f )
{
    m_timer = new QTimer( this );
    connect( m_timer, SIGNAL( timeout() ),
             this, SLOT( slotMoveRect() ) );
    m_timer->start( 33 );
}

I don’t need to swap buffers in Qt

P.S. carsten neumann, thank you very much :slight_smile: