Problem with method in a class when called from another class
I'm writing a simple scene graph to hold some objects so I can control the rendering and drawing of these objects in OpenGL. I have two classes, one called GameObject which defines the objects with certain parameters such as position and velocity as well as how to draw the object. It has a method called update() which is used to calculate any change in position and then calls the draw() to draw itself onto the screen.
Another class is called sceneNode. This class controls the data structure which I use to store the objects. This an instance of this class contains a pointer to a GameObject instance to allow me to access the data and a sceneNode has children of type sceneNode stored in a vector.
Each class works perfectly well on their own. I can add children to the scene graph etc and I can create a GameObject and tell it to draw itself and everything works as expected.
I then added a new method to sceneNode which is called render(), this method gets the pointer to gameObject and calls it's update function before calling render() on any children of the node.
The problem is: the update() method is called and the GameObject is drawn but it is always drawn in the same place and doesn't move despite having a velocity and change in position. Calling the update() function by using an instance of GameObject DOES draw the object and move the object around the screen. I've been staring at this code for hours and can't see what I'm missing. I'm still fairly new to the idea of pointers and calling methods from another class so I may have missed something o开发者_如何学Gobvious.
Here are the relevant methods:
GameObject.cpp: The variables position, velocity etc are listed as protected.
void GameObject::update(){
for (int i = 0; i<3;i++){
this->velocity[i] +=this->acceleration[i];
}
this->position[0] += this->velocity[0];
this->position[1] += this->velocity[1];
this->position[2] += this->velocity[2];
this->draw();
}
void GameObject::draw() {
glTranslatef(this->position[0], this->position[1], this->position[2]);
glBegin(GL_TRIANGLES);
for (int i = 0; i < this->num_tris; i++) {
for (int j = 0; j <3 ; j++) {
glVertex3fv(vertices[triangles[i].INDEXES[j]]);
}
}
glEnd();
}
sceneNode.cpp:
void sceneNode::render(){
GameObject *go = new GameObject();
go = this->data;
//data is the name of the variable storing a pointer to a GameObject
go->update();
//update() is a method that redraws the object and calc's new position etc
if (hasChildren()) { //if this node has children, render all of them aswell...
for (int i = 0; i< this->node_tree.size(); i++) {
this->node_tree.at(i).render();
}
}
sceneNode.h: This is how the GameObject pointer is set up in the sceneNode
Protected:
GameObject* data;
I'm lost as to why the position is not changing for the render() method but is for the update() method as they are both calling the same thing?
Thanks for any help
There are some big problems here.
GameObject *go = new GameObject();
go = this->data;
You're creating a new object and then you are forgetting the pointer to that object. This happens every time you call render, so you have tons of memory that you aren't using that grows with time. You can just say:
GameObject *go = NULL;
to create a pointer without allocating data to it.
You can also omit the this->foo everywhere. It's implied within all classes.
So although I can't see the error in this code, chances are it is elsewhere, since you're making mistakes with pointers like above. You probably have pointers pointing to things you're not drawing. If you look at the memory addresses of the things that are updating and the memory addresses of the things being updated in render(), they may actually be different. If they are then you know that you're not calling update on the same things you are drawing. To get a memory address look at the value of 'this' within a function call. Write them down and make sure they are the same as the objects you are drawing. The error is not in this code.
In SceneNode, when you assign this-> data to go, you are effectively setting go to null! take out that assignment or do this->data = new GameObject() instead of using go.
精彩评论