PDA

View Full Version : "Bounce" example from SuperBible (3th)



8Observer8
08-31-2014, 11:55 AM
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!

Yandersen
08-31-2014, 06:04 PM
I do not see a call swapping the buffers after the rectangle is drawn ( at the end of Scene :: PaintGL(){...} ).

8Observer8
08-31-2014, 10:56 PM
I see the blinking and this message:


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

Yandersen
09-01-2014, 02:20 AM
Well, that is not a reason to avoid calling that function. :)
It looks like window is not initialized properly (the call to wglMakeCurrent() is not made for the created OpenGL rendering context).

carsten neumann
09-01-2014, 02:57 AM
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.

8Observer8
09-01-2014, 03:27 AM
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 :)