How to updated OpenGL scene?

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:

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???

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.

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

It looks like you aren’t calling SwapBuffers().

Actually I’m D:

Look at the WinMain,


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

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

[QUOTE=mhagain;1238533]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[/QUOTE]

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?