The Ultimate In "What The &@#( Is Going On?"

Started by
8 comments, last by _the_phantom_ 18 years, 7 months ago
Ok, I'm going to post a lot of code. Sorry everyone, but please read through, download & compile, something! I have spent 2 whole days on this! The problem: The program window opens and closes immiediately. SEND AID! I actaully shought about buying a shotgun just to shoot my computer. Anyone got any prices on shotguns? Main.h

//This is the main loop function.  This is where the game cycle is executed.
#if !defined (MAIN)
#define MAIN

#include "EWindow.h"
#include "EObject.h"
#include <GL/gl.h>
#include <GL/glu.h>

//This is where all variables used in the GameLoop() go:
bool fullscreen=false;
bool max=false;
bool min=false;
float angle;
int ww=800;
int wh=600;
EObject test;

void Init()
{
    glClearColor(0.0f,0.0f,0.0f,0.0f);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);
    
    glViewport(0,0,ww,wh);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
	gluPerspective(45.0f,(GLfloat)ww/(GLfloat)wh,10.0f,10000.0f);
    
    glEnable(GL_DEPTH_TEST);
    glPolygonMode (GL_FRONT_AND_BACK,GL_POINT);
}

//Finally the game loop...
bool GameLoop()
{
	test.display();
    return true;
}

#endif MAIN

Main.cpp

#define WIN32_LEAN_AND_MEAN

#include "include/Main.h"
#include <windows.h>

bool quit = false;
bool once = true;
HDC ghdc;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	MSG message;
	EWindow window(fullscreen,ww,wh,32);
	
    test.load3ds("main.3ds");
	test.assigntex("blank.bmp");

	while(!quit)
	{
		PeekMessage(&message,NULL,0,0,PM_REMOVE);
		
        if (message.message == WM_QUIT)
			quit=true;
		else
		{
	    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	        GameLoop();
      		SwapBuffers(ghdc);

			TranslateMessage(&message);
			DispatchMessage(&message);
		}
	}

	return message.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static HDC hdc;
	static HGLRC hrc;
	PAINTSTRUCT ps;

	switch (message)
	{
	case WM_CREATE:
		{
			hdc = GetDC(hwnd);
			ghdc=hdc;
			EWindow::SetupPixelFormat(hdc);
			hrc = wglCreateContext(hdc);
			wglMakeCurrent(hdc,hrc);
			once = true;

			return 0;
			break;
		}
	case WM_CLOSE:
		{
			wglMakeCurrent(hdc,NULL);
			wglDeleteContext(hrc);
			PostQuitMessage(0);

			return 0;
			break;
		}
    case WM_QUIT:
         {
            wglMakeCurrent(hdc,NULL);
            wglDeleteContext(hrc);
            PostQuitMessage(0);
            
            return 0;
            break;
         }
	case WM_DESTROY:
		{
			wglMakeCurrent(hdc,NULL);
			wglDeleteContext(hrc);
			PostQuitMessage(0);

			return 0;
			break;
		}
	case WM_PAINT:
		{
			BeginPaint(hwnd, &ps);
			EndPaint(hwnd, &ps);
			
			return 0;
			break;
		}
	case WM_SIZE:
		{
            if( once )
                once = false;
            else
                Init();     
                 
           	return 0;
			break;
		}
	default:
		break;
	}

	return DefWindowProc(hwnd,message,wParam,lParam);
}

EWindow.h

//EWindow.h  Contains that class for window creation, management, and destruction.

#if !defined (EWINDOW)
#define EWINDOW

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/GLAUX.h>

extern HDC ghdc;
void SetupPixelFormat(HDC);
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

class EWindow
{
private:
	int fullscreen;			//Is window full screen?
	int h,w,bpp;
	RECT wndrect;
	WNDCLASSEX wndclass;	//Window Class
	HWND hwnd;				//Window Handle
	HINSTANCE hinstance;	//Application Handle
//	ERender* RenderObject;	//Render Object
public:
	//Functions
	EWindow();
	EWindow(bool,int,int,int);
	~EWindow();
	int GetHeight()	//Get Height
	{	return h; }
	int GetWidth()		//Get Width
	{	return w; }
	int GetBPP()	//Get bit depth
	{ return bpp;}
	bool ECreateClass();	//Create and registers class
	bool ECreateWindow(bool,int,int,int);	//Create and display window
	bool EDestroy();		//Closes window and frees memory
	static void SetupPixelFormat(HDC);	//Set up the pixel format for OpenGL
};

#endif EWINDOW


EWindow.cpp

#include "include/EWindow.h"
#include <stdio.h>
#include <GL/gl.h>
#include <GL/glu.h>

void Init();

EWindow::EWindow()
{
	if(!ECreateClass())
		PostQuitMessage(0);
	
	if(!ECreateWindow(true,800,600,32))
		PostQuitMessage(0);
}

EWindow::EWindow(bool fullscreen, int w, int h, int bpp)
{
	if(!ECreateClass())
		PostQuitMessage(0);
	if(!ECreateWindow(fullscreen,w,h,bpp))
		PostQuitMessage(0);
}

EWindow::~EWindow()
{
}

bool EWindow::ECreateClass()
{
	hinstance=GetModuleHandle(NULL);
	wndclass.cbSize = sizeof(WNDCLASSEX);
	wndclass.style = CS_HREDRAW | CS_VREDRAW;
	wndclass.lpfnWndProc = WndProc;
	wndclass.cbClsExtra = 0;
	wndclass.cbWndExtra = 0;
	wndclass.hInstance = hinstance;
	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndclass.hbrBackground = NULL;
	wndclass.lpszMenuName = NULL;
	wndclass.lpszClassName = "3dge";
	wndclass.hIconSm = LoadIcon(NULL, IDI_WINLOGO);

	if(!RegisterClassEx(&wndclass))
	{
		MessageBox(NULL, "\tError:  Could not register window", "Error", NULL);
		return false;
	}

	return true;
}

bool EWindow::ECreateWindow(bool fulllscreen,int width, int height, int bits)
{
	DWORD dwStyle;
	DWORD dwExStyle;

	fullscreen = fulllscreen;
	w = width;
	h = height;
	bpp = bits;

	if(fullscreen)
	{
		dwExStyle = WS_EX_APPWINDOW;
		dwStyle = WS_POPUP;
		ShowCursor(FALSE);

		DEVMODE devmodescreen;
		memset(&devmodescreen, 0, sizeof(devmodescreen));
		devmodescreen.dmSize = sizeof(devmodescreen);
		devmodescreen.dmPelsWidth = w;
		devmodescreen.dmPelsHeight = h;
		devmodescreen.dmBitsPerPel = bpp;
		devmodescreen.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;

		if (ChangeDisplaySettings(&devmodescreen,CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
			fullscreen = false;
	}
	else
	{
		dwExStyle = NULL;
		dwStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_SYSMENU | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
	}

	wndrect.top = 0;
	wndrect.left = 0;
	wndrect.right = w;
	wndrect.bottom = h;

	AdjustWindowRectEx(&wndrect,dwStyle,false,dwExStyle);

	hwnd = CreateWindowEx(NULL,
		"3dge",
		"Crosonio Game Engine",
		dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
		0,0,
		w,h,
		NULL,
		NULL,
		hinstance,
		NULL);

	if (!hwnd)
	{
		MessageBox(NULL, "\tError:  Could not create window", "Error", NULL);
		PostQuitMessage(0);
		return false;
	}

	ShowWindow(hwnd, SW_SHOW);
	UpdateWindow(hwnd);

	return true;
}

void EWindow::SetupPixelFormat(HDC hdc)
{
	int iFormat;

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

	iFormat = ChoosePixelFormat(hdc, &pfd);

	SetPixelFormat(hdc,iFormat,&pfd);
}

EObject.h

#if !defined (EOBJECT_H)
#define EOBJECT_H

#include "Texture.h"

//Point structure, containing x,y, and z coordinates
struct point
{
	float x,y,z;
};

//Triangle structure, containing 3 verticie numbers
struct triangle
{
	int a,b,c;
};

//UV Point sturucture, containing u and v coordinates
struct uvpoint 
{
	float u,v;
};

/* EObject Class, containing model data and functions
to load, edit, display, and unload model data */
class EObject
{
private:
	//3d data
	point* verticies;
	triangle* tris;
	uvpoint* uv;

	//EObject ammount tags
	int numvert;
	int numtri;
public:
	//Basic Innitialization
	EObject();
	EObject(char*);
	~EObject();

	//Member Functions
	bool load3ds(char*);
	void display();
	void update();
	void unload();
	void assigntex(char*);

	//EObject ID Tag
	unsigned int texture;
};

#endif EOBJECT_H

EObject.cpp

#define MAIN 0x4D4D
#define EDITOR 0x3D3D
#define OBJECT 0x4000
#define TRIANGLE 0X4100
#define VERTICIES 0x4110
#define FACE 0x4120
#define UV 0x4140

#include "include/EObject.h"
#include "include/EWindow.h"
#include <stdio.h>
#include <io.h>
#include <GL/gl.h>

//Basic EObject constructor
EObject::EObject()
{
	//Pointer Data
	verticies = NULL;
	tris = NULL;
	uv = NULL;

	//Non-Pointer Data
	texture = 0;
	numvert = 0;
	numtri = 0;
}

//File loading EObject constructor
EObject::EObject(char* filename)
{
	load3ds(filename);
}

//EObject destructor
EObject::~EObject()
{
	delete[] verticies;
	delete[] tris;
	delete[] uv;
}

//.3ds file loader
bool EObject::load3ds(char* filename)
{
	//Data
	FILE* fp;	//The file pointer (file access)

	int count;	//Used for data loading
	bool done = false;	//Determines if file loading is done

	unsigned short chunkid;		//The Chunk ID tag
	unsigned long chunklength;	//The Chunk length
	unsigned char temp;			//Temporary char for name bypass
	unsigned short datalength;	//The Chunk Data length

	//Open file
	fp = fopen(filename,"rb");

	//If file couldn't be opened, make object null
	if( fp==NULL )
	{
		verticies = NULL;
		tris = NULL;
		uv = NULL;

		texture = 0;
		numvert = 0;
		numtri = 0;
		MessageBox(NULL,"File Not Loaded.","File",NULL);
		return false;
	}

	//Begin the reading process
	while( ftell (fp) < filelength (fileno (fp)) )
	{
		//Read the chunk ID tag and length
		fread(&chunkid,2,1,fp);
		fread(&chunklength,4,1,fp);

		switch (chunkid)
		{
		//Main Chunk, no data
		case MAIN:
			break;
		//3d Editor Chunk, no data
		case EDITOR:
			break;
		//Object Block, object name
		case OBJECT:
			do
			{
				fread(&temp,1,1,fp);
			}while(temp != '\0');
			break;
		//Triangle Mesh Block, no data
		case TRIANGLE:
			break;
		//Verticies Block, number of verticies and their data
		case VERTICIES:
			fread(&datalength,2,1,fp);
			verticies = new point[datalength];
			numvert = datalength;
			for( count = 0; count < datalength; count++)
			{
				fread(&verticies[count].x,4,1,fp);
				fread(&verticies[count].y,4,1,fp);
				fread(&verticies[count].z,4,1,fp);
			}
			break;
		//Faces Block, number of faces and their data
		case FACE:
			fread(&datalength,2,1,fp);
			tris = new triangle[datalength];
			numtri = datalength;
			for( count = 0; count < datalength; count++)
			{
				fread(&tris[count].a,2,1,fp);
				fread(&tris[count].b,2,1,fp);
				fread(&tris[count].c,2,1,fp);
				fseek(fp,2,SEEK_CUR);
			}
			break;
		//UV Points Block, number of UV points and their data
		case UV:
			fread(&datalength,2,1,fp);
			uv = new uvpoint[datalength];
			for( count = 0; count < datalength; count++)
			{
				fread(&uv[count].u,4,1,fp);
				fread(&uv[count].v,4,1,fp);
			}
			break;
		//We don't care, so we move to the next Chunk on the hierarchy
		default:
			fseek(fp, chunklength-6, SEEK_CUR);
		}
	}
	//Done with file
	fclose(fp);
	return true;
}

void EObject::display()
{
	int count;

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glPushMatrix();
		glBindTexture(GL_TEXTURE_2D,texture);
		glTranslatef(0.0f,0.0f,-10.0f);
		glBegin(GL_TRIANGLES);
		for( count = 0; count < numtri; count += 3)
		{
			glTexCoord2f(uv[tris[count].a].u,uv[tris[count].a].v);
			glVertex3f(verticies[tris[count].a].x,verticies[tris[count].a].y,verticies[tris[count].a].z);
	     
			glTexCoord2f(uv[tris[count].b].u,uv[tris[count].b].v);
			glVertex3f(verticies[tris[count].b].x,verticies[tris[count].b].y,verticies[tris[count].b].z);

			glTexCoord2f(uv[tris[count].c].u,uv[tris[count].c].v);
			glVertex3f(verticies[tris[count].c].x,verticies[tris[count].c].y,verticies[tris[count].c].z);
		}
		glEnd();
	glPopMatrix();
}

void EObject::update()
{	}

void EObject::unload()
{	}

void EObject::assigntex(char* filename)
{
     gentexobj(filename,texture);     
}

Texture.h

#if !defined ( TEXTURE_H )
#define TEXTURE_H

struct image
{
	unsigned long x,y,size;
	unsigned short bpp;
	unsigned char* data;
};

void loadbmp(char* filename,image& text_o);
void gentexobj(char* filename,unsigned int& ID);
void gentextobj(unsigned int& ID,image* text_o);

#endif TEXTURE_H

Texture.cpp

#define WIN32_LEAN_AND_MEAN

#include "include/Texture.h"
#include <stdio.h>
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>

void loadbmp(char* filename,image& text_o)
{
	FILE* fp;
	unsigned char swap;
	unsigned long count;
	BITMAPFILEHEADER bfh;
	BITMAPINFOHEADER bih;

	fp = fopen(filename,"rb");
	if( fp == NULL )
	{
		MessageBox(NULL,"Bitmap Not Opened.","Bitmap",NULL);
	}
	//else
	//	MessageBox(NULL,"Bitmap Opened.","Bitmap",NULL);

	fread(&bfh,sizeof(BITMAPFILEHEADER),1,fp);
	if( bfh.bfType != 0x4D42 )
	{
	//	MessageBox(NULL,"Bitmap File Corrupt.","Bitmap",NULL);
		fclose(fp);
	}

	//Read all width, height, and bits.  Skips all the
	//extra crap we couldn't care less about.
	fread(&bih,sizeof(BITMAPINFOHEADER),1,fp);
	text_o.x = bih.biWidth;
	text_o.y = bih.biHeight;
	text_o.bpp = bih.biBitCount;
	text_o.size = bih.biSizeImage;
	
	text_o.data = new unsigned char[text_o.size];

	if( text_o.data == NULL )
	{
		delete[] text_o.data;
		fclose(fp);
	}

	fread(&text_o.data,1,text_o.size,fp);

	if( text_o.data == NULL )
	{
		fclose(fp);
	}

	for ( count = 0; count < text_o.size; count+=3)
	{
		swap = text_o.data[count];
		text_o.data[count] = text_o.data[count+2];
		text_o.data[count+2] = swap;
	}

	fclose(fp);
}

void gentexobj(char* filename,unsigned int& ID)
{
     image texto;
     loadbmp(filename,texto);
     glGenTextures(1,&ID);
     glBindTexture(GL_TEXTURE_2D, ID);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     
     glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,texto.x,texto.y,0,GL_RGB,GL_UNSIGNED_BYTE,texto.data);
}

void gentextobj(unsigned int& ID,image* text_o)
{
     glGenTextures(1,&ID);
     glBindTexture(GL_TEXTURE_2D,ID);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     
     glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,text_o->x,text_o->y,0,GL_RGB,GL_UNSIGNED_BYTE,text_o->data);
}

I beg of this whole community! Solve my problem!
We should do this the Microsoft way: "WAHOOOO!!! IT COMPILES! SHIP IT!"
Advertisement
Since it's a window problem I don't think it has anything to do with Textures.
An obvious question: Have you been using the debugger?

You say that "The program window opens and closes immediately". That means that Windows is creating your window just fine. Your problem probably isn't there.

This means (looking at your main loop) that your program is quitting in one of two ways: a quit message being posted, or the quit variable becoming true. I suggest that you set breakpoints throughout your code where either of these can happen, then step through your program. It could be that your code is succeeding, but posting a quit message in error, causing the window to be closed immediately.

You might like to try using exceptions to handle errors in your initialization code, too. I use a simple little exception class which lets me throw a message, and uses some natty preprocessor directives to print out the exact location of the error (function, line and file). It's a lot more informative than just calling PostQuitMessage when something goes wrong, and really helps debugging problems like this one. PM me if you'd like some more info on that...
My opinion is a recombination and regurgitation of the opinions of those around me. I bring nothing new to the table, and as such, can be safely ignored.[ Useful things - Firefox | GLee | Boost | DevIL ]
Yes, I am using a debugger. I also figured that window creation is not a problem. I will find out what the problem is according to how you say to solve this.
We should do this the Microsoft way: "WAHOOOO!!! IT COMPILES! SHIP IT!"
Also, the problem came about when I finished writing the texture part of the code. I had created a .3ds file loader and render function, but it wouldn't display. Hoping that the problem was that I had half set it up to have textures, I finished textures. I now arive at this problem.
We should do this the Microsoft way: "WAHOOOO!!! IT COMPILES! SHIP IT!"
Help still needed people! It's still not working!
We should do this the Microsoft way: "WAHOOOO!!! IT COMPILES! SHIP IT!"
send me a zip file of all those files to simplemail@gmail.com. I'll take a personal look at it for you! :p
Put a break point in your main, and another in your wndproc. Step through both line by line and see where EXACTLY shit goes bad.
No offense, but you certainly haven't run a debugger. Line 48 of Texture.cpp should be changed from:
fread(&text_o.data,1,text_o.size,fp);

to
fread(text_o.data,1,text_o.size,fp);

Since you were not writing to the correct place in memory, it caused corruption and probably caused the program to exit.

Once you have fixed that, you get another error, but this time in EObject::display. It looks like your array of triangle indexes is incorrectly loaded, which i believe is coming from your "FACE" case in EObject::load3ds. I don't have the time to look into that right now, but that should help you to get on tracks.

Y.
Hmmmm, ya know what I'm going to close this for a number of reasons, not least of which being this isnt directly an OpenGL problem and you've just dumpped the code to a program into the forum without trying to locate the problem.

If you have a specific opengl related problem then post again, however just posting a whole program with some vague 'fix it' request isnt what this forum is about.

This topic is closed to new replies.

Advertisement