PDA

View Full Version : How to updated OpenGL scene?



Indloon
06-07-2012, 09:50 AM
Hello.

I'm having a problematic problem D:

The problem is that, I draw a triangle and I have the code written so if the mouse moves,

then a value is sent to glRotatef(), which rotates triangle,

however, the rotation works only if I minimize and maximize my window,

THEN the scene is updated.

So yeah, how to make rotating to realtime?

Here is the code:



#include "glab.h"

#define WINDOW_NAME "Glab - OpenGL - Clock"
#define WINDOW_CLASS "glab"
#define WINDOW_STYLE (WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
#define WINDOW_HEIGHT 500
#define WINDOW_WIDTH 500
#define PI 3.141592653589793

typedef struct {
HWND hWnd;
HINSTANCE hInstance;
int tund;
int minut;
int sekund;
GLfloat rtri;
} glab_t;

static glab_t glab;

HDC hDC = 0;
HGLRC hRC = 0;

//---------------------------------------------------------------------------------------------------------------------------
int SetTime( glab_t *glab ) {
time_t settime;
struct tm *gt;

settime = time( NULL );

if( !glab ) {
return settime;
}
gt = localtime( &settime );

if( gt ) {
glab->sekund = gt->tm_sec;
glab->minut = gt->tm_min;
glab->tund = gt->tm_hour;
}
return settime;
}
//---------------------------------------------------------------------------------------------------------------------------
static void Glab_DestoryWindow( void ) {
if ( glab.hWnd ){
ShowWindow( glab.hWnd, SW_HIDE );
DestroyWindow( glab.hWnd );
glab.hWnd = NULL;

UnregisterClass( WINDOW_CLASS, glab.hInstance );
}
}
//---------------------------------------------------------------------------------------------------------------------------
static void Glab_Quit( void ) {
Glab_DestoryWindow();
ExitProcess( 0 );
}
//---------------------------------------------------------------------------------------------------------------------------
static void Glab_Error( const char *text ) {
MessageBox( NULL,text,"ERROR",MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL );
Glab_Quit();
}

//---------------------------------------------------------------------------------------------------------------------------
static LRESULT CALLBACK Glab_WindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) {
switch ( msg ) {
case WM_DESTROY:
PostQuitMessage (0);
break;
case WM_MOUSEMOVE:
glab.rtri += 0.25f;
break;
}

return DefWindowProc (hwnd, msg, wParam, lParam);
}
//---------------------------------------------------------------------------------------------------------------------------
static void Glab_CreateWindow( void ) {
RECT rect;
WNDCLASSEX wndClass;
GLuint PixelFormat;
int screenWidth, screenHeight;
int x,y,w,h;

screenWidth = GetSystemMetrics( 0 );
screenHeight = GetSystemMetrics( 1 );

rect.left = ( screenWidth - 582 ) / 2;
rect.top = ( screenHeight - 358 ) / 2;
rect.right = rect.left + 582;
rect.bottom = rect.top + 358;

AdjustWindowRectEx(&rect, WINDOW_STYLE, FALSE, 0);

x = rect.left;
y = rect.top;
w = WINDOW_WIDTH;
h = WINDOW_HEIGHT;

memset( &wndClass, 0, sizeof(WNDCLASSEX) );

wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.style = 0;
wndClass.lpfnWndProc = Glab_WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = glab.hInstance;
wndClass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndClass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = WINDOW_CLASS;

if ( !RegisterClassEx(&wndClass) ) {
Glab_Error( "Could not register window class" );
}

glab.hWnd = CreateWindowEx(0, WINDOW_CLASS, WINDOW_NAME, WINDOW_STYLE, x, y, w, h, NULL, NULL, glab.hInstance, NULL);

if( !glab.hWnd ) {
UnregisterClass(WINDOW_CLASS, glab.hInstance);
Glab_Error( "Could not create window" );
}

static PIXELFORMATDESCRIPTOR pfd= { sizeof( PIXELFORMATDESCRIPTOR ), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 };

if ( !(hDC=GetDC(glab.hWnd)) ) {
Glab_Error("Can't Create A GL Device Context.");
}

if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) {
Glab_Error("Can't Find A Suitable PixelFormat.");
}

if(!SetPixelFormat(hDC,PixelFormat,&pfd)) {
Glab_Error("Can't Set The PixelFormat.");
}

if (!(hRC=wglCreateContext(hDC))) {
Glab_Error("Can't Create A GL Rendering Context.");
}

if(!wglMakeCurrent(hDC,hRC)) {
Glab_Error("Can't Activate The GL Rendering Context.");
}

ShowWindow( glab.hWnd, SW_SHOW );
UpdateWindow( glab.hWnd );
SetForegroundWindow( glab.hWnd );
SetFocus( glab.hWnd );
}
//---------------------------------------------------------------------------------------------------------------------------
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
MSG msg;

glab.hInstance = hInstance;
SetErrorMode( SEM_FAILCRITICALERRORS );

Glab_CreateWindow();

while( 1 ) {
if ( !GetMessage(&msg, NULL, 0, 0) ) {
Glab_Quit();
}

if ( IsDialogMessage( glab.hWnd, &msg) ) {
continue;
}

if (!GL_init() ) {
Glab_Error("Initialization Failed.");
return false;
}

/*if( !GL_drawit() ) {
Glab_Error("Initialization Failed.");
return false;
}*/
GL_drawit();

TranslateMessage(&msg);
DispatchMessage(&msg);
}

return true;
}
// OpenGL-i osa

//---------------------------------------------------------------------------------------------------------------------------
void GL_drawit( GLvoid ) {
glab_t timetable;

SetTime(&timetable);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

glTranslatef( 0.0f, 0.0f, -6.0f );
glRotatef( glab.rtri, 0.0f, 1.0f, 0.0f );
glBegin( GL_TRIANGLES );
glColor3f(0.0f,1.0f,0.0f);
glVertex3f( 0.0f, 4.0f, 0.0f); // Up part

glColor3f(0.0f,0.0f,1.0f);
glVertex3f(-4.0f,-4.0f, 0.0f); // Down left part

glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 4.0f,-4.0f, 0.0f); // Down right part
glEnd();
SwapBuffers( hDC );
// return true;
}
//---------------------------------------------------------------------------------------------------------------------------
int GL_init( GLvoid ) {
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glViewport(0,0,WINDOW_WIDTH,WINDOW_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0f,(GLfloat)WINDOW_WIDTH/(GLfloat)WINDOW_HEIGHT,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
return true;
}


The settime is for clock what I wan't to do D:

Indloon
06-07-2012, 10:11 AM
Ah, I got it working:

#include "glab.h"

#define WINDOW_NAME "Glab - OpenGL - Clock"
#define WINDOW_CLASS "glab"
#define WINDOW_STYLE (WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
#define WINDOW_HEIGHT 500
#define WINDOW_WIDTH 500
#define PI 3.141592653589793

typedef struct {
HWND hWnd;
HINSTANCE hInstance;
int tund;
int minut;
int sekund;
GLfloat rtri;
} glab_t;

static glab_t glab;
static bool keys[256]; // no support for extented ASCII, sorry northern countries D:

HDC hDC = 0;
HGLRC hRC = 0;

//---------------------------------------------------------------------------------------------------------------------------
int SetTime( glab_t *glab ) {
time_t settime;
struct tm *gt;

settime = time( NULL );

if( !glab ) {
return settime;
}
gt = localtime( &settime );

if( gt ) {
glab->sekund = gt->tm_sec;
glab->minut = gt->tm_min;
glab->tund = gt->tm_hour;
}
return settime;
}
//---------------------------------------------------------------------------------------------------------------------------
static void Glab_DestoryWindow( void ) {
if ( glab.hWnd ){
ShowWindow( glab.hWnd, SW_HIDE );
DestroyWindow( glab.hWnd );
glab.hWnd = NULL;
memset( &glab, 0, sizeof( glab ) );
wglMakeCurrent(NULL,NULL);
wglDeleteContext(hRC);
ReleaseDC(glab.hWnd,hDC);

UnregisterClass( WINDOW_CLASS, glab.hInstance );
}
}
//---------------------------------------------------------------------------------------------------------------------------
static void Glab_Quit( void ) {
Glab_DestoryWindow();
ExitProcess( 0 );
}
//---------------------------------------------------------------------------------------------------------------------------
static void Glab_Error( const char *text ) {
MessageBox( NULL,text,"ERROR",MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL );
Glab_Quit();
}

//---------------------------------------------------------------------------------------------------------------------------
static LRESULT CALLBACK Glab_WindowProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) {
switch ( msg ) {
case WM_DESTROY:
PostQuitMessage (0);
break;
case WM_KEYDOWN:
keys[wParam] = TRUE;
break;
case WM_KEYUP:
keys[wParam] = FALSE;
break;
}

return DefWindowProc (hwnd, msg, wParam, lParam);
}
//---------------------------------------------------------------------------------------------------------------------------
static void Glab_CreateWindow( void ) {
RECT rect;
WNDCLASSEX wndClass;
GLuint PixelFormat;
int screenWidth, screenHeight;
int x,y,w,h;

screenWidth = GetSystemMetrics( 0 );
screenHeight = GetSystemMetrics( 1 );

rect.left = ( screenWidth - 582 ) / 2;
rect.top = ( screenHeight - 358 ) / 2;
rect.right = rect.left + 582;
rect.bottom = rect.top + 358;

AdjustWindowRectEx(&rect, WINDOW_STYLE, FALSE, 0);

x = rect.left;
y = rect.top;
w = WINDOW_WIDTH;
h = WINDOW_HEIGHT;

memset( &wndClass, 0, sizeof(WNDCLASSEX) );

wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.style = 0;
wndClass.lpfnWndProc = Glab_WindowProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = glab.hInstance;
wndClass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndClass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor (NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = WINDOW_CLASS;

if ( !RegisterClassEx(&wndClass) ) {
Glab_Error( "Could not register window class" );
}

glab.hWnd = CreateWindowEx(0, WINDOW_CLASS, WINDOW_NAME, WINDOW_STYLE, x, y, w, h, NULL, NULL, glab.hInstance, NULL);

if( !glab.hWnd ) {
UnregisterClass(WINDOW_CLASS, glab.hInstance);
Glab_Error( "Could not create window" );
}

static PIXELFORMATDESCRIPTOR pfd= { sizeof( PIXELFORMATDESCRIPTOR ), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 };

if ( !(hDC=GetDC(glab.hWnd)) ) {
Glab_Error("Can't Create A GL Device Context.");
}

if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) {
Glab_Error("Can't Find A Suitable PixelFormat.");
}

if(!SetPixelFormat(hDC,PixelFormat,&pfd)) {
Glab_Error("Can't Set The PixelFormat.");
}

if (!(hRC=wglCreateContext(hDC))) {
Glab_Error("Can't Create A GL Rendering Context.");
}

if(!wglMakeCurrent(hDC,hRC)) {
Glab_Error("Can't Activate The GL Rendering Context.");
}

ShowWindow( glab.hWnd, SW_SHOW );
UpdateWindow( glab.hWnd );
SetForegroundWindow( glab.hWnd );
SetFocus( glab.hWnd );
}
//---------------------------------------------------------------------------------------------------------------------------
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
MSG msg;
bool done = false;

glab.hInstance = hInstance;
SetErrorMode( SEM_FAILCRITICALERRORS );

Glab_CreateWindow();

while( !done ) {
if ( !GetMessage(&msg, NULL, 0, 0) ) {
Glab_Quit();
}

if ( IsDialogMessage( glab.hWnd, &msg) ) {
continue;
}

if (!GL_init() ) {
Glab_Error("Initialization Failed.");
return false;
}

if( !GL_drawit() ) {
Glab_Error("Initialization Failed.");
return false;
}

if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
if (msg.message==WM_QUIT) {
done=TRUE;
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} else {
if( !GL_drawit() ) {
done = true;
} else {
SwapBuffers( hDC );
}
}

}
return (msg.wParam); // We don't let to kill ourself
}
// OpenGL-i osa

//---------------------------------------------------------------------------------------------------------------------------
int GL_drawit( GLvoid ) {
glab_t timetable;

SetTime(&timetable);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

glTranslatef( 0.0f, 0.0f, -6.0f );
glRotatef( glab.rtri, 0.0f, 1.0f, 0.0f );
glBegin( GL_TRIANGLES );
glColor3f(0.0f,1.0f,0.0f);
glVertex3f( 0.0f, 4.0f, 0.0f); // Up part

glColor3f(0.0f,0.0f,1.0f);
glVertex3f(-4.0f,-4.0f, 0.0f); // Down left part

glColor3f(1.0f,0.0f,0.0f);
glVertex3f( 4.0f,-4.0f, 0.0f); // Down right part
glEnd();
glab.rtri += 0.25f;
return true;
}
//---------------------------------------------------------------------------------------------------------------------------
int GL_init( GLvoid ) {
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glViewport(0,0,WINDOW_WIDTH,WINDOW_HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.0f,(GLfloat)WINDOW_WIDTH/(GLfloat)WINDOW_HEIGHT,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
return true;
}


But the problem is that it lags as hell???

RadekH
06-07-2012, 10:35 AM
Well, I do not like winblows and I try to avoid it every time I can. My recommendations need not be exact but ...

Your window procedure seems to be a bit strange. Perhaps, you should process WM_PAINT and, instead of BeginPaint() and EndPaint(), paint your OpenGL graphics and then ValidateRect(). The WM_MOUSEMOVE should set the glab.rtri variable and invalidate the OpenGL window. Also, you should process WM_SIZE and set viewport and reinitialize from there.

Indloon
06-07-2012, 10:57 AM
Also, you should process WM_SIZE and set viewport and reinitialize from there.

That is not needed, since you cannot resize the window, I have disabled it :D

V-man
06-07-2012, 03:40 PM
It looks like you aren't calling SwapBuffers().

Indloon
06-08-2012, 01:49 AM
It looks like you aren't calling SwapBuffers().

Actually I'm D:

Look at the WinMain,


if( !GL_drawit() ) {
done = true;
} else {
SwapBuffers( hDC );
}

mhagain
06-08-2012, 02:22 AM
Your code is incredibly confusing. I don't see why you're calling both GetMessage and PeekMessage in your main loop, for example - what that's going to do is cause the thread to block until GetMessage returns a message - if the message queue is empty it just blocks indefinitely (and check the documentation for GetMessage while you're at it - !GetMessage is unsafe to use) which is why you're seeing lag.

A more typical Windows rendering loop would look like this (source: http://www.mvps.org/directx/articles/writing_the_game_loop.htm):
MSG mssg;

// prime the message structure
PeekMessage (&mssg, NULL, 0, 0, PM_NOREMOVE);

// run till completed
while (mssg.message != WM_QUIT)
{
// is there a message to process?
if (PeekMessage (&mssg, NULL, 0, 0, PM_REMOVE))
{
// dispatch the message
TranslateMessage (&mssg);
DispatchMessage (&mssg);

}
else
{
// our stuff will go here!!
}
}

That will ensure that everything runs smooth and fast, and with no sense of lag.

Your timer is not going to provide good enough precision or accuracy for drawing either, but that's another problem for another day

Indloon
06-08-2012, 07:25 AM
Your code is incredibly confusing. I don't see why you're calling both GetMessage and PeekMessage in your main loop, for example - what that's going to do is cause the thread to block until GetMessage returns a message - if the message queue is empty it just blocks indefinitely (and check the documentation for GetMessage while you're at it - !GetMessage is unsafe to use) which is why you're seeing lag.

A more typical Windows rendering loop would look like this (source: http://www.mvps.org/directx/articles/writing_the_game_loop.htm):
MSG mssg;

// prime the message structure
PeekMessage (&mssg, NULL, 0, 0, PM_NOREMOVE);

// run till completed
while (mssg.message != WM_QUIT)
{
// is there a message to process?
if (PeekMessage (&mssg, NULL, 0, 0, PM_REMOVE))
{
// dispatch the message
TranslateMessage (&mssg);
DispatchMessage (&mssg);

}
else
{
// our stuff will go here!!
}
}

That will ensure that everything runs smooth and fast, and with no sense of lag.

Your timer is not going to provide good enough precision or accuracy for drawing either, but that's another problem for another day

Thanks, it runs smooth and fast now and there is no lag.

However, I checked my task manager, while running the program, and what I saw is that it used 90%-98% of my CPU O.o

Is it normal? Or I should think using OpenCL with OpenGL?