Original Post
I wrote an OpenGL Checkers game program for Mac OS 10.4 using XCode 2.x. The game runs quite well, so I decided to also make one for Windows using DevC++. Just like with XCode, getting images to load and display is turning out to be a monumental task. The error is my own messageBox error saying that there is no hBitmap (!hBitmap). What could be causing this? The code is included below. ------------------------------------------------------------------------------ To start, a new C plus plus Windows project was created and saved in its own folder which also contains a 512x512 24 bit bmp image of a checkerboard (checkerboard.bmp). ------------------------------------------------------------------------------ A new resource file, "Images.rc" was created with the following information: CHECKERBOARD BITMAP "checkerboard.bmp" ------------------------------------------------------------------------------ main.cpp looks like this: #include #include #include #include #include using namespace std; GLuint texture; static HINSTANCE hinst; HBITMAP hBitmap; BITMAP bitmap; bool determinePixelFormat(HDC *hDC, HGLRC *hRC, HWND hwnd); LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { glClearColor(0.0, 0.0, 0.0, 0.0); glClearDepth(1.0); glShadeModel(GL_SMOOTH); glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); hBitmap = (HBITMAP) LoadImage(hinst, "CHECKERBOARD", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); if (!hBitmap) { MessageBox(NULL, "LoadImage failed", "ERROR", MB_OK); } int get_object; get_object = GetObject(hBitmap, sizeof(bitmap), &bitmap); if (!get_object) { MessageBox(NULL, "GetObject failed", "ERROR", MB_OK); } GLint bm_bits_pixel = (GLint) bitmap.bmBitsPixel; GLint internal_format; if (bm_bits_pixel < 32) { internal_format = GL_RGB; } else { internal_format = GL_RGBA; } GLuint width = (GLuint) bitmap.bmWidth; GLuint height = (GLuint) bitmap.bmHeight; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, internal_format, width, height, 0, internal_format, GL_UNSIGNED_BYTE, bitmap.bmBits); DeleteObject(hBitmap); bool quit_game = FALSE; WNDCLASSEX wincl; HWND hwnd; HDC hDC; HGLRC hRC; MSG messages; wincl.cbSize = sizeof(WNDCLASSEX); wincl.style = CS_OWNDC; wincl.lpfnWndProc = WinProc; wincl.cbClsExtra = 0; wincl.cbWndExtra = 0; wincl.hInstance = hThisInstance; wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION); wincl.hCursor = LoadCursor (NULL, IDC_CROSS); wincl.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wincl.lpszMenuName = NULL; wincl.lpszClassName = "Checkers"; wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION); if (!RegisterClassEx(&wincl)) { return 0; } hwnd = CreateWindowEx(NULL, "Checkers", "Checkers Beta 0.70", WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, 100, 100, 768, 600, NULL, NULL, hThisInstance, 0); if (!determinePixelFormat(&hDC, &hRC, hwnd)) { PostQuitMessage (0); } ShowWindow(hwnd, SW_SHOWNORMAL); UpdateWindow(hwnd); while (!quit_game) { if (PeekMessage(&messages, NULL, 0, 0, PM_REMOVE)) { if (messages.message == WM_QUIT) { quit_game = TRUE; } else { TranslateMessage(&messages); DispatchMessage(&messages); } } else { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glDisable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, -1.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, 1.0, 0.0); glTexCoord2f(1.0, 1.0); glVertex3f(0.5, 1.0, 0.0); glTexCoord2f(1.0, 0.0); glVertex3f(0.5, -1.0, 0.0); glEnd(); glDisable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); glFlush(); SwapBuffers(hDC); } } wglMakeCurrent(NULL, NULL); wglDeleteContext(hRC); ReleaseDC(hwnd, hDC); return (messages.wParam); } bool determinePixelFormat(HDC *hDC, HGLRC *hRC, HWND hwnd) { PIXELFORMATDESCRIPTOR pfd; pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.dwLayerMask = PFD_MAIN_PLANE; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; pfd.cDepthBits = 16; pfd.cAccumBits = 0; pfd.cStencilBits = 0; *hDC = GetDC(hwnd); int pixelformat; pixelformat = ChoosePixelFormat(*hDC, &pfd); if (!pixelformat) { MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK); return (FALSE); } bool set_pixel_format; set_pixel_format = SetPixelFormat(*hDC, pixelformat, &pfd); if (!set_pixel_format) { MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK); return (FALSE); } *hRC = wglCreateContext(*hDC); wglMakeCurrent(*hDC, *hRC); return (TRUE); } LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_QUIT: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; }