PDA

View Full Version : Problems with DrawElements :(



M/\dm/\n
11-24-2002, 10:01 PM
float *va, *na, *ta;
unsigned int *i3, *i4;
sizes temp;
temp = GetPointerSizes("1.obj");
va = new float[temp.vert*3+3];
na = new float[temp.vert*3+3];
ta = new float[temp.vert*2+2];
i3 = new unsigned int[temp.i3*3];
i4 = new unsigned int[temp.i4*4];
Loader("1.obj", va, na, ta, i3, i4);
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer(3, GL_FLOAT, 0, va);
rhino = glGenLists (1);
glNewList(rhino, GL_COMPILE);
glColor4f(1,0,0,1);
(temp.i3==0)?NULL:glDrawElements(GL_TRIANGLES, temp.i3, GL_UNSIGNED_INT, i3);
(temp.i4==0)?NULL:glDrawElements(GL_QUADS, temp.i4, GL_UNSIGNED_INT, i4);
glEndList();
glDisableClientState (GL_VERTEX_ARRAY);

This is the part that dosn't seem to work http://www.opengl.org/discussion_boards/ubb/frown.gif temp.i3,i4&vert are integer values. I just don't know what is wrong here :?

[This message has been edited by M/\dm/\n (edited 11-24-2002).]

[This message has been edited by M/\dm/\n (edited 11-24-2002).]

M/\dm/\n
11-27-2002, 01:18 AM
Heeeeeeeelp plzzzzzzzzz!!

Bob
11-27-2002, 01:48 AM
You can begin with explaining what "dosn't seem to work" mean. As far as I know, vertex arrays can "not work" in quite a few different ways, including craches during runtime dues to invalid pointers or indices, compile time errors due wrong parameters, and currupt models due to messed up indices.

If you want any help, at least say what is wrong. We can't just guess.

M/\dm/\n
11-27-2002, 02:42 AM
Sorry. The problem is in fact that program draws nothing, all arrays called through pointers have real values from files, inices are all right (I even substracted 1 from value in the file to get array elements starting from 0, as it's not implemented in standart obj files, indices start from 1) I had feeling that DrawElements is incompatible with pointers so that I should have "real" array, but it seems that NVIDIAs cg_simple demo uses pointers with no problems, *va notation also gives nothing http://www.opengl.org/discussion_boards/ubb/frown.gif. I'can send my all program importer code, or maybe it'll be sufficient for me to take a look at simple, working obj imported (without p_mender.objectrender->vertexarray.pointer(get)) 8))

Bob
11-27-2002, 03:33 AM
...draws nothing...

Are you sure the viewpoit is correctly set up so the model is actually within the view volume? Are you sure it's not being drawn in the same color as the background? There are other factors affecting what is show and not show other than how you set up your vertex arrays.


I had feeling that DrawElements is incompatible with pointers...

A pointer is the only thing it accepts. You can't pass an array to it. When using an array, you actually pass the address of the first element in the array, which is a pointer.

Can you draw the model correct without vertex arrays? That is, with glVertex-calls.

M/\dm/\n
11-27-2002, 06:27 AM
Actually it's a 3D game, I have a maze & outdoor environment, with walls, operational doors, multitexturing & cg, I can move, look up&down and so on. Currently I'm trying to import cube with coords -1,-1,-1, 1,1,1, which simply stands centred at point 0,0,0 (I can walk to that point http://www.opengl.org/discussion_boards/ubb/smile.gif) because I'm NOT calling glLoadIdentity before drawing it. Or else it would move with me, it would be drawn around me & polygon culling would do the job.
By the way, I'm trying to get this cube in to the display list, maybe that's the problem? Also, I tried to call few of the vertices with Vertex3f and they worked!? http://www.opengl.org/discussion_boards/ubb/frown.gif http://www.opengl.org/discussion_boards/ubb/frown.gif http://www.opengl.org/discussion_boards/ubb/frown.gif http://www.opengl.org/discussion_boards/ubb/frown.gif http://www.opengl.org/discussion_boards/ubb/frown.gif http://www.opengl.org/discussion_boards/ubb/frown.gif http://www.opengl.org/discussion_boards/ubb/frown.gif http://www.opengl.org/discussion_boards/ubb/frown.gif http://www.opengl.org/discussion_boards/ubb/frown.gif http://www.opengl.org/discussion_boards/ubb/frown.gif

[This message has been edited by M/\dm/\n (edited 11-27-2002).]

bakery2k
11-27-2002, 07:14 AM
You are trying to put your drawElements calls in a display list.
Is VERTEX_ARRAY enabled when you call the list??

M/\dm/\n
11-28-2002, 03:43 AM
Yes, for sure http://www.opengl.org/discussion_boards/ubb/frown.gif

Music_Man
11-28-2002, 05:00 AM
M/\dm/\n, this sounds remarkably like what I am doing at the moment as well (3d maze etc).... u wouldn't happen to be in your 3rd year at Hull uni would u?

Music_Man :-)

Relic
11-28-2002, 05:03 AM
If temp.i3 is the number of triangles and temp.i4 the number of quads, the drawelements calls are both using the wrong amount of indices.

glDrawElements manual:
"When you call the glDrawElements function, it uses count sequential elements from indices to construct a sequence of geometric primitives. The mode parameter specifies what kind of primitives are constructed, and how the array elements are used to construct these primitives. If GL_VERTEX_ARRAY is not enabled, no geometric primitives are generated."



Is VERTEX_ARRAY enabled when you call the list??

Yes, for sure


Huh? No, you don't want that.

Also from the glDrawElements manual:
"You can include the glDrawElements function in display lists. When glDrawElements is included in a display list, the necessary array data (determined by the array pointers and enables) is also entered into the display list. Because the array pointers and enables are client-side state variables, their values affect display lists when the lists are created, not when the lists are executed."

And wouldn't be
if (temp.i3!=0) glDrawElements(GL_TRIANGLES, temp.i3*3, GL_UNSIGNED_INT, i3);
if (temp.i4!=0) glDrawElements(GL_QUADS, temp.i4*4, GL_UNSIGNED_INT, i4);
be much nicer in the above code.

M/\dm/\n
11-28-2002, 08:55 AM
Nop I'm not at my 3rd year at Hull, I'm at my 2nd year in DU, Latvia http://www.opengl.org/discussion_boards/ubb/frown.gif http://www.opengl.org/discussion_boards/ubb/smile.gif, but if you want to share some ideas, just let me know http://www.opengl.org/discussion_boards/ubb/smile.gif I'm checking this forum every day! By the way, how long it'll take you to find Latvia on the world map? Just wondering http://www.opengl.org/discussion_boards/ubb/smile.gif

About code:

if (temp.i3!=0) glDrawElements(GL_TRIANGLES, temp.i3*3, GL_UNSIGNED_INT, i3); ? : should be closer to assembly: je, jbe ... (only one operation) if you know what I mean. Although I'd be happy if someone could tell me is that right. I'm too lazy to check it out myself.

about temp.i3:
OBJ files include lines f 1/1/1 2/2/2 3/3/3 and f 1/1/1 2/2/2 3/3/3 4/4/4, that means case 1: use vertices 1,2,3 to draw triangle, case 2: use vertices 1,2,3,4 to draw quad. So every quad line adds 1 to temp.i4, and every triangle line adds 1 to temp.i3;
Yes, one more time, I noticed that (1/1/1)=>1=>1-1; because vertexarrays starts from 0.
I guess that ././. notation shows xcord from vertice N/ycoord from vertice N/zcoord from vertice, but they are same anyways.

Thats the way it is http://www.opengl.org/discussion_boards/ubb/frown.gif

[This message has been edited by M/\dm/\n (edited 11-28-2002).]

M/\dm/\n
11-28-2002, 09:14 AM
Well, I guess I must finaly send my code. It's possible that there is an ordinary C++ bug (as often happens), and maybe someone will benefit from it http://www.opengl.org/discussion_boards/ubb/smile.gif
So:
header file => ObjLoader.h <=



#include <windows.h>
#include <GL/gl.h>

struct sizes
{
int vert;
int i3;
int i4;
};

sizes GetPointerSizes(const char *file);
void Loader(const char *file, float *va, float *na, float *ta, unsigned int *i3, unsigned int *i4);

and source file => ObjLoader.cpp <=



#include <fstream.h>
#include <string.h>
#include "ObjLoader.h"

struct sizes GetPointerSizes(const char *file)
{
sizes temp;
temp.i3=0;
temp.i4=0;
temp.vert=0;

fstream obj;
obj.open(file,ios::in);
if (!obj.is_open())
MessageBox(NULL,"Error opening file!","Load error!",MB_ICONSTOP);
while (!obj.eof())
{
char c[100]="";
obj.getline(c,99,'\n');
if ((c[0]=='v') &amp;&amp; (c[1]==' '))
temp.vert++;
if ((c[0]=='f') &amp;&amp; (c[1]==' '))
{
int i=0, sp=0;
while (c[i]!=0)
{
if (c[i]==32)
sp++;
i++;
}
(sp>3)?temp.i4++:temp.i3++;
}
}
obj.close();

return temp;
}

void Loader(const char *file, float *va, float *na, float *ta, unsigned int *i3, unsigned int *i4)
{
fstream obj;
obj.open("1.obj",ios::in);
if (!obj.is_open())
MessageBox(NULL,"Error opening file!","Load error!",MB_ICONSTOP);
while (!obj.eof())
{
int i=0;
char c[89]="";
obj.getline(c,88,'\n');
if ((c[0]=='v') &amp;&amp; (c[1]==' '))
for (i=0;i<abs(strlen(c));i++)
{
if (c[i]==' ')
{
int k=i+1;
char temp[26]="";
int j=0;
while ((c[k]!=' ')&amp;&amp;(c[k]!=0))
{
temp[j]=c[k];
j++;
k++;
}
*va++=float(atof(temp));
}
}
if ((c[0]=='v') &amp;&amp; (c[1]=='t'))
for (i=0;i<abs(strlen(c));i++)
{
if (c[i]==' ')
{
int k=i+1;
char temp[12]="";
int j=0;
while ((c[k]!=' ')&amp;&amp;(c[k]!=0))
{
temp[j]=c[k];
j++;
k++;
}
*ta++=float(atof(temp));
}
}
if ((c[0]=='v') &amp;&amp; (c[1]=='n'))
for (i=0;i<abs(strlen(c));i++)
{
if (c[i]==' ')
{
int k=i+1;
char temp[26]="";
int j=0;
while ((c[k]!=' ')&amp;&amp;(c[k]!=0))
{
temp[j]=c[k];
j++;
k++;
}
*na++=float(atof(temp));
}
}
if ((c[0]=='f') &amp;&amp; (c[1]==' '))
{
int i=0, sp=0;
while (c[i]!=0)
{
if (c[i]==' ')
sp++;
i++;
}
if (sp>3)
{
for (i=0;i<abs(strlen(c));i++)
{
if (c[i]==' ')
{
int k=i+1;
char temp[5]="";
int j=0;
while ((c[k]!='/')&amp;&amp;(c[k]!=0))
{
temp[j]=c[k];
j++;
k++;
}
*i4++=int(atoi(temp))-1;
}
}
}
else
{
for (i=0;i<abs(strlen(c));i++)
{
if (c[i]==' ')
{
int k=i+1;
char temp[5]="";
int j=0;
while ((c[k]!='/')&amp;&amp;(c[k]!=0))
{
temp[j]=c[k];
j++;
k++;
}
*i3++=int(atoi(temp))-1;
}
}
}
}

}
obj.close();
}


I'll be thankfull about any advice, bugs, optimization and so on.

Music_Man
11-28-2002, 04:02 PM
Random (educatedish) guess, Latvia, hmmm. baltic states springs to mind, dont knwo why.... eastern europe? I should know really, I am in the UK :-)

M/\dm/\n
11-28-2002, 09:40 PM
I remember that few years ago Latvia was quite a "mystic" country at don't, know where. Thatís why I asked http://www.opengl.org/discussion_boards/ubb/smile.gif

By the way, you said that you are working on something similar. Have you got working collision test? I wrote one, but it's based on logical comparisons without BSP or that sort of things, although I have implemented some sort of space dividing, but it doesn't seem like the most efficient way for this sort of programs. And one more thing, I have a ceiling in my maze, and each "square" 2x2 has it own light source => lightmap & sphere in the centre (because I can't get my OBJ importer working), the problem is in fact that those glutSolidSpheres(0.5,10,10); simply kills my fps 70=>36. What's the hell? Polygon count shouldn't affect that, and culling is on. And what's about huge polygons they seem to use a lot of computing power.

Music_Man
11-29-2002, 04:50 AM
I havent got very far with the maze yet, basically have two levels (floor,walls, ceiling) linked by a lift, with a bouncing ball in the middle of the ground floor. Have turned on running and jumping, and also movement which allows turning while moving rather than move, stop, turn, move..... This may seem like basic stuff to you but this is as far as I have got unfortunately. I have got it so that you cant walk through the outer perimiter except to get in the lift, but thats it. Am finishing off the lift at the moment, and am then gonna look at collision detection. I posted a topic on here a couple of days ago (Collision detection...help - or something like that) and there was a good suggestion on how to do it. May be worth a look :-)

Music_Man :-)

M/\dm/\n
11-29-2002, 06:45 AM
I'm not at home right now, but I'll send you the code for moving, rotating + looking up & down at time (In case you use glut, although it should work in any case). Just check your e-mail, because this topic is already at 2 pages long, and I havn't found what's wrong with the code yet http://www.opengl.org/discussion_boards/ubb/frown.gif
Maybe you know nice timing function in C++, shortest period I can record is 1s, but that works only for my FPS counter well. I guess, you should know one if you have bouncing sphere.

[This message has been edited by M/\dm/\n (edited 11-29-2002).]

Music_Man
11-29-2002, 08:46 AM
Cheers for the offer, I have got rotations etc working... just collision detection being a bitch at the moment, haven't really looked at it to be fair tho....

Unfortunately, I dont know any timing functions, I am using Java, but havent come across any yet.... For my bouncing sphere, I am just making it go up (or down) by the square root of the difference between where it is now, and the max height, crude, but it does make it slow down when going up, and speed up when going down :-)