Jump to content
  • Advertisement
Sign in to follow this  
jessica_chen

OpenGL OpenGL+Win32 api+Timer problem

This topic is 3993 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have 2 projects with "Timer" usage for OpenGL display. One has good performance (without using much CPU resources); another one DON'T. WHY? Is there anybody can give me any suggestion to improve the one which consume too much CPU resources? The code projects are attached. Thanks in advance, Jessica

Share this post


Link to post
Share on other sites
Advertisement
You can upload your finished projects/demos to GD, but otherwise you need to find a free site on the web (search a bit, they are popping out like crazy) - unless you run a FTP server at home :).

Once you have uploaded your projects, you can link to them in GD posts using a standard HTML link tag.

Share this post


Link to post
Share on other sites
//this code works fine-performance is normal.
//=====


//minimal.cpp
/* An example of the minimal Win32 & OpenGL program. It only works in
16 bit color modes or higher (since it doesn't create a
palette). */



#include <windows.h>/* must include this before GL/gl.h */
#include <GL/gl.h>/* OpenGL header file */
#include <GL/glu.h>/* OpenGL utilities header file */
#include <stdio.h>
// angle variables
float angx = 0.0f;
float angy = 0.0f;
float angz = 1.0f;
// grid variables
float Fx = 0.0f;
float Fy = 1.0f;
float Sx = 0.87f;
float Sy = -0.5f;
float Tx = -0.87f;
float Ty = -0.5f;
// speed
float theta = 0.0f;
float Spd = 1.0f;

HDC hDC;

void
display()
{
/* rotate a triangle around */
glClear(GL_COLOR_BUFFER_BIT);

glPushMatrix();
glRotatef( theta, angx, angy, angz);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(Fx, Fy);
glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(Sx, Sy);
glColor3f(0.0f, 0.0f, 1.0f); glVertex2f(Tx, Ty);
glEnd();
glPopMatrix();

SwapBuffers(hDC);
// start of add
theta += Spd;
// end of add
}


LONG WINAPI
WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static PAINTSTRUCT ps;

switch(uMsg) {
// Start of add
case WM_CREATE:
SetTimer(hWnd, 1, 10, NULL);
return TRUE;

case WM_TIMER:
PostMessage(hWnd, WM_PAINT, 0, 0);
break;
// End of add
case WM_PAINT:
display();
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);

return 0;

case WM_SIZE:
glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
PostMessage(hWnd, WM_PAINT, 0, 0);
return 0;

case WM_CHAR:
switch (wParam) {
case 27:/* ESC key */
PostQuitMessage(0);
DestroyWindow(hWnd);
exit(1);
break;
}
return 0;

case WM_CLOSE:
PostQuitMessage(0);
DestroyWindow(hWnd);
exit(1);
return 0;
}

return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

HWND
CreateOpenGLWindow(char* title, int x, int y, int width, int height,
BYTE type, DWORD flags)
{
int pf;

HWND hWnd;
WNDCLASS wc;
PIXELFORMATDESCRIPTOR pfd;
static HINSTANCE hInstance = 0;

/* only register the window class once - use hInstance as a flag. */
if (!hInstance) {
hInstance = GetModuleHandle(NULL);
wc.style = CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = "OpenGL";

if (!RegisterClass(&wc)) {
MessageBox(NULL, "RegisterClass() failed: "
"Cannot register window class.", "Error", MB_OK);
return NULL;
}
}

hWnd = CreateWindow("OpenGL", title, WS_OVERLAPPEDWINDOW |
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
x, y, width, height, NULL, NULL, hInstance, NULL);

if (hWnd == NULL) {
MessageBox(NULL, "CreateWindow() failed: Cannot create a window.",
"Error", MB_OK);
return NULL;
}

hDC = GetDC(hWnd);

/* there is no guarantee that the contents of the stack that become
the pfd are zeroed, therefore _make sure_ to clear these bits. */

memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | flags;
pfd.iPixelType = type;
pfd.cColorBits = 32;

pf = ChoosePixelFormat(hDC, &pfd);
if (pf == 0) {
MessageBox(NULL, "ChoosePixelFormat() failed: "
"Cannot find a suitable pixel format.", "Error", MB_OK);
return 0;
}

if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
MessageBox(NULL, "SetPixelFormat() failed: "
"Cannot set format specified.", "Error", MB_OK);
return 0;
}

DescribePixelFormat(hDC, pf, sizeof(PIXELFORMATDESCRIPTOR), &pfd);

ReleaseDC(hWnd, hDC);

return hWnd;
}

int APIENTRY
WinMain(HINSTANCE hCurrentInst, HINSTANCE hPreviousInst,
LPSTR lpszCmdLine, int nCmdShow)
{
HDC hDC;/* device context */
HGLRC hRC;/* opengl context */
HWND hWnd;/* window */
MSG msg;/* message */

hWnd = CreateOpenGLWindow("minimal", 0, 0, 256, 256, PFD_TYPE_RGBA, 0);
if (hWnd == NULL)
exit(1);

hDC = GetDC(hWnd);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);

ShowWindow(hWnd, nCmdShow);

while(GetMessage(&msg, hWnd, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}

wglMakeCurrent(NULL, NULL);
ReleaseDC(hWnd, hDC );
wglDeleteContext(hRC);
DestroyWindow(hWnd);

return msg.wParam;
}



[Edited by - jessica_chen on January 8, 2008 2:41:05 PM]

Share this post


Link to post
Share on other sites
// this projects cannot work fine - performance is really high.
// why? how shall i modify it?
// i think maybe u can help me find the solution.
// i wrote the code based on the project above.
// there are 3 files in this projects: main.cpp;main.h;rsrc.rc

// 1. main.cpp
#include <windows.h>
#include <process.h>
#include "main.h"
#include <gl/gl.h>
#include <stdio.h>
#include <stdlib.h>

HWND ghMainDialog;
HWND Structure;
HWND About;
HWND hwndTimer;
UINT KBcod;

int nCmdShow;
HDC hDC;

HDC ghDC;
HGLRC ghRC;

typedef unsigned (WINAPI *PBEGINTHREADEX_THREADFUNC)(
LPVOID lpThreadParameter
);
typedef unsigned *PBEGINTHREADEX_THREADID;

// angle variables
float angx = 0.0f;
float angy = 0.0f;
float angz = 1.0f;
// grid variables
float Fx = 0.0f;
float Fy = 1.0f;
float Sx = 0.87f;
float Sy = -0.5f;
float Tx = -0.87f;
float Ty = -0.5f;
// speed
float theta = 0.0f;
float Spd = 1.0f;


BOOL CALLBACK OpenProc(HWND, UINT, WPARAM, LPARAM);
VOID EnableOpenGL( HWND hWnd, HDC * ghDC, HGLRC * ghRC );
VOID DisableOpenGL( HWND hWnd, HDC ghDC, HGLRC ghRC );

static char g_szClassName[] = "MyWindowClass";
static HINSTANCE g_hInst = NULL;

void
display()
{
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
/* rotate a triangle around */
glClear(GL_COLOR_BUFFER_BIT);

glPushMatrix();
glRotatef( theta, angx, angy, angz);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(Fx, Fy);
glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(Sx, Sy);
glColor3f(0.0f, 0.0f, 1.0f); glVertex2f(Tx, Ty);
glEnd();
glPopMatrix();

// printf("display\n");

SwapBuffers(ghDC);
// start of add
theta += Spd;
// end of add
}

int STDCALL WinMain (HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmd, int nCmdShow)
{
int i = 0;
HANDLE hThread;
DWORD dwThreadId;

g_hInst = hInstance;


MSG msg;
BOOL bQuit = FALSE;

ghMainDialog = CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(ID_DIALOG), NULL, OpenProc);

if(!ghMainDialog)
return FALSE;

ShowWindow(ghMainDialog, SW_SHOW);

UpdateWindow(ghMainDialog);

while(1)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE)
{
if (GetMessage(&msg, NULL, 0, 0) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
return TRUE;
}
}

}
}


BOOL CALLBACK OpenProc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
int len = 0;
HDC main;
LPRECT recy;

static PAINTSTRUCT ps;

switch(Message)
{
case WM_INITDIALOG:
case WM_CREATE:
// 2.
SetTimer(hWnd, 1, 10, NULL);
// 3.
ghDC = GetDC(hWnd);
// if (!bSetupPixelFormat(ghDC))
// PostQuitMessage (0);

ghRC = wglCreateContext(ghDC);
wglMakeCurrent(ghDC, ghRC);

Structure = GetDlgItem(hWnd,IDC_STRUCT);

// enable OpenGL for the window
EnableOpenGL( Structure, &ghDC, &ghRC );

break;


case WM_TIMER:
printf("WindowProc WM_TIMER\n");
PostMessage(hWnd, WM_PAINT, 0, 0);
break;
// End of add
case WM_PAINT:
printf("WindowProc WM_PAINT\n");
display();
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;

case WM_SIZE:
printf("WindowProc WM_SIZE\n");
glViewport(0, 0, LOWORD(lParam), HIWORD(lParam));
PostMessage(hWnd, WM_PAINT, 0, 0);
break;

case WM_CLOSE:
DisableOpenGL(Structure, ghDC, ghRC);
DestroyWindow (hWnd);
break;

case WM_DESTROY:
KillTimer(hWnd, 1);
DisableOpenGL(Structure, ghDC, ghRC);
PostQuitMessage (0);
break;


case ID_FILE_EXIT:
EndDialog(hWnd, IDCANCEL);
return TRUE;

case IDC_ABOUT:
system("start IExplore.exe http://users.pandora.be/gothicsouls");
MessageBox (NULL, "OpenGL" , "About...", 0 + MB_ICONASTERISK);
break;

case IDC_MODIFY:

len = GetWindowTextLength(GetDlgItem(hWnd, IDC_SPEED));
if(len > 0)
{
char* Speed;
Speed = (char*)GlobalAlloc(GPTR, len + 1);
GetDlgItemText(hWnd, IDC_SPEED, Speed, len + 1);
sscanf(Speed,"%f", &Spd);
GlobalFree((HANDLE)Speed);
}

len = GetWindowTextLength(GetDlgItem(hWnd, ANGX));
if(len > 0)
{
char* AngleX;
AngleX = (char*)GlobalAlloc(GPTR, len + 1);
GetDlgItemText(hWnd, ANGX, AngleX, len + 1);
sscanf(AngleX,"%f", &angx);
GlobalFree((HANDLE)AngleX);
}

len = GetWindowTextLength(GetDlgItem(hWnd, ANGY));
if(len > 0)
{
char* AngleY;
AngleY = (char*)GlobalAlloc(GPTR, len + 1);
GetDlgItemText(hWnd, ANGY, AngleY, len + 1);
sscanf(AngleY,"%f", &angy);
GlobalFree((HANDLE)AngleY);
}

len = GetWindowTextLength(GetDlgItem(hWnd, ANGZ));
if(len > 0)
{
char* AngleZ;
AngleZ = (char*)GlobalAlloc(GPTR, len + 1);
GetDlgItemText(hWnd, ANGZ, AngleZ, len + 1);
sscanf(AngleZ,"%f", &angz);
GlobalFree((HANDLE)AngleZ);
}

len = GetWindowTextLength(GetDlgItem(hWnd, FIRSTX));
if(len > 0)
{
char* FirstX;
FirstX = (char*)GlobalAlloc(GPTR, len + 1);
GetDlgItemText(hWnd, FIRSTX, FirstX, len + 1);
sscanf(FirstX,"%f", &Fx);
GlobalFree((HANDLE)FirstX);
}

len = GetWindowTextLength(GetDlgItem(hWnd, FIRSTY));
if(len > 0)
{
char* FirstY;
FirstY = (char*)GlobalAlloc(GPTR, len + 1);
GetDlgItemText(hWnd, FIRSTY, FirstY, len + 1);
sscanf(FirstY,"%f", &Fy);
GlobalFree((HANDLE)FirstY);
}

len = GetWindowTextLength(GetDlgItem(hWnd, SECONDX));
if(len > 0)
{
char* SecondX;
SecondX = (char*)GlobalAlloc(GPTR, len + 1);
GetDlgItemText(hWnd, SECONDX, SecondX, len + 1);
sscanf(SecondX,"%f", &Sx);
GlobalFree((HANDLE)SecondX);
}

len = GetWindowTextLength(GetDlgItem(hWnd, SECONDY));
if(len > 0)
{
char* SecondY;
SecondY = (char*)GlobalAlloc(GPTR, len + 1);
GetDlgItemText(hWnd, SECONDY, SecondY, len + 1);
sscanf(SecondY,"%f", &Sy);
GlobalFree((HANDLE)SecondY);
}

len = GetWindowTextLength(GetDlgItem(hWnd, THIRDX));
if(len > 0)
{
char* ThirdX;
ThirdX = (char*)GlobalAlloc(GPTR, len + 1);
GetDlgItemText(hWnd, THIRDX, ThirdX, len + 1);
sscanf(ThirdX,"%f", &Tx);
GlobalFree((HANDLE)ThirdX);
}

len = GetWindowTextLength(GetDlgItem(hWnd, THIRDY));
if(len > 0)
{
char* ThirdY;
ThirdY = (char*)GlobalAlloc(GPTR, len + 1);
GetDlgItemText(hWnd, THIRDY, ThirdY, len + 1);
sscanf(ThirdY,"%f", &Ty);
GlobalFree((HANDLE)ThirdY);
}
//sscanf(string, "%f", floatnumber)//
break;

// case WM_DESTROY:
// DestroyWindow(ghMainDialog);
// PostQuitMessage (0);
// return 0;
// break;

default:
return FALSE;
}
return TRUE;
}

// Enable OpenGL

VOID EnableOpenGL( HWND hWnd, HDC * ghDC, HGLRC * ghRC )
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;

// get the device context (DC)
*ghDC = GetDC( hWnd );

// set the pixel format for the DC
// ZeroMemory( &pfd, sizeof( pfd ) );
memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
iFormat = ChoosePixelFormat( *ghDC, &pfd );
SetPixelFormat( *ghDC, iFormat, &pfd );

// create and enable the render context (RC)
*ghRC = wglCreateContext( *ghDC );
wglMakeCurrent( *ghDC, *ghRC );

printf("EnableOpenGL\n");
}


// Disable OpenGL

VOID DisableOpenGL( HWND hWnd, HDC ghDC, HGLRC ghRC )
{
wglMakeCurrent( NULL, NULL );
wglDeleteContext( ghRC );
ReleaseDC( Structure, ghDC );
}


=======================================
// 2. MAIN.H

#define ID_DIALOG 101
#define IDC_STRUCT 999
#define IDC_ABOUT 56

#define ANGX 2001
#define ANGY 2002
#define ANGZ 2003

#define FIRSTX 3001
#define FIRSTY 3002
#define SECONDX 3003
#define SECONDY 3004
#define THIRDX 3005
#define THIRDY 3006

#define IDC_SPEED 4001

#define IDC_MODIFY 7001

#define ID_FILE_EXIT 8001
#define ID_HELP 8002
#define ID_ABOUT 8003

#define IDR_MENU 9001
===========================
// 3. Rsrc.rc

#include <windows.h>
#include "main.h"
//Microsoft Developer Studio generated resource script.
//


#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#ifndef __BORLANDC__
#include "afxres.h"
#endif

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources


#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32



IDR_MENU MENU DISCARDABLE
BEGIN
// 1. File
POPUP "&File"
BEGIN
MENUITEM "&Exit", ID_FILE_EXIT
END

// 3. Help
POPUP "&Help"
BEGIN
MENUITEM "&Help", ID_HELP
MENUITEM SEPARATOR
MENUITEM "&About...", ID_ABOUT
END
END


ID_DIALOG DIALOG 120, 100, 304, 300
style DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "OpenGL"
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
FONT 8, "HELV"
{
CONTROL "0.0f", 2001, "EDIT", 0x50810000, 10, 20, 27, 14
CONTROL "0.0f", 2002, "EDIT", 0x50810000, 45, 20, 27, 14
CONTROL "1.0f", 2003, "EDIT", 0x50810000, 80, 20, 27, 14
CONTROL "Modify", 7001, "BUTTON", 0x50018000, 10, 183, 60, 14
CONTROL "Angle:", 0, "STATIC", 0x50020000, 10, 5, 23, 10
CONTROL "Speed:", 0, "STATIC", 0x50020000, 10, 164, 24, 11
CONTROL "1.0f", 4001, "EDIT", 0x50810000, 39, 162, 30, 14
CONTROL "Structure", 999, "BUTTON", 0x50000007, 120, 17, 174, 181
CONTROL "About", 56, "BUTTON", 0x50018000, 76, 183, 35, 14
CONTROL "Grid points:", 0, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 10, 45, 38, 12
CONTROL "First:", 0, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 10, 60, 18, 10
CONTROL "Second:", 0, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 10, 90, 28, 9
CONTROL "Third:", 0, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 10, 120, 21, 10
CONTROL "X", 0, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 50, 45, 8, 9
CONTROL "Y", 0, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 80, 45, 8, 9
CONTROL "0.0f", 3001, "EDIT", ES_AUTOHSCROLL | ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 40, 70, 20, 14
CONTROL "1.0f", 3002, "EDIT", ES_AUTOHSCROLL | ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 75, 70, 20, 14
CONTROL "0.87f", 3003, "EDIT", ES_AUTOHSCROLL | ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 40, 100, 20, 14
CONTROL "-0.5f", 3004, "EDIT", ES_AUTOHSCROLL | ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 75, 100, 20, 14
CONTROL "-0.87f", 3005, "EDIT", ES_AUTOHSCROLL | ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 40, 130, 20, 14
CONTROL "-0.5f", 3006, "EDIT", ES_AUTOHSCROLL | ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 75, 130, 20, 14
}

//500 ICON MOVEABLE PURE LOADONCALL DISCARDABLE "D:/Dev-C++/Icon/console.ico"




[Edited by - jessica_chen on January 8, 2008 2:44:04 PM]

Share this post


Link to post
Share on other sites
Please post source inside
[ code ] source goes here [ / code ]
tags (without the spaces), since it will make the source a lot easier to read for the rest of us :)

Share this post


Link to post
Share on other sites
Quote:
Please post source inside
[ code ] source goes here [ / code ]
tags (without the spaces), since it will make the source a lot easier to read for the rest of us :)


For long snippets of code, it's better to replace 'code' with 'source' in both brackets. It will create a small white scrollable box, like this:


void foo() {
// ...
}



You might want to edit your posts and add this to make them easier to read.

Share this post


Link to post
Share on other sites
jessica_chen,
If you are asking why the second example use 100% CPU resource, then, the problem is your message loop. PeekMessage() will keep executed, so "while(1)" loop does not rest. However, when GetMessage() is used in message loop, the system will be idle until an event is triggered.

You may have 2 options:
One is using Timer function with a generic message loop;
while(::GetMessage(&msg, 0, 0, 0) > 0)
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}

The other is using PeekMessage() without Timer;
while(1)
{
::Sleep(10);

if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
{
break;
}
else
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
else
{
display();
}
}

Notice the first line in "while(1)" block. Sleep(10) makes the application idle for 10 ms. It gives a similar effect as SetTimer(10).

Share this post


Link to post
Share on other sites
Hi, SongHo,

Thanks very much. They works fine now.

May I ask more questions about your suggestion?
(1) why you use ::? is the style from C++?
(2) my colleague told me, Sleep() is always the temp solution. because Sleep() will block the process. so i should use timer to do, then the process won't be stopped. what do you think about Sleep()? do you think in formal project, we can use Sleep()?

Thanks.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!