Computer Science Final Project

Started by
23 comments, last by Erunama 21 years, 11 months ago
I am currently taking AP Computer Science A at my high school, and we are working on our final projects. We are allowed to work off of a base code, and I will be using NeHe''s (I hope my teacher will accept an OpenGL program, since we never even did graphics in class, just regular old DOS programming). The project must include classes and at least one AP class (I am using apvector, which is just a class for creating an array). I will be creating a room with a spinning cube inside. I also have implemented a primitive form of shading for the class Draw() function (it darkens the colors towards the back... primitive, I know, but I haven''t reached texture mapping or lighting in the tuts yet). I had a little problem with apvectors and my Cube class, but I have ironed that out. The room looks pretty good right now, and only one thing is keeping me from being "finished." The cube does not spin. Here are a few snippets of code that I thought were relevant. Can anyone figure out my problem? Creating the cube objects:
  
	// Create cube objects

	Cube room(6.0f,6.0f,15.0f);
	Cube cube(1.0f,1.0f,1.0f);

	// Modify cube parameters

	room.SetColor(0.5f,0.5f,0.5f);
	room.ShowDepth(TRUE);
	room.SetPosition(0.0f,-1.0f,-7.0f);
	cube.IsRotation(TRUE);
	cube.SetColor(0.2f,0.1f,1.0f);
	cube.SetPosition(0.0f,-1.0f,-5.0f);
	cube.SetRotation(2.0f,1.0f,1.0f,0.0f);

	apvector <Cube> cubes(2);
	cubes[0] = room;
	cubes[1] = cube;
  
The apvector with the two cubes (yes, the room is a rectangle, but I felt like calling the class Cube) gets passed the the DrawGLScene function:
  DrawGLScene(cubes);				// Draw The Scene  
Here is the DrawGLScene function:
  
int DrawGLScene(apvector <Cube> cubes)								// Here''s Where We Do All The Drawing

{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			// Clear The Screen And The Depth Buffer


	// Draw the objects

	for (int i = 0; i < cubes.length(); i++)
	{
		glLoadIdentity();
		cubes[i].Draw();
	}

	return TRUE;								// Everything Went OK

}
  
The member functions that modify rotation paramaters:
  
void Cube::IsRotation(BOOL rotation)
{
	myRotate = rotation;
}

void Cube::SetRotation(GLfloat change, GLfloat x, GLfloat y, GLfloat z)
{
	myChange = change;
	myRot[0] = x;
	myRot[1] = y;
	myRot[2] = z;
}
  
And finally, the Draw() function, which draws the cube based on all the private data members (I omitted the actual plotting of the vertices and my primitive shading code to save space):
  
void Cube::Draw()
{
	if(amIDefined)
	{
		glTranslatef(myPosition[0],myPosition[1],myPosition[2]);

		if(myRotate)
		{
			glRotatef(myAngle,myRot[0],myRot[1],myRot[2]);
			myAngle += myChange;
		}

		//Start drawing the cube

		glBegin(GL_QUADS);
	             (Insert vertice drawing code here)
		glEnd();

	}
}
  
Ok, there is all the code I think is relevant for someone to find my problem. If you want anymore code, feel free to ask. I get no errors when I compile, and everything draws to the screen fine, it''s just that the cube sits there and does not spin. Thanks for any help you can provide, Dan Carroll
Advertisement
it looks like you are missing one or a couple of:

glPushMatrix()
glLoadIdentity()
glPopMatrix()

look deeper into the NeHe tuts to find out where exactly to call them

-me
Yep. Are you using gluLookAt or something similar? If so, you don't want to use glLoadIdentity, as it will destroy your modelview matrix. Use
glLoadIdentity();gluLookAt(...);for (all cubes) {    glPushMatrix();    glTranslate(...);    ...    // DrawCube    ...    glPopMatrix();}  

If you're not using gluLookAt, what do you use?

[edited by - IndirectX on May 1, 2002 8:49:39 PM]
---visit #directxdev on afternet <- not just for directx, despite the name
my bad on the glLoadIdentity()

you are definitely missing the push and pop matrix calls which render your translate and rotate openGL calls useless.

-me

Thanks for the quick replies.

IndirectX: I am not using gluLookAt (don''t even know what it is). I am just building the objects using glTranslatef and glVertex3f (very simple stuff here, along the lines of tutorial 5).

Palidine: I don''t think it has anything to do with those Matrix functions, since I have never encountered them before (again, we are looking at complexity along the lines of tutorial 5).


I am pretty sure it is a very simple code/class error that I am not catching. I programmed this without classes and it worked fine. So I am losing something in the modification to my Cube class.
quote:Original post by Palidine
my bad on the glLoadIdentity()

LOL! I forgot to put it in my pseudocode; that''s fixed.

Erunama: seeing that you do pretty much the same thing as Tutorial 5 does, are you initializing myAngle to 0? Step through your code and make sure that all your variables have reasonable values.

[rant]
I really dislike AP coding conventions, as well as their questions. The worst coding style I''ve ever seen (speaking of questions on the AP test). Intentionally giving you code snippets that will make anyone say "Why the hell did they do that?"

I took APCS A last year in my school, we have 32MB PII boxes with BC++4 and no help files whatsoever. No Win32 fun over there. :D
[/rant]
---visit #directxdev on afternet <- not just for directx, despite the name
I think I figured it out. But first some assumptions (if I make the wrong assumptions, the solution might not be correct). I think you use the glRotatef function incorrectly.

assumption: You have myRot[] float 3 array. Does this store the angles the cube is at?

glRotatef works like this:

glRotatef(angle, x, y, z) in which angle is the amount to rotate and x, y and z the axis. if:
x=1.0f
y=0.5f
z=0.0f
then it would rotate (1.0f * angle) degrees on the x axis
(0.5f * angle) degrees on the y axis and
(0.0f * angle) degrees on the z axis.

To rotate correctly on the angles stored in MyRot[] use 3 calls:

glRotatef(MyRot[0], 1.0f, 0.0f, 0.0f);
glRotatef(MyRot[1], 0.0f, 1.0f, 0.0f);
glRotatef(MyRot[2], 0.0f, 0.0f, 1.0f);

Hope this helps

- An eye for an eye will make the world go blind -

<hr />
Sander Marechal<small>[Lone Wolves][Hearts for GNOME][E-mail][Forum FAQ]</small>

Hi everyone !

Erunama, I think your problem comes from your call to glLoadIdentity() since it is used to reinitialize the matrix from wich you are doing your position calculation to the identity matrix. That means that, with this call, you''re rotating your cube by an angle of 2° along your x and y axis from it''s original orientation, not from it''s current orientation. I guess that''s one of the reasons why your cube doesn''t seems like it''s spinning.
Btw you should really use the glPushMatrix() / glPopMatrix() calls since it allows you to do any transformation you want between this two calls without affecting anything that is done outside the calls. I mean this the right way to get your cube spinning indepently from your room. Otherwise your cube and your room would be rotating the same way and you wouldn''t notice the change.
Is the room.myRotate default value false ? That''s another point that you''ve not precised.

So your code might look something like this :

for (int i = 0; i < cubes.length(); i++) {
cubes.Draw();
}

void Cube::Draw(){
if(amIDefined) {

glPushMatrix();
glTranslatef(myPosition[0],myPosition[1],myPosition[2]); if(myRotate) {
glRotatef(myAngle,myRot[0],myRot[1],myRot[2]); myAngle += myChange;
}
//Start drawing the cube
glBegin(GL_QUADS);
(Insert vertice drawing code here)
glEnd();
glPopMatrix();
}
}

Hope I''ve been clear enough and your demo will be working correctly soon. I''m still learning too and I don''t pretend that this is the answer to your problem, just that this the way I would do it.

Good luck.
"I have questions. Questions that need answering !" - Gandalf the gray, The fellowship of the ring
Let me clarify some of the questions you guys had.

IndirectX - Yes, I am pretty sure everything is being initialized correctly. Here is my constructor:

    Cube::Cube(GLfloat x, GLfloat y, GLfloat z)  : amIDefined(TRUE),    myLength(z),	myHeight(y),	myWidth(x),	myDepth(FALSE),	myRotate(FALSE),	myAngle(0.0f),	myChange(0.0f),	myRot(3),	myPosition(3),	myColor(3){	// set default position to center of screen	myPosition[0] = 0.0f;	myPosition[1] = 0.0f;	myPosition[2] = 0.0f;	// set default color to white	myColor[0] = 1.0f;	myColor[1] = 1.0f;	myColor[2] = 1.0f;}    

And yes, I dislike the whole AP coding stuff too (I take the test May 9th, but I have been doing practice questions in class). I also hate the AP classes they use, such as apmatrix, apstring, and apvector. What is the point of teaching something that we will not use outside of the class? It's not like I am going to bring along my AP files to my first job as a programmer. They should just teach the regular C++ strings and arrays.


smarechal: The array holds the axis for the cube to spin around (so in you example, x, y, and z would be stored in myRot[0], myRot[1], and myRot[2], respectively). The angle is myAngle, which is initialized to 0.0f, and is increased by myChange every time Draw() is called.

Trexmaster: I have not yet tried your code, but let me first enter a rebuttal to what you said. The cube alway starts from it's original position (0 degrees), and I am rotating it by myAngle. But every time Draw() is called, myAngle is increased by myChange. Therefore, through the first five calls, myAngle should be 0.0f, 2.0f, 4.0f, 6.0f, 8.0f. myAngle would continually be increased, therefore spinning.


A few of you have recommended using glPushMatrix() and glPopMatrix(), which I want to avoid using since I have no idea what they do. There must be some bug that I am not catching, because this program worked before I starting using classes (without Push and PopMatrix(), just glLoadIdentity).

Can anyone figure out my problem? Need more code?

Edit: Just for the record, I tried your code Trexmaster and it did not solve the problem. Thanks for your help though.



[edited by - Erunama on May 2, 2002 4:49:50 PM]
the reason for using such a library is becuase it makes exponential easier to get the concpet across. a good teacher will ween you off using the classes so by the end of you sequence you would be using only c++ code and classes you created (ie reimplement some of the basic classes). later on you could begin using STL, and such.

apvector from the code looks very much like an STL template so dont be so sure that you are not just using STL wrappers. though i think the classes you are using are probably designed with more error checking and you can actually see the code. thus be able to understand what is happening and not treat it as a blackbox.

also for reference. dont create varible names with my infront of them to show there are your varibles. it is not required and makes things look wierd. instead pick names that describe the varible, if you like prefixes, put the varible type infront. like flRot or iLength. this is merely a style concern, because it looks a bit unprofessional currrently. you dont need to change it if you dont want to for this project, but i would siggest starting to tear away from that. you probably picked up the habit from tutorials or how the teacher taught things.

This topic is closed to new replies.

Advertisement