Sign in to follow this  
dbzprogrammer

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

Recommended Posts

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!

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.
Sign in to follow this  

  • Forum Statistics

    • Total Topics
      627736
    • Total Posts
      2978869
  • Similar Content

    • By DelicateTreeFrog
      Hello! As an exercise for delving into modern OpenGL, I'm creating a simple .obj renderer. I want to support things like varying degrees of specularity, geometry opacity, things like that, on a per-material basis. Different materials can also have different textures. Basic .obj necessities. I've done this in old school OpenGL, but modern OpenGL has its own thing going on, and I'd like to conform as closely to the standards as possible so as to keep the program running correctly, and I'm hoping to avoid picking up bad habits this early on.
      Reading around on the OpenGL Wiki, one tip in particular really stands out to me on this page:
      For something like a renderer for .obj files, this sort of thing seems almost ideal, but according to the wiki, it's a bad idea. Interesting to note!
      So, here's what the plan is so far as far as loading goes:
      Set up a type for materials so that materials can be created and destroyed. They will contain things like diffuse color, diffuse texture, geometry opacity, and so on, for each material in the .mtl file. Since .obj files are conveniently split up by material, I can load different groups of vertices/normals/UVs and triangles into different blocks of data for different models. When it comes to the rendering, I get a bit lost. I can either:
      Between drawing triangle groups, call glUseProgram to use a different shader for that particular geometry (so a unique shader just for the material that is shared by this triangle group). or
      Between drawing triangle groups, call glUniform a few times to adjust different parameters within the "master shader", such as specularity, diffuse color, and geometry opacity. In both cases, I still have to call glBindTexture between drawing triangle groups in order to bind the diffuse texture used by the material, so there doesn't seem to be a way around having the CPU do *something* during the rendering process instead of letting the GPU do everything all at once.
      The second option here seems less cluttered, however. There are less shaders to keep up with while one "master shader" handles it all. I don't have to duplicate any code or compile multiple shaders. Arguably, I could always have the shader program for each material be embedded in the material itself, and be auto-generated upon loading the material from the .mtl file. But this still leads to constantly calling glUseProgram, much more than is probably necessary in order to properly render the .obj. There seem to be a number of differing opinions on if it's okay to use hundreds of shaders or if it's best to just use tens of shaders.
      So, ultimately, what is the "right" way to do this? Does using a "master shader" (or a few variants of one) bog down the system compared to using hundreds of shader programs each dedicated to their own corresponding materials? Keeping in mind that the "master shaders" would have to track these additional uniforms and potentially have numerous branches of ifs, it may be possible that the ifs will lead to additional and unnecessary processing. But would that more expensive than constantly calling glUseProgram to switch shaders, or storing the shaders to begin with?
      With all these angles to consider, it's difficult to come to a conclusion. Both possible methods work, and both seem rather convenient for their own reasons, but which is the most performant? Please help this beginner/dummy understand. Thank you!
    • By JJCDeveloper
      I want to make professional java 3d game with server program and database,packet handling for multiplayer and client-server communicating,maps rendering,models,and stuffs Which aspect of java can I learn and where can I learn java Lwjgl OpenGL rendering Like minecraft and world of tanks
    • By AyeRonTarpas
      A friend of mine and I are making a 2D game engine as a learning experience and to hopefully build upon the experience in the long run.

      -What I'm using:
          C++;. Since im learning this language while in college and its one of the popular language to make games with why not.     Visual Studios; Im using a windows so yea.     SDL or GLFW; was thinking about SDL since i do some research on it where it is catching my interest but i hear SDL is a huge package compared to GLFW, so i may do GLFW to start with as learning since i may get overwhelmed with SDL.  
      -Questions
      Knowing what we want in the engine what should our main focus be in terms of learning. File managements, with headers, functions ect. How can i properly manage files with out confusing myself and my friend when sharing code. Alternative to Visual studios: My friend has a mac and cant properly use Vis studios, is there another alternative to it?  
    • By ferreiradaselva
      Both functions are available since 3.0, and I'm currently using `glMapBuffer()`, which works fine.
      But, I was wondering if anyone has experienced advantage in using `glMapBufferRange()`, which allows to specify the range of the mapped buffer. Could this be only a safety measure or does it improve performance?
      Note: I'm not asking about glBufferSubData()/glBufferData. Those two are irrelevant in this case.
    • By xhcao
      Before using void glBindImageTexture(    GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format), does need to make sure that texture is completeness. 
  • Popular Now