Original Post
Anyways, before I post my code, let me explain my problem. I am making a 2D OpenGL game.Anyways, I am drawing 16x16 textures to the screen(I know, that's smaller than usual), and I only get 1/4 of my 640x480 window (about 300 tiles total). Any more and the program send me immediately to my "shutdown error" message boxes, and it displays them all. This is odd to me becuase they don't show up if I stay at or under 300 16x16 tiles. Anyways, I must be doing something wrong, since i've heard of opengl 2d games that can easily run 1500 32x32 tiles. Now, onto the code: incs.h topglobals.h topglfunc.h classes.h globals.h glfunc.h and finally, main.cpp Anyways, if someone could please point out my mistake, and maybe show me how to correct it, I would greatly appreciate it. P.S. I have so many files because i'm a bit of an organization freak. Thanks, Lycio [Edited by - lycio on May 12, 2008 8:15:06 PM]
#include <windows.h>
#include <stdio.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>
#pragma comment(lib,"glu32.lib")
#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"glaux.lib")
#include "topglobals.h"
#include "topglfunc.h"
#include "classes.h"
#include "globals.h"
#include "glfunc.h"
#define SMALL_TILE_WIDTH 16
#define SMALL_TILE_HEIGHT 16
#define TILE_WIDTH 32
#define TILE_HEIGHT 32
GLuint bgtex[1];
void glEnable2D()
{
int vPort[4];
glGetIntegerv(GL_VIEWPORT,vPort);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0,vPort[2],0,vPort[3],-1,1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
}
void glDisable2D()
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
struct Tile
{
int x;
int y;
int width;
int height;
GLuint texture[1];
Tile(int startx,int starty,int startwidth,int startheight)
{
x = startx;
y = starty;
width = startwidth;
height = startheight;
}
void draw()
{
glBindTexture(GL_TEXTURE_2D,bgtex[0]);
glEnable2D();
glBegin(GL_QUADS);
glTexCoord2i(0,0);
glVertex2i((x * width),(y * height));
glTexCoord2i(1,0);
glVertex2i((x * width) + width,(y * height));
glTexCoord2i(1,1);
glVertex2i((x * width) + width,(y * height) + height);
glTexCoord2i(0,1);
glVertex2i((x * width),(y * height) + height);
glEnd();
glDisable2D();
}
};
//system variables
HGLRC hRC = NULL;
HDC hDC = NULL;
HWND hWnd = NULL;
HINSTANCE hInstance;
//other variables
bool keys[256];
bool active = true;
//tile varaibles
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define MAP_WIDTH 20
#define MAP_HEIGHT 15
Tile *map[MAP_WIDTH][MAP_HEIGHT];
//Tile *character;
//prototypes
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
AUX_RGBImageRec *LoadBMP(char *Filename)
{
FILE *File = NULL;
if(!Filename)
{
return NULL;
}
File = fopen(Filename,"r");
if(File)
{
fclose(File);
return auxDIBImageLoad(Filename);
}
return NULL;
}
int LoadGLTextures()
{
int Status = false;
AUX_RGBImageRec *TextureImage[1];
memset(TextureImage,0,sizeof(void *)*1);
if(TextureImage[0] = LoadBMP("small-tile-grass.bmp"))
{
Status = true;
glGenTextures(1,&bgtex[0]);
glBindTexture(GL_TEXTURE_2D,bgtex[0]);
glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
if(TextureImage[0])
{
if(TextureImage[0]->data)
{
free(TextureImage[0]->data);
}
free(TextureImage[0]);
}
return Status;
}
int InitGL()
{
if(!LoadGLTextures())
{
return false;
}
glEnable(GL_TEXTURE_2D);
//glShadeModel(GL_SMOOTH);
glClearColor(0.0f,0.0f,0.0f,0.0f);
glDisable(GL_DEPTH_TEST);
return true;
}
void draw_background()
{
for(int x = 0;x < MAP_WIDTH;x++)
{
for(int y = 0;y < MAP_HEIGHT;y++)
{
map[x][y] = new Tile(x,y,SMALL_TILE_WIDTH,SMALL_TILE_HEIGHT);
map[x][y]->draw();
}
}
}
int DrawGLScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
draw_background();
return true;
}
void KillGLWindow()
{
if(hRC)
{
if(!wglMakeCurrent(NULL,NULL))
{
MessageBox(NULL,"Release of DC and RC failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
if(!wglDeleteContext(hRC))
{
MessageBox(NULL,"Release rendering context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
}
hRC = NULL;
}
if(hDC && !ReleaseDC(hWnd,hDC))
{
MessageBox(NULL,"Release device context failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hDC = NULL;
}
if(hWnd && !DestroyWindow(hWnd))
{
MessageBox(NULL,"Could not release window.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hWnd = NULL;
}
if(!UnregisterClass("OpenGL",hInstance))
{
MessageBox(NULL,"Could not unregister class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);
hInstance = NULL;
}
}
bool CreateGLWindow(char* title,int width,int height,int bits)
{
GLuint PixelFormat;
WNDCLASS wc;
DWORD dwExstyle;
DWORD dwstyle;
RECT WindowRect;
WindowRect.left = (long)0;
WindowRect.right = (long)width;
WindowRect.top = (long)0;
WindowRect.bottom = (long)height;
hInstance = GetModuleHandle(NULL);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
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,"Failed to register the window class.","ERROR",MB_OK | MB_ICONEXCLAMATION);
return false;
}
dwExstyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
dwstyle = WS_OVERLAPPEDWINDOW;
AdjustWindowRectEx(&WindowRect,dwstyle,false,dwExstyle);
if(!(hWnd = CreateWindowEx(dwExstyle,"OpenGL",title,WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwstyle,0,0,WindowRect.right - WindowRect.left,WindowRect.bottom - WindowRect.top,NULL,NULL,hInstance,NULL)))
{
KillGLWindow();
MessageBox(NULL,"Window creation error.","ERROR",MB_OK | MB_ICONEXCLAMATION);
return false;
}
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(!(hDC = GetDC(hWnd)))
{
KillGLWindow();
MessageBox(NULL,"Can't create a GL device context.","ERROR",MB_OK | MB_ICONEXCLAMATION);
return false;
}
if(!(PixelFormat = ChoosePixelFormat(hDC,&pfd)))
{
KillGLWindow();
MessageBox(NULL,"Can't find a suitable pixel format.","ERROR",MB_OK + MB_ICONEXCLAMATION);
return false;
}
if(!SetPixelFormat(hDC,PixelFormat,&pfd))
{
KillGLWindow();
MessageBox(NULL,"Can't set the pixel format.","ERROR",MB_OK | MB_ICONEXCLAMATION);
return false;
}
if(!(hRC = wglCreateContext(hDC)))
{
KillGLWindow();
MessageBox(NULL,"Can't create a GL rendering context.","ERROR",MB_OK | MB_ICONEXCLAMATION);
return false;
}
if(!wglMakeCurrent(hDC,hRC))
{
KillGLWindow();
MessageBox(NULL,"Can't activate the GL rendering context.","ERROR",MB_OK | MB_ICONEXCLAMATION);
return false;
}
ShowWindow(hWnd,SW_SHOW);
SetForegroundWindow(hWnd);
SetFocus(hWnd);
if(!InitGL())
{
KillGLWindow();
MessageBox(NULL,"Initialization failed.","ERROR",MB_OK | MB_ICONEXCLAMATION);
return false;
}
return true;
}
#include "incs.h"
LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case WM_ACTIVATE:
if(!HIWORD(wParam))
{
active = true;
}
else
{
active = false;
}
return 0;
case WM_SYSCOMMAND:
switch(wParam)
{
case SC_SCREENSAVE:
case SC_MONITORPOWER:
return 0;
}
break;
case WM_CLOSE:
PostQuitMessage(0);
return 0;
case WM_KEYDOWN:
keys[wParam] = true;
return 0;
case WM_KEYUP:
keys[wParam] = false;
return 0;
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
MSG msg;
bool done = false;
if(!CreateGLWindow("OpenGL Tiling Test",SCREEN_WIDTH,SCREEN_HEIGHT,16))
{
return 0;
}
while(!done)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message == WM_QUIT)
{
done = true;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
if(active)
{
if(keys[VK_ESCAPE])
{
done = true;
}
else
{
DrawGLScene();
SwapBuffers(hDC);
}
}
}
}
KillGLWindow();
return msg.wParam;
}