poliet 0 Light Poster

First: I believe you still did not get what is meant by glOrtho. It sets the dimensions of your 3d Cordinate System. You would like to have it good long, wide and deep, so that you are comfortable drawing a moving shape in it. The sytanx ist:

void glOrtho(	GLdouble  	left, 
 	GLdouble  	right, 
 	GLdouble  	bottom, 
 	GLdouble  	top, 
 	GLdouble  	nearVal, 
 	GLdouble  	farVal);

Thus if you want to draw a cube that is about 30 wide and 30 long and 30 deep and also move it around within the cordinate system up to 640 in x and 400 in top

glOrtho(0, 640, 0, 400, -50.0f, 50.0f);

Now, the big difference to your posted code are the last two values. They specify the near Value and far Value of your cordinate system.

Nearvar, Farvar specify the distances to the nearer and farther depth clipping planes. These values are negative if the plane is to be behind the viewer.

Thus, if you do not plan to anim your shape in z direction, its range should be at least as big as the shape's dimension, otherwise it will be clipped. And that is what exactly happened in your code. Since zou use negative z values, you also need to specify negative nearVal.

Point 2: Your shapes are still a little screwed. Play around once you have set your new glOrtho. It will work then.

Point 3: You need Color for your every shape, as they would appear meshed, once you …

poliet 0 Light Poster

Thanks! The easiest things are always the fartherst away in my mind.. :P

poliet 0 Light Poster

Hello,

I have a class with as many objects I need. I am changing the value of some member variables individually here and there, however, now I want to be able to change one specific member variable of all objects e.g. bool visibility at once, so that all objects wll have visibility=OFF.

I thought of creating a vector of pointers to all objects, or an array of references and then making a static member function which does that by looping through all existing objects. But then again if I decide to have other member variables to change as well, I would need to have all sorts of funcs which do the trick for various member variables.

I have read ages ago there is an easy way out somehow.. Any help would be appreciated,

&Cheers,

poliet

poliet 0 Light Poster

I am not sure how detailed you want to do things and how organized your game is. But here is what I think.

Well, you need first something like an Collision Manager. A class that keeps track of all positions of textures within your visible range. All positions are stored here as references to the original positions. You can do it with arrays or if you want to use carefully pointers instead, you can use vectors.

The positions are looped through and checked if your characters position is near and if a collision occured. That is called a bounding box collision and basically you check if the dimensions of your bitmap overlapps with the dimensions of other objects.

Once a collision is detected, it creates an event your Event Management class. Something like

if (Collision(*textureSizeVector[i], *collisionVector[i], Character->Position(), Character->Size()) EventManager->CreateEvent(COLLISION_OCCURED);

now once you have the proper event flagged. Your event Manager starts all follow up events that are necessary when a collision occured. There are:

1. Take away controll of your character from player to computer
2. You need to deviate the cordinates of your character
3. You need to start a gravitydeviation in vetical direction
4. You need to flag when the event is finished

First you need to hand over controll of your character to the computer. That means your EventManager flags your MovementClass, that movement is OFF.

Secondly then witin your GLUT displayfunc, you need something like:

if (EventManager->CheckEvents()==NOEVENT) …
poliet 0 Light Poster

Not quite sure what you are asking, but br must be initialized and since you declared it to be a constant reference, you will not be able to change it directly without getting a compiler error. Also within a member func declared to be constant, you cannot change br, at least not with my compiler...

Maybe post the whole code again and ask anew with the exact error message.

poliet 0 Light Poster

I don't know what other calls you have there...

but first make sure everything is off:

glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glDisable(GL_ALPHA);

Then...

Also it looks from there that Ortho Call is too vast scaled. Ortho sets a cordinte system. Your cordinate system goes from 0 to w (or h), thus scale is 1024 on both sides. If you draw then a Triangle with 0.2, guess where it is? Probably in the vast space of the opengl universe...

Either change glOrtho

double itsUnit=1.0f;
double itsRatio=1024.0f/768.0f;

glOrtho(0.0, itsUnit*itsRatio, 0.0, itsUnit, 0, 10);

or Change the size of your trinagle..

glVertex2d(-400, -400);

Could be other things as well, but for that I would need to see the whole code.

&Cheers,

poliet

poliet 0 Light Poster

When you write:

const Bird& br = eagle;

or

Bird const & br = eagle;

then basically you want br to be an alias for eagle and it is equipped with the same address as our eagle. But here also the keyword "const" is glued to the reference and not to the object. Thus the reference br is not allowed to be modified.

What is the use of a constant reference? Well, references do not dublicate when passed, thus they are quite efficient in terms of memory management. Passing by value on the other hand can be quite bulky. Still, we DO WANT to protect our source objects and that is why we declare references sometimes to be constant. Maybe the scope of protection might sound not clear from scratch, but when you have hundreds of interdependent classes, constant objects and thousands of lines, they help you to remember where to look for in the code as the compiler alarms you on every violation.

Now, when you write:

const Bird eagle(1);

You say that Bird is an constant object. As such you are not allowed to change it and it cannot call any member functions unless they are specified as constant, e.g. Do()const{};

Also when you write:

const Bird eagle(1);
Bird  & br  = eagle;

You have a constant object Then you want to refer to it with an not constant alias. That's clearly a violation!

You will also get a logical …

poliet 0 Light Poster

Not sure, as I am a novice myself. But I think "const" is a promise not to change the class members. What are your class members?

Bird b is a permanent class member.

-> Thus b you cannot change when you call set(int) in birdhouse as it is its class member.

What about rb? rb is a reference. A reference is an alias for something. In must refer to another object. It holds the same address as the object it refers to.

The object it is going to refer to is the first passed object when you create BirdHouse. Lets say:

Bird eagle(1);
Bird dove(2);

BirdHouse BH(eagle, dove) ;

Thus you have now a real object named "eagle" and a reference, so to speak another name for it, called "Birdhouse.rb".

Therefore whenever you want to use your eagle, you can write

Eagle.set(6); Eagle.fly(10)

or as an alias, once you create BirdHouse BH:

BH.rb.set(6); BH.rb.fly(10)

As I said Birdhouse.rb has the same address as Bird eagle. But eagle is the origin of the reference. The bird object BrdHouse.rb is therefore not a class member of Birdhouse, only its reference is. Changing Eagle doesn't hurt the class members of Birdhouse.

Hope that helps,

&Cheers,

poliet

poliet 0 Light Poster

Or, if you do not want to have a reserve function. The problem is in your algorithm in your function indexMax. Change the order as written beneath, and you will have an array that will result in an descending order. However, more natural feels rather a sorting algoritm in ascending order in combination with a reverse array function. Hope that helps.

int indexMax (int num[], int low, int high)
{
	int i, maxInd;
	maxInd=low;
	for (i=high;i>=low;i--)
	{
		if (num[i]>num[maxInd])
		{
			maxInd=i;
		}
	}
	return (maxInd);
}
poliet 0 Light Poster

Make a reverse function, which is using your swap function. Then call it in main before displayArray()

void reverse(int num[])

void reverse(int num[])
    {
    for (int i=0; i<int((size)/2);i++)
        swap (num, i, size-1-i);
    }

int main()
{
    int num[size];

    getArray(num);
    sortArray(num);
    reverse(num);
    displayArray(num);
}
poliet 0 Light Poster

I've rewritten slightlly the code referring to getArray via iostream as I do not have the necessary includes, however I haven't change your sorting algoritm. The array is displaying the values in ascending order.

#include <iostream>


#define size 7

void sortArray (int num[]);
int indexMax(int num[], int low, int high);
void swap (int num[], int loc1, int loc2);
void getArray (int num[]);
void displayArray (int num[]);

int main()
{
	int num[size];

	getArray(num);
	sortArray(num);
	displayArray(num);
}

void getArray (int num[])
{
	int i;
	for (i=0; i<size; i++)
	{
		printf("Enter integer: \n");
		int anInt;
		std::cin >> anInt;
		num[i]=anInt;
	}
}

void displayArray (int num[])
{
	int i;
	printf("\nThe sorted list is: \n");
	for (i=0; i<size; i++)
	{
		printf("%d\n", num[i]);
	}
}

void sortArray (int num[])
{
	int i, maxInd;
	for (i=0; i<size; i++)
	{
		maxInd=indexMax (num, i, size-1);
		swap (num, i, maxInd);
	}
}

int indexMax (int num[], int low, int high)
{
	int i, maxInd;
	maxInd=low;
	for (i=low;i<=high;i++)
	{
		if (num[i]<num[maxInd])
		{
			maxInd=i;
		}
	}
	return (maxInd);
}

void swap (int num[], int loc1, int loc2)
{
	int temp;
	temp=num[loc1];
	num[loc1]=num[loc2];
	num[loc2]=temp;
}

The result is this:

Enter integer:
9
Enter integer:
5
Enter integer:
2
Enter integer:
1
Enter integer:
6
Enter integer:
7
Enter integer:
3

The sorted list is:
1
2
3
5
6
7
9

Process returned 0 (0x0) execution time : 7.324 s

poliet 0 Light Poster

Also just an additional idea if you are up to it. Since it is rather difficult to find your way in this code.. if you know a little bit about functions, you should use them and wrap your code within them. Thus you will be better able to understand your own code and be able to easily modify it. A good function could be looking like this:

double LoanBalanceLeft(double interest, int monthsleft, double principal)
{
//Here you write your formuals and calculate balance and return it at the end of the function
return balance 
}

And after having collected all user variables you could call that function e.g. int loan = LoanBalanceLeft(10, 3, 200000) and the function will return the correct balance amount left as loan will hold the value.

You may also make another function that returns the interest to pay. Something like

double MonthlyInterestToPay(double interest, double LoanBalance, int monthsleft)



Then your main could look like this at the end.

[code=C++]

int main(void)
{
GetUserData();

for (int month=1; month<=totalmonths;c++)
   {
   std::cout << "Balance: " << LoanBalanceLeft(double interest, principal, totalmonths, month) << " left at month "<< monthstotal-monthsleft << std::endl;

   std::cout << "Interest to pay: " << MonthlyInterestToPay(interest, LoanBalance, totalmonths, month) << std::endl;
   }

UserQuit();
return 0;
}

Cheers,
poliet

poliet 0 Light Poster

Not maybe much of a C++ question, but rather a business issue. You have used a wrong formula in two places.

On line 73 and 82 change your balane calculations into

double balance = principle-principalPaid; //Line73

balance -= principalPaid; //Line 82

and you should be right. Also you have the months wrong. Since you already deducted the principalPaid in line 72 once, you need to start from month 1+1 on.

Thus change on line 78:

for (double i=1; i<years*12;i++)

Also, for the sake of correctness..

if (balance<1.00)
                balance=0.0;
            //CHANGED
            else
                balance -= principalPaid ;

The order is wrong as you need to calculate first the balance and THEN check if it's close to 0. Thus write:

balance -= principalPaid;
            if (balance<1.00)
                balance=0.0;

and you should get round to 0 on month 12.

poliet 0 Light Poster

You do have the "const" keyword in your function definition and declaration. This keywords prevents you from modifying Sizex, Sizey and Sizez. It would also prevent you from altering other member variables.

void Circle::Draw()const{

Keyword "const" protects all your members and the members of your parent class. Delete this keyword in the definition and as well declaration and it should compile. But use "const" to make your code safer, for instance everytime you plan your class member functions not to modify your class members. Thus everything that is within const {..} and modifies your class members causes a compile error. However, "const" helps you to spot easy mistakes before you start to lose controll of your class members as the compiler warns you that you want to change something, that you originally planned not to.

poliet 0 Light Poster

You have probably set draw to take a constant object but you are passing a reference and thus modifying the object it. The keyword constant protects you from unwanted modifications. Either pass by value or check your constant keywords.

This one compiles fine.

#include <iostream>


class Shape;
class Circle;

class Shape
{
    public:
        Shape():Sizex(0),Sizey(0),Sizez(0){};
        float GetX(void) const {return Sizex;}

    protected:
      float Sizex, Sizey, Sizez;
      void SetSize(float sx,float sy,float sz);
};

void Shape::SetSize(float sx,float sy,float sz)
    {
    this->Sizex = sx;  this->Sizey = sy; this->Sizez = sz;
    }


class Circle:public Shape
    {
    public:
    Circle(){};
    void Draw(int, int, int);
    void Draw(Circle& aCircle);
    };


void Circle::Draw(int x, int y, int z)
    {
    Shape::SetSize(Sizex=y,Sizey=y,Sizez=z);
    }

void Circle::Draw(Circle& aCircle)
    {
    Shape::SetSize(1,2,3);
    }


int main ()
    {
    Circle cir;
    cir.Draw(1,2,3);
    cir.Draw(cir);
    std::cout << "SizeX: " << cir.GetX() << std::endl;
    }
poliet 0 Light Poster

Well.. dipping deeper into this topic, I figured, that functions templates cannot have default values.. Thus the only "good" work around I came up it so far, is to overload the function... This compiles fine.

#include <iostream>

class A
{
public:
    A():x(0),y(0.0f){}
    void Do(void);

    template <class T1, class T2>
    void Add (int a,
              int b,
              T1 *var1,
              T2 *var2);

    template <class T1>
    void Add (int a,
              int b,
              T1 *var1);

    int x;
    double y;
};

template <class T1, class T2>
void A::Add (int a,
             int b,
             T1 *var1,
             T2 *var2)
{
}

template <class T1>
void A::Add (int a,
             int b,
             T1 *var1)
{
}

void A::Do(void)
    {
    Add(1,2, &x, &y); //works!
    Add(1,2,&x); //works!
    }

int main ()
    {
    A a;
    a.Do();
    }
poliet 0 Light Poster

Thanks so far, that are some really good posts, but yet I cannot make things work easier for me..

I want to pass a certain number of arguments... My actual code is working with a bitmap OpenGL font and I can do something like this:

Add(gEventManager::ENQ_SCREENDIMENSIONS, "Screen Dimensions X: $$  Y: $$", &Camera->rScreenX(), &Camera->rScreenY() );

Add(gEventManager::ENQ_Help, "Help Message: $$  ", &HELP->rLastHelpAsked());

while $$ in the String are being replaced in with the appropriate passed Variables in the right order

then later in the code I call my message class

gMessage->DisplayOnScreen(gEventManager::ENQ_SCREENDIMENSIONS)

gMessage->DisplayOnScrollboard(gEventManager::ENQ_HELP)

This all works fine, except I needed a good Add(..) and not bother of the type of passed variables too much. Sometimes there could be up to 5 passed variables and with different types int, double or string.

poliet 0 Light Poster

Hello,

I was hinted for my cause in using a mastertemplate. I did and I swear my little programm was up and running late night just the way I wanted it. This morning, however, I did some other corner stuff and now it does not compile anymore.. just like that... Have a look please...

#include <iostream>

class A
{
public:
    A():x(0),y(0.0f){}
    void Do(void);

    template <class T1, class T2>
    void Add (int a,
              int b,
              T1 *var1,
              T2 *var2);

    int x;
    double y;
};

template <class T1, class T2>
void A::Add (int a,
             int b,
             T1 *passedVar1=T1(),
             T2 *passedVar2=T2())
{
}

void A::Do(void)
    {
    Add(1,2, &x, &y); //works!
    Add(1,2, &x); //error!
    }

int main ()
    {
    A a;
    a.Do();
    }

Compiler Error@Code::Blocs 8.02

D:\C++ Projects\marc\console\main.cpp||In member function `void A ::Do()': |
D:\C++ Projects\marc\console\main.cpp|30|error: no matching function for call to `A::Add(int, int, int* )'|
||=== Build finished: 1 errors, 0 warnings ===|

I appreciate any help on that!

poliet

poliet 0 Light Poster

Additional note for people checking up on this topic...

Using the neat code Tom Gunn provided about multiple templates, I figured I still need to make a reinterpret_cast call despite of using

if (typeid(T1) ==typeid(int))

If I do not use reinterpret_cast I get an error message:

D:\C++ Projects\Project1\project.cpp|1950|error: cannot convert `double*' to `int*' in assignment|

The reason for that is probably that the compiler ignores the typecheck if statement as it does not really know what will be passed after all, however on runtime everything works as it should. Thus forcing the compiler with reinterpret_cast to take an int really for an int and take a double for an double works best...

template <class T1, class T2>
void gFont::AddTest3 (int passedPosition,
                     std::string passedString,
                     T1 *var1=T1(), T2 *var2=T2())
    {
        gMessage* aMessage =  new gMessage(1, passedString);

        if (typeid(T1) == typeid(int))
            {
            aMessage->nItsVars=0;


        //reinterpret_cast<int*> is needed, otherwise I get 
       the described compiler error
  
        aMessage->pInt=reinterpret_cast<int*>(var1); 


            vMessages[passedPosition]=aMessage;
            nMessages++;

            std::cout << "that was an int";
            std::cout << *aMessage->pInt;
            }

        if (typeid(T1) == typeid(double))
            {
            aMessage->nItsVars=0;
            //reinterpret_cast<double> for this if statement is needed
            aMessage->pDouble=reinterpret_cast<double*>(var1); 
            vMessages[passedPosition]=aMessage;
            nMessages++;

            std::cout << "that was an double";
            std::cout << *aMessage->pDouble;
            }

    }

It should be hopefully safe.. ;)

poliet 0 Light Poster

Again a genious strike of yours! I am shattered. Not bad.. I need too much to learn.. *humble*

I'd say thats done now and lets move on with our lives... Topic closed

poliet 0 Light Poster

I'd say, you did already give a great answer.. I implemented the master Templates now you given me and it works just fine, however, I do not understand the bit of additional of code you provided, as you write

void AddTest3 (int passedPosition,
                     std::string passedString,
                     T1 &var1=T1(), T2 &var2=T2())

Why ... T1 &var=T1(), T2 &var=T2()?

and not simply

.. T1 &var, T2 &var

does the appendix =T1() has an additional meaning?

And... about simmering

iostream library fixes the type safety problem

I guess so.. I wish I had a better understanding of stdio than just std::string.. I'd love to do something beautiful like...

gFont->Message ("This is this" << varDouble << "and dats dat" << varInt);

but since the message system is just a smaller sub system in my application, its queentask is to perform its job safely and quietly and do nice graphics! Also the fontload underlying the messagesystem works with a printf similar system and I do not want to mengle with it.

I am really really happy with the template example you provided me. I was exactly looking for that, but was not aware how to do multiple templates b4.

poliet 0 Light Poster

Mastertemplates... now that is something I can work on! Many thanks to you!

The only thing I can think of without overhauling the entire system

What do you have in mind? My programm is still, I believe, flexbible enough to handle an overhaul. However, the system now is with my limited C++ knowlege the best I could come up so far. If you hint me in the right direction I can look into it.. I am always glad to learn something new..

poliet 0 Light Poster

You are right I don't need to know it so much, however, only to have more controll over errors and have a quicker way of coding thousand messages ahead. I am doing an opengl application and I need to know the passed type just out of confortability after all since I will have more than 100++ different message to go.

I have a message class which works with font bitmaps and does something like that to get the basic idea:

First I initialize my messagesystem with many different messages:

Font->Init("Arial.tga")

bool InitMessages(void)
{
Message(DISPLAY_MOUSE_COORD, "Those are my coordinates: X %f and Y %f", gMouse->GetX(), gMouse->GetY);
Message(DISPLAY_USERINFO, "User Name %s, Age %d", User.GetName(), User.GetAge());
Message(DISPLAY_SCROLLINFO, "ScrollSpeed: %f", Camera.GetScrollSpeed());
...
..
.
}

The ".." are any string and the %f, %s etc. are being replaced by the value, similar to <iostream>, only that this works now completely in OpenGL.

Then within the code I can I call the right message with

if (Button(G) && Event(WHATEVER)) DisplayMessage->OnScreen(DISPLAY_USERINFO, Line 12, Colum 14);

which will print on an OpenGL Screen at the given coordinates:

Jack Bauer, Age 43

or

if (MousePress(LEFT)) DisplayMessage->OnScrolldisplay(DISPLAY_USERINFO)

and it displays this messages on the Screen, in the way or whereever I want it to...

The reason why I want to know the passed pointer type is simple, that when I init a Message like

Message(DISPLAY_MOUSE_COORD, "Those are my coordinates: X %f and Y %f", gMouse->GetX(), gMouse->GetY);

I do not …

poliet 0 Light Poster

Sky Diploma: Your proposal is not working as I get this->

D:\C++ Projects\marc\console\main.cpp|24|error: ISO C++ forbids cast to non-reference type used as lvalue|

Tom Gunn: Good idea, however, is there a way to change a member void pointer to an int pointer? If this were possible, I wouldnt need to store all kind of pointers as members and assign the passedVar to the correct one. That would be less ugly.

Also, is there a way to know the type of passed pointer? Let's say I pass an int* to Do(void* p). How can I figure out that int* was passed? I thought of checking with size, or having a seperate class stores all addresses and compares it, but is there an easy way to know what type was passed?

poliet 0 Light Poster

I want my member class void* pointer to be change to a int* pointer. This does not however work.

D:\C++ Projects\marc\console\main.cpp||In member function `void B::Do(void*)':|
D:\C++ Projects\marc\console\main.cpp|26|error: `void*' is not a pointer-to-object type|
||=== Build finished: 1 errors, 0 warnings ===|

#include <iostream>

class A;
class B;

class A
    {
    public:
        A():      pVar(0){};
        
        void*     pVar;
    };

class B
    {
    public:
        B(){};
        void      Do(void *passedVar);
    };

void B::Do(void *passedVar)
    {
    A* a = new A;
    a->pVar=static_cast<int*>(passedVar);

    std::cout << *a->pVar; 

// Basically I want to have pVar to be a pointer to 
// an int but obviously it is and remains a void* pointer... ;(
    
    }

int main()
    {
    B* b = new B;
    int*cVar=0;

    b->Do(cVar);
    }
poliet 0 Light Poster

I figured it, however it is very ugly code.. I decleared in the other class gMessage another pointer to an int and then assign it

void gFont::AddTest(int passedPosition, std::string passedString, void *passedVar, void *passedVar2)
    {
    gMessage* aMessage =  new gMessage(1, passedString);
    int* passedInt=static_cast<int*> (passedVar);
    aMessage->pVar=passedInt;
    int* pInt_loc = static_cast<int*> (aMessage->pVar);
    aMessage->pInt=pInt_loc;
}

It works but I get a funny feeling with it.. ;/

All I want to do is to pass an unknown type of pointer and interpret it the right way and store it in another class member variable..

poliet 0 Light Poster

Hello!

I want to use static_cast<int> on a void* member Variable in another class. (class aMessage). aMessage class has a public variable void* pVar. While using static_cast on a local variable is running smoothly, I get a compiler error trying to cast it on the aMessage->pVar.

pVar is being declared in gMessage.
pVar is also being initialized in constructor with
gMessage::gMessage(unsigned short int passedType, std::string passedString):pVar(0){...}

This is the flawed code:

void gFont::AddTest(int passedPosition, std::string passedString, void *passedVar, void *passedVar2)
    {
    gMessage* aMessage =  new gMessage(1, passedString); // Constructor for gMessage, initializing

    int* passedInt=static_cast<int*> (passedVar); // This one works without problem!

    aMessage->pVar=passedInt;

    int* aMessage->pVar=static_cast<int*> (aMessage->pVar); // This one does not work at all (see log beneath)
    }

D:\C++ Projects\Project1\project.cpp||In member function `void gFont::AddTest(int, std::string, void*, void*)':|
D:\C++ Projects\Project1\project.cpp|1918|error: expected initializer before '->' token|

Any help is very appreciated. Thank you!