PDA

View Full Version : Not Rendering triangles



Hylke Donker
03-15-2006, 11:32 AM
Hello,
I currently have a *really strange problem. When my program loads and then renders 2 models, it only rendered the first first model.
After some diging and code de-listing I ended up with the following code:

cout << "Render3DS::Render()" << endl;

for(unsigned int j = 0;j < Model3DS.meshes.size();j++)
{
vector<Face3DS>::iterator FaceIt;
for(FaceIt = Model3DS.meshes.at(j).Faces.begin();FaceIt < Model3DS.meshes.at(j).Faces.end();FaceIt++)
{
if(FaceIt->HasMaterial)
{


}

glBegin(GL_TRIANGLES);
glVertex3f(FaceIt->Vertices.data[0],FaceIt->Vertices.data[1], FaceIt->Vertices.data[2]);
glVertex3f(FaceIt->Vertices.data[3],FaceIt->Vertices.data[4], FaceIt->Vertices.data[5]);
glVertex3f(FaceIt->Vertices.data[6],FaceIt->Vertices.data[7], FaceIt->Vertices.data[8]);
glEnd();
}
}The points do contain values(because I've printed them out using cout), but for some strange reason it doesn't render anything. I have lighting disabled, and I don't get any OpenGL errors(from glGetError).
I gues you can't see the problem from only this piece of code, but I really have no idea where else to look for the problem.
I hope somebody can help me fix this problem.
Hylke

jide
03-15-2006, 01:17 PM
You guess very well :)

Komat
03-15-2006, 01:21 PM
The code you presented here draws both models in single "pass" (for diffent values of j variable) or it is called twice with two different Model3DS objects?

Hylke Donker
03-16-2006, 12:00 AM
Originally posted by jide:
You guess very well :) Do you have any idea where/what it could be?


The code you presented here draws both models in single "pass" (for diffent values of j variable) or it is called twice with two different Model3DS objects? It's supposed to draw every face of every mesh of my model. And what exactly do you mean with 'single pass'?
Hylke

Komat
03-16-2006, 12:43 AM
And what exactly do you mean with 'single pass'?If both models you draw are stored in single Model3DS.meshes

jide
03-16-2006, 01:59 AM
You should give much more information. Did you ensure the two models are not rendered in the same place and that one of them is not more little than the other (so it could be rendered but inside the other so not seenable) ?

Did you try to render, one, then the other ? Are they visible ?

Ehsan Kamrani
03-16-2006, 02:35 AM
Or maybe the model is not in your view volume.
Maybe you have enabled the face culling and it culls your faces. ;-)

Hylke Donker
03-17-2006, 02:55 AM
Originally posted by Komat:
If both models you draw are stored in single Model3DS.meshes Each model has a seperate Model3DS structure, and all models are stored in a vector.


You should give much more information. Did you ensure the two models are not rendered in the same place and that one of them is not more little than the other (so it could be rendered but inside the other so not seenable) ?

Did you try to render, one, then the other ? Are they visible ? They're not rendered in the same place, one is a little taller, but that does not supposed to change anything.
They are rendered seperate(the code that I placed is executed twice, for each model one time).
And they are visible, because it worked before.



Or maybe the model is not in your view volume.
Maybe you have enabled the face culling and it culls your faces. ;-) They are in my viewing volume(because I use a mouse and a keyboard to controll the camera(and i'm 100 % positive this is not the cause of the problem).
And checking the culling is indeed a good idea, because I remebered that I've added culling not to long a go(for a performance boost).
Hylke
PS: Niek says: :confused:

Hylke Donker
03-17-2006, 12:54 PM
It's getting really odd now. I've downloaded an old version of my code(which worked better). It renders a house and a gun, as it should, but when I add the following code to my Format3DS class:
string FileName;It no longer renders the gun. If you don't believe me(which I can imagine, since I wouldn't believe it either, if I didn't saw it my self), you can download my loading and rendering classes(required Lib3ds):
Render3DS.cpp (http://svn.gna.org/viewcvs/combatofdeath/trunk/Render3DS.cpp?rev=146&view=markup) Render3DS.h (http://svn.gna.org/viewcvs/combatofdeath/trunk/Render3DS.h?rev=146&view=markup)
Format3DS.cpp (http://svn.gna.org/viewcvs/combatofdeath/trunk/Format3DS.cpp?rev=146&view=markup) Format3DS.h (http://svn.gna.org/viewcvs/combatofdeath/trunk/Format3DS.h?rev=146&view=markup)

Komat
03-17-2006, 03:00 PM
Originally posted by Hylke Donker:
but when I add the following code to my Format3DS class:
string FileName;It no longer renders the gun.Such behaviour usually indicate that your code has memory dependent problem (like uninitialized variable, memory overwritte or incorrect pointers).

From looking at your code I suspect that the problem is that you keep pointers and iterators pointing into vectors to which you latter add additional values (vector<TextureData>::iterator TexDatIt, Mesh3DS *ParentNode, vector<vector<Mesh3DS>::iterator> ChildNodes ). Basically if vector is modified by adding or removing element then pointers and iterators pointing into it may become invalid if vector allocates new memory during that operation.

Hylke Donker
03-17-2006, 11:50 PM
So lets say, if I have a class called A, with the element C(which is a pointer), and create a vector of A's like this:
vector<A> MyAVector;I can't allocate memory like this:
MyAVector.begin()->c = new char;?

jide
03-18-2006, 01:49 AM
What you have usually means memory leaks. Debug your program. Check what Komat told you, I guess he pointed something interresting (can't ensure it since I didn't saw your code).

You can do what you wrote with vectors since A is a class holding c defined as a char* and that you do the appropriate operations on container's deletion.

What Komat says is that:


vector<int> v;
v.push_back (1);
vector<int>::iterator i = v.begin();

for (;i!=v.end();++i){
cout << *i << endl;
if ((*i) < 10)
v.push_back ((*i)+1);
}
...You simply cannot do that !! Each time you add, remove, well change your container, then you must go threw it since the start:


vector<int> v;
v.push_back (1);
vector<int>::iterator i = v.begin();

for (;i!=v.end();){
cout << *i << endl;
if ((*i) < 10){
v.push_back ((*i)+1);
i = v.begin();
}
else
i++;
}
...My code might not work, of course ;)

Well as this is now out of GL, I just can advise you to check some good tutorials about C++. Bjarne Stroustrup's books are most certainly the best.
Also, check that, don't remember if he points what we actually are speaking aobut, but that might help you:

http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html

Komat
03-18-2006, 03:05 AM
Much simpler example is:

vector<int> v;
v.push_back( 1 ) ;

vector<int>::iterator it = v.begin();
int * p = &amp;(*it) ;

// Here both it and p are valid.

v.push_back( 2 ) ;

// Now both p and it may be invalid if
// vector relocated memory into which objects
// are stored into another place.

Komat
03-18-2006, 04:03 AM
Originally posted by Hylke Donker:
So lets say, if I have a class called A, with the element C(which is a pointer), and create a vector of A's like this:
vector<A> MyAVector;I can't allocate memory like this:
MyAVector.begin()->c = new char;? You can however if destructor of class A deletes memory pointed by C, you have to create copy constructor that creates copy of that memory.

Following code will fail to work with vector if reallocation happens:


class Foo {

DataStruct * data ;

public:

Foo()
: data( NULL )
{
}

~Foo()
{
delete[] data ;
}
} ;Following example should work.


class Foo {

DataStruct * data ;

public:

Foo()
: data( NULL )
{
}

~Foo()
{
delete[] data ;
}

Foo( const Foo & other )
: data( NULL )
{
if ( other.data ) {
data = new DataStruct( *other.data )
}
}
} ;

Ehsan Kamrani
03-18-2006, 04:59 AM
Komat,
I guess that *other.data produces a syntax error. You should write it in this manner:
(*other).data
In your code, compiler interpreates it as *(other.data) and i guess it is an invalid command. But i'm not sure ;-)
-Ehsan-

jide
03-18-2006, 05:18 AM
No Ehsan. other is a referency, you can't dereference a reference, only a pointer. So this looks good for me (this is data that is a pointer and need to be copied by the copy constructor of DataStruct, which undoubtelly requires a reference not a pointer).

Hylke Donker
03-18-2006, 11:51 PM
Wow, thanks a lot, I would never be able to figure this out my self.

I now have a question regarding Komats' last code.
I don't fully understand the code:
Foo( const Foo & other )
: data( NULL )
{
if ( other.data ) {
data = new DataStruct( *other.data )
}
}What does the DataStruct constructor do with data, and why doesn't work the example above?

Komat
03-19-2006, 02:33 AM
What does the DataStruct constructor do with dataThe constructor initializes object from the data given to it. The default copy constructor that is generated by compiler calls copy constructor on ancestor class if there is any and on each class variable.



and why doesn't work the example above?
When vector increases in size, it may need to allocate new memory because all elements it contains are stored in one continuous memory block.
After it allocates that new block it copies content of the old block into the new block by calling copy constructor on each element in the block. If default copy constructor is used, pointers are simply copied which is still fine.
Problem is that after this copy is done the old memory block is destroyed by calling destructors on all elements in it. If destructor of element frees memory pointed by the pointer, the copies in new memory block will still point to place where that memory once was, which is obviously incorrect.

Hylke Donker
03-22-2006, 12:31 PM
Wow, thank you very much.
I gues I should really buy a C++ boek if I have enough money, because these things are really fital to know. :p

jide
03-22-2006, 01:38 PM
This turns out: you can't program without knowing the language you use :)