PDA

View Full Version : My First Code - Not Updating



beakie
08-25-2012, 10:04 PM
My code draws a square but doesn't change size for each timer tick event?

Any ideas please?




#include "frmDeviceRender.h"

void initGL() {
glClearColor (0.0, 0.0, 0.0, 0.0);
glColor3f (1.0, 1.0, 1.0);
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
};

void drawIt(float bsize) {
glClear (GL_COLOR_BUFFER_BIT);
glBegin(GL_POLYGON);
float from = (1 - bsize) / 2;
float to = (1 - from);
glVertex3f (from, from, 0.0);
glVertex3f (to, from, 0.0);
glVertex3f (to, to, 0.0);
glVertex3f (from, to, 0.0);
glEnd();
glFlush();
};

void FrmDeviceRender::setFormDefaults() {
setFormProperties(0, WS_OVERLAPPEDWINDOW , CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, TEXT("Rendered Container"));
};

void FrmDeviceRender::populateForm() {
hdc = GetDC (me) ;

GLsizei width = 200;
GLsizei height = 200;
int bits = 32;
GLuint PixelFormat;
static PIXELFORMATDESCRIPTOR pfd=
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
bits,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};

if (!(PixelFormat=ChoosePixelFormat(hdc,&pfd))) {
MessageBox(NULL,L"Can't Find A Suitable PixelFormat.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
}

if(!SetPixelFormat(hdc,PixelFormat,&pfd)) {
MessageBox(NULL,L"Can't Set The PixelFormat.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
}

if (!(hRC=wglCreateContext(hdc))) {
MessageBox(NULL,L"Can't Create A GL Rendering Context.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
}

if(!wglMakeCurrent(hdc,hRC)) {
MessageBox(NULL,L"Can't Activate The GL Rendering Context.",L"ERROR",MB_OK|MB_ICONEXCLAMATION);
}
};

void FrmDeviceRender::onPaint() {
initGL();

BoxSize = 0.8;
drawIt(BoxSize);
SwapBuffers(hdc);

SetTimer (me, 1, 1000, NULL);
}

void FrmDeviceRender::onUnload() {
KillTimer (me, 1);
ReleaseDC (me, hdc) ;

PostQuitMessage (0);
};

void FrmDeviceRender::onTimerTick(int id) {
BoxSize *= 0.9;
drawIt(BoxSize);
SwapBuffers(hdc);
};

Rosario Leonardi
08-26-2012, 04:57 AM
This is an evolution of the previous code? I glad that you divide the function rationally with meaningful names (there is hope).
But if you update your scene in the onPaint function you will have a problem. The onPaint is called only when your windows is damaged (was hidden and now need to paint, another windows have passed above your, and so on). You have to intercept the on idle message (WM_IDLE) and call invalidate. Otherwise insert your render function in your pump message, or invalidate your window area with a timer.
Also remove that glFlush, the flush command is automatically inserted by glFinish and SwapBuffers commands.

beakie
08-26-2012, 05:34 AM
This is an evolution of the previous code? I glad that you divide the function rationally with meaningful names (there is hope).

But if you update your scene in the onPaint function you will have a problem. The onPaint is called only when your windows is damaged (was hidden and now need to paint, another windows have passed above your, and so on). You have to intercept the on idle message (WM_IDLE) and call invalidate. Otherwise insert your render function in your pump message, or invalidate your window area with a timer.


This code is actually inserted into a previous project (I wrote a software based 3D engine - it has limitations, which is why im looking at opengl) and therefore I temporarily put the code in the existing chunk (onPaint) but this is only while im trying to get a few shapes drawn correctly... i agree entirely with what ur saying...

I have included a timer to do the drawing... its call is at the bottom. Beyond the initial draw, each subsequent draw (in this temporary code) should be made using timertick. are u saying i should invalidate the rectangle because the code is in onPaint or because this is what OpenGL requires?

I haven't seen any examples/tutorials online going down the InvalidateRect road?? Could you please expand?



Also remove that glFlush, the flush command is automatically inserted by glFinish and SwapBuffers commands.


Great, thanks. Will do.

Rosario Leonardi
08-26-2012, 06:16 AM
If you don't call invalidate your onPaint will be called only once, or when Window decide that need to redraw your window. In your case you need a smooth animation, so you have to call onPaint at least 60 times for second. You can't call onPaint directly, but you must ask Window that the content of your window is not valid anymore. That's why you need to call invalidate.
I'm not a Window expert but InvalidateRect require the window handle and with part of your window want to invalidate. To get the correct area you can ask window (GetClientArea) of to it by yourself is you store the dimension of the window somewhere.

beakie
08-26-2012, 06:37 AM
Cool. InvalidateRect worked a treat. Thanks for this!!!