hi everybody!
I really need your help here. I am developing a 3D game. so far I have came no further than finishing the 3D engine and print out some basic 3D-models.
everything works okay, with exception of a bug, occuring after a couple of minutes of running time. it starts with that everything freezes, and then either I have to use process manager to shut it down, or it goes back to working but this time much slower, and after a couple of second giving the error
Microsoft Visual C++ Runtime Library
Runtime Error
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information
I have done several tests with different objects. my models are drawn with only triangles. when I draw a cube in the 3D-world it doesn't occur from what I've seen. when I drawn a floor with 512 triangles the bug came after not even a half minute. when I draw a 3D-creature into the world, it take a few minutes before the bug come.
I'll show you the codes below. in this code the 3D-creature is drawn in the 3D-world.
defines.h
#ifndef DEFINES_H
#define DEFINES_H
#define PI 3.14159265359
#define VK_a 0x41
#define VK_d 0x44
#define VK_s 0x57
#define VK_w 0x53
#define FADE 1.02
#define ANGLE_V 0.01
#define MOVE_V 0.01
#define SORTBASE 2
int w=800;
double SCREEN_M = 1.7;
int h=(int)(w/SCREEN_M);
int angleRangeX = 90;
int angleRangeY = (int)(angleRangeX/SCREEN_M);
int maxARX = 180;
int maxARY = 180;
double sX = 2.0f/angleRangeX;
double sY = 2.0f/angleRangeY;
#endif
engine.h
#ifndef ENGINE_H
#define ENGINE_H
#include <gl/gl.h>
#include <cmath>
#include <vector>
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include "defines.h"
using namespace std;
class Point3D{
public:
double x,y,z;
double color[3];
Point3D(double x, double y, double z){
this->x = x;
this->y = y;
this->z = z;
color[0] = 1.0;
color[1] = 1.0;
color[2] = 1.0;
}
};
double getAngleX(Point3D* point1, Point3D* point2){
double deltax = point2->x - point1->x;
double deltaz = point2->z - point1->z;
double angle = atan2(deltaz, deltax)*180/PI;
return angle-90;
}
double getAngleY(Point3D* point1, Point3D* point2){
double deltay = point2->y - point1->y;
double deltaz = point2->z - point1->z;
double angle = atan2(deltay, deltaz)*180/PI;
return angle;
}
double dis(Point3D* point1, Point3D* point2){
return sqrt(
pow(point2->x-point1->x, 2)+
pow(point2->y-point1->y, 2)+
pow(point2->z-point1->z, 2)
);
}
void Rotate(Point3D* rotatingPoint, Point3D* centerPoint, double aX, double aY){
double deltax = rotatingPoint->x - centerPoint->x;
double deltay = rotatingPoint->y - centerPoint->y;
double deltaz = rotatingPoint->z - centerPoint->z;
double angleX = getAngleX(centerPoint, rotatingPoint)+aX+90;
double disXZ = sqrt(pow(deltax,2)+pow(deltaz,2));
double radX = angleX*PI/180;
rotatingPoint->z = centerPoint->z + disXZ*sin(radX);
rotatingPoint->x = centerPoint->x + disXZ*cos(radX);
double angleY = getAngleY(centerPoint, rotatingPoint)+aY;
deltay = rotatingPoint->y - centerPoint->y;
deltaz = rotatingPoint->z - centerPoint->z;
double disZY = sqrt(pow(deltaz,2)+pow(deltay,2));
double radY = angleY*PI/180;
rotatingPoint->y = centerPoint->y + disZY*sin(radY);
rotatingPoint->z = centerPoint->z + disZY*cos(radY);
}
class Triangle{
public:
Point3D* point[3];
float color[3];
Triangle(Point3D* point[3], float color[3]){
this->point[0] = point[0];
this->point[1] = point[1];
this->point[2] = point[2];
this->color[0] = color[0];
this->color[1] = color[1];
this->color[2] = color[2];
for(int i=0; i<3;i++){
this->point[i]->color[0] = color[0];
this->point[i]->color[1] = color[1];
this->point[i]->color[2] = color[2];
}
}
Triangle(){}
Point3D* Center(){
Point3D* p = new Point3D(
(point[0]->x+point[1]->x+point[2]->x)/3,
(point[0]->y+point[1]->y+point[2]->y)/3,
(point[0]->z+point[1]->z+point[2]->z)/3
);
}
};
Triangle* clone(Triangle* triangle){
Point3D* point[3];
for (int i=0; i<3;i++){
point[i] = new Point3D(triangle->point[i]->x,triangle->point[i]->y,triangle->point[i]->z);
}
return new Triangle(point, triangle->color);
}
bool trianglesSorted(vector<Triangle*>* triangles){
for (int i=1; i<triangles->size(); i++){
if (triangles->at(i-1)->Center()->z < triangles->at(i)->Center()->z){
return false;
}
}
return true;
}
void sortTriangles(Triangle* triangles[], int size){
for (int i=0; i<size; i++){
for (int j=size-1; j>i; j--){
if (triangles[j]->Center()->z > triangles[i]->Center()->z){
Triangle* holder = clone(triangles[i]);
triangles[i] = triangles[j];
triangles[j] = holder;
}
}
}
}
void ViewTriangle3D(Point3D* view, Triangle* triangle){
bool isInView = true;
double maxX=0,maxY=angleRangeX/2,minX=0,minY=angleRangeY/2;
float c[3][2];
double a = getAngleX(view, triangle->Center());
bool isNotBehind = true;
double cd = sqrt(pow(view->x-triangle->Center()->x, 2)+
pow(view->y-triangle->Center()->y, 2)+
pow(view->z-triangle->Center()->z, 2)
);
for (int i=0; i<3; i++){
double aX = getAngleX(view, triangle->point[i]);
double aY = getAngleY(view, triangle->point[i]);
if (aX < -maxARX/2 || aX > maxARX / 2 || aY < -maxARY/2 || aY > maxARY/2){
isNotBehind = false;
}
double d = sqrt(pow(view->x-triangle->point[i]->x, 2)+
pow(view->y-triangle->point[i]->y, 2)+
pow(view->z-triangle->point[i]->z, 2)
);
if (isNotBehind){
int b = i-1;
if (b < 0){b = 2;}
for (int col=0; col<3;col++){
double diff = pow(FADE, d);
triangle->point[i]->color[col] = triangle->color[col];
triangle->point[i]->color[col] /= diff;
}
}
double bx = sX, by=sY;
float x = aX*bx;
float y = aY*by;
c[i][0] = x;
c[i][1] = y;
}
if (isNotBehind){
for (int i=0; i<3;i++){
glColor3f(triangle->point[i]->color[0], triangle->point[i]->color[1], triangle->point[i]->color[2]);
glVertex2f(c[i][0],c[i][1]);
}
}
}
class Camera{
public:
Point3D* position;
double angleX, angleY;
Camera(Point3D* position, double angleX, double angleY){
this->position = position;
this->angleX = angleX;
this->angleY = angleY;
}
void Move(double distance, double aX){
position->x += distance*cos(-(angleX+90+aX)*PI/180);
position->z += distance*sin(-(angleX+90+aX)*PI/180);
}
};
class World{
public:
vector<Triangle*>* faces;
World(){
faces = new vector<Triangle*>();
}
void addFace(Point3D* p1, Point3D* p2, Point3D* p3, float r, float g, float b){
Triangle* triangle = new Triangle();
triangle->point[0] = p1;
triangle->point[1] = p2;
triangle->point[2] = p3;
triangle->color[0] = r;
triangle->color[1] = g;
triangle->color[2] = b;
faces->push_back(triangle);
}
void view(Camera* camera){
Point3D* inv = new Point3D(
-camera->position->x,
-camera->position->y,
-camera->position->z
);
Triangle* t[faces->size()];
for (int i=0; i<faces->size(); i++){
t[i] = clone(faces->at(i));
for (int p=0; p<3; p++){
Rotate(t[i]->point[p], camera->position, camera->angleX, camera->angleY);
}
}
sortTriangles(t, faces->size());
for (int i=0; i<faces->size(); i++){
ViewTriangle3D(camera->position, t[i]);
}
}
};
class Model{
public:
vector<Triangle*>* faces;
vector<Triangle*>* copy;
World* world;
Point3D* pos;
double angleX, angleY;
Model(Point3D* pos, World* world){
this->pos = pos;
this->faces = new vector<Triangle*>();
this->copy = new vector<Triangle*>();
this->world = world;
angleX = 0;
angleY = 0;
}
void addFace(Point3D* p1, Point3D* p2, Point3D* p3, float r, float g, float b){
Triangle* triangle = new Triangle();
triangle->point[0] = p1;
triangle->point[1] = p2;
triangle->point[2] = p3;
triangle->color[0] = r;
triangle->color[1] = g;
triangle->color[2] = b;
faces->push_back(triangle);
Triangle* cop = clone(triangle);
for (int i=0; i<3;i++){
cop->point[i]->x = triangle->point[i]->x + pos->x;
cop->point[i]->y = triangle->point[i]->y + pos->y;
cop->point[i]->z = triangle->point[i]->z + pos->z;
}
this->copy->push_back(cop);
this->world->faces->push_back(cop);
}
void update(){
for (int i=0; i<faces->size(); i++){
Triangle* v = copy->at(i);
Triangle* lv = faces->at(i);
for (int p=0; p<3; p++){
Point3D* npoint = new Point3D(lv->point[p]->x,lv->point[p]->y,lv->point[p]->z);
Rotate(npoint, new Point3D(0,0,0), angleX, angleY);
npoint->x += pos->x;
npoint->y += pos->y;
npoint->z += pos->z;
v->point[p] = npoint;
}
}
}
};
Model* clone(Model* model){
Model* n = new Model(new Point3D(model->pos->x,model->pos->y,model->pos->z), model->world);
for (int i=0; i<model->faces->size();i++){
Triangle* tri = model->faces->at(i);
n->addFace(tri->point[0], tri->point[1], tri->point[2], tri->color[0], tri->color[1], tri->color[2]);
}
return n;
}
Point3D* parsePoint(int color){
Point3D* point = new Point3D(0,0,0);
point->x = (int)(color/pow(256.0, 2.0));
color-=(int) (point->x*pow(256.0,2.0));
point->y = (int)(color/pow(256.0, 1.0));
color-=(int) (point->y*pow(256.0,1.0));
point->z = color;
return point;
}
#endif
gameworld.h
#ifndef GAMEWORLD_H
#define GAMEWORLD_H
#include "engine.h"
double b = 0.0;
class Controller{
public:
double speed, *angleX, *angleY, dx,dy, score;
Point3D* pos;
Controller(Camera* camera){
pos = camera->position;
speed = 0;
angleX = &camera->angleX;
angleY = &camera->angleY;
dx = 0;
dy = 0;
score = 0;
}
Controller(Model* model){
pos = model->pos;
speed = 0;
angleX = &model->angleX;
angleY = &model->angleY;
dx = 0;
dy = 0;
score = 0;
}
Controller(){
speed = 0;
dx = 0;
dy = 0;
score = 0;
}
void update(){
pos->x += speed*cos(-(*angleX-90)*PI/180);
pos->z += speed*sin(-(*angleX-90)*PI/180);
pos->y += -speed*sin((*angleY)*PI/180);
*angleX+=dx;
*angleY+=dy;
while (*angleX >= 360){
*angleX-=360;
}
while (*angleX < 0){
*angleX+=360;
}
while (*angleY >= 360){
*angleY-=360;
}
while (*angleY < 0){
*angleY+=360;
}
}
};
template <class parent> class Creature{
public:
parent* game;
Controller* ctrlr;
Model* model;
void (*draw)(Controller*, Model*);
void (*main)(Controller*, parent*);
Creature(void (*draw)(Controller*, Model*), void (*main)(Controller*, parent*), parent* g){
this->draw = draw;
this->game = g;
model = new Model(g->getSpawnPoint(), g->world);
ctrlr = new Controller(model);
(*draw)(ctrlr, model);
}
};
template <class parent> class Player{
public:
parent* game;
Controller* ctrlr;
bool active;
Player(parent* g){
game = g;
ctrlr = new Controller(g->camera);
active = true;
}
};
double random(){
double i = 0.34872894789;
b+=i;
if (b>1){i--;}
return b;
}
class Game{
public:
Player<Game>* player;
Camera* camera;
World* world;
vector<Creature<Game>*>* creatures;
Game(){
camera = new Camera(new Point3D(0,0,0),0,0);
player = new Player<Game>(this);
world = new World();
}
Point3D* getSpawnPoint(){
Point3D* newPoint = new Point3D(0,0,0);
double dis = 16*12 + 16*6*random();
}
void AddCreature(Creature<Game>* (*specie)(Game*)){
Point3D* pos = getSpawnPoint();
Creature<Game>* creature = (*specie)(this);
creatures->push_back(creature);
}
void update(){
world->view(camera);
}
};
//speedo Mob
void speedoM(Controller* selfctrlr, Model* model){
Point3D* f= new Point3D(0,0,8);
Point3D* ul=new Point3D(-8,8,0);
Point3D* ur=new Point3D(8,8,0);
Point3D* ml=new Point3D(-8,0,0);
Point3D* mr=new Point3D(8,0,0);
Point3D* bl=new Point3D(-8,-8,0);
Point3D* br=new Point3D(8,-8,0);
Point3D* b= new Point3D(0,0,-8);
model->addFace(f, ul, ur, 0.2,0.2,0.4);
model->addFace(f, ul, ml, 0,0,0);
model->addFace(f, bl, ml, 1,0,0);
model->addFace(f, ur, mr, 0,0,0);
model->addFace(f, br, mr, 1,0,0);
model->addFace(f, bl, br, 1,0,0);
model->addFace(b, ul, ur, 0.2, 0.2, 0.4);
model->addFace(b, ul, bl, 1, 1, 1);
model->addFace(b, ur, br, 1, 1, 1);
model->addFace(b, bl, br, 1, 1, 1);
Point3D* wingFL1 = new Point3D(-16,0,0);
Point3D* wingFL2 = new Point3D(-16,0,-8);
Point3D* wingFR1 = new Point3D(16,0,0);
Point3D* wingFR2 = new Point3D(16,0,-8);
model->addFace(wingFL1, wingFL2, ml, 0,0,1);
model->addFace(wingFR1, wingFR2, mr, 0,0,1);
Point3D* wingBL = new Point3D(-8, 0, -16);
Point3D* wingBR = new Point3D(8, 0, -16);
model->addFace(wingBL, wingBR, b, 0,0,1);
}
#endif
main.cpp
/**************************
* Includes
*
**************************/
#include <windows.h>
#include <gl/gl.h>
#include "defines.h"
#include "gameworld.h"
/**************************
* Function Declarations
*
**************************/
LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC);
void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC);
Camera* camera;
World* world;
Controller* player;
/**************************
* WinMain
*
**************************/
int WINAPI WinMain (HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int iCmdShow)
{
WNDCLASS wc;
HWND hWnd;
HDC hDC;
HGLRC hRC;
MSG msg;
BOOL bQuit = FALSE;
float theta = 0.0f;
/* register window class */
wc.style = CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "GLSample";
RegisterClass (&wc);
/* create main window */
hWnd = CreateWindow (
"GLSample", "OpenGL Sample",
WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
0, 0, w, h,
NULL, NULL, hInstance, NULL);
/* enable OpenGL for the window */
EnableOpenGL (hWnd, &hDC, &hRC);
camera = new Camera(new Point3D(0,32,0), 0,0);
world = new World();
double s=16;
Model* speedo = new Model(new Point3D(0,16+8,64), world);
Controller* controller = new Controller(speedo);
controller->dx = ANGLE_V*20;
player = new Controller(camera);
speedoM(controller, speedo);
/* program main loop */
while (!bQuit)
{
/* check for messages */
if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
/* handle or dispatch messages */
if (msg.message == WM_QUIT)
{
bQuit = TRUE;
}
else
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
else
{
/* OpenGL animation code goes here */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable( GL_BLEND );
glClearColor (1.0f, 1.0f, 1.0f, 0.0f);
glClear (GL_COLOR_BUFFER_BIT);
glPushMatrix ();
glBegin (GL_TRIANGLES);
controller->update();
speedo->update();
player->update();
world->view(camera);
glEnd ();
glPopMatrix ();
controller->dx = -controller->dx;
SwapBuffers (hDC);
theta += 1.0f;
Sleep (1);
}
}
/* shutdown OpenGL */
DisableOpenGL (hWnd, hDC, hRC);
/* destroy the window explicitly */
DestroyWindow (hWnd);
return msg.wParam;
}
/********************
* Window Procedure
*
********************/
LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
return 0;
case WM_CLOSE:
PostQuitMessage (0);
case WM_DESTROY:
return 0;
case WM_KEYDOWN:
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
return 0;
case VK_LEFT:
player->dx-=ANGLE_V;
return 0;
case VK_RIGHT:
player->dx+=ANGLE_V;
return 0;
case VK_UP:
player->dy-=ANGLE_V;
return 0;
case VK_DOWN:
player->dy+=ANGLE_V;
return 0;
case VK_a:
return 0;
case VK_d:
return 0;
case VK_s:
player->speed+=MOVE_V;
return 0;
case VK_w:
player->speed-=MOVE_V;
return 0;
return 0;
}
default:
return DefWindowProc (hWnd, message, wParam, lParam);
}
}
/*******************
* Enable OpenGL
*
*******************/
void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
/* get the device context (DC) */
*hDC = GetDC (hWnd);
/* set the pixel format for the DC */
ZeroMemory (&pfd, 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 (*hDC, &pfd);
SetPixelFormat (*hDC, iFormat, &pfd);
/* create and enable the render context (RC) */
*hRC = wglCreateContext( *hDC );
wglMakeCurrent( *hDC, *hRC );
}
/******************
* Disable OpenGL
*
******************/
void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC)
{
wglMakeCurrent (NULL, NULL);
wglDeleteContext (hRC);
ReleaseDC (hWnd, hDC);
}
I am developing this using dev C++ on Windows 7.
I really hope someone could help me. I have checked almost all existing threads on the internet by searching the error message on google but no thread did help me. I would be thankful for answers and I will not know how to thank the person who solves my problem.