# glDrawRangeElement issue.

This topic is 4428 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

i'm not coding in C++. Instead i'm using blitzmax. However, i doubt it's the source of the problem. Case Key_1 does as expected and renders the quad. Case Key_2 does as expected and renders the top corner. However case Key_3 only renders the left upper half. Instead it's suppost to render the bottom right corner of the quad. Can someone help me out here?
GLGraphics 800,600
glewInit()

Local	fltVertex#[] =[ -1.0 , 1.0 , 0.0 ,    1.0 , 1.0,  0.0 ,    -1.0, -1.0, 0.0 ,    1.0, -1.0, 0.0 ]
Local	fltColor#[] = [ 1.0 ,  0.0 , 0.0 ,    0.0 , 1.0,  0.0 ,     0.0,  0.0, 1.0 ,    1.0,  1.0, 0.0 ]
'              Red                      Green              Blue                  Yellow
Local	shtElements:Short[] = [ 0:Short,  1:Short, 2:Short, 1:Short, 3:Short , 2:Short ]

glMatrixMode(GL_PROJECTION);				'		// Select The Projection Matrix
glLoadIdentity();							'// Reset The Projection Matrix

'// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0 ,Float(GraphicsWidth())/GraphicsHeight(),0.1 ,100.0 );

glMatrixMode(GL_MODELVIEW);						'// Select The Modelview Matrix

glClearColor( 0.0, 0.0 , 0.0 , 0.0 )

glEnable(GL_DEPTH_TEST);					'	// Enables Depth Testing

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

glEnableClientState(GL_VERTEX_ARRAY)
glEnableCLientState(GL_Color_Array)
glVertexPointer(3, GL_FLOAT , 0 , Varptr(fltVertex[0]) )
glColorPointer(3,  GL_FLOAT , 0 , Varptr(fltColor[0]) )

Local KeyInput = KEY_1
While Not KeyHit(KEY_A)

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);			'// Clear The Screen And The Depth Buffer
glLoadIdentity();							'// Reset The Current Modelview Matrix

glTranslatef( 0.0 , 0.0, -5.0 )

If KeyHit(KEY_1)
Keyinput = KEY_1
ElseIf KeyHit(Key_2)
keyinput = KEY_2
ElseIf KeyHit(Key_3)
keyinput = KEY_3
EndIf

Select KeyInput

Case KEY_1
glDrawRangeElements(GL_TRIANGLES, 0,5,6, GL_UNSIGNED_SHORT , Varptr(shtElements[0]) )
Case Key_2
glDrawRangeElements(GL_TRIANGLES, 0,2,3, GL_UNSIGNED_SHORT , Varptr(shtElements[0]) )
Case Key_3
glDrawRangeElements(GL_TRIANGLES, 3,5,3, GL_UNSIGNED_SHORT , Varptr(shtElements[0]) )

End Select

Flip()

Wend

gldisableClientState(GL_VERTEX_ARRAY)
gldisableCLientState(GL_Color_Array)



##### Share on other sites
Quote:
 Original post by Drey Case KEY_1 glDrawRangeElements(GL_TRIANGLES, 0,5,6, GL_UNSIGNED_SHORT , Varptr(shtElements[0]) ) Case Key_2 glDrawRangeElements(GL_TRIANGLES, 0,2,3, GL_UNSIGNED_SHORT , Varptr(shtElements[0]) ) Case Key_3 glDrawRangeElements(GL_TRIANGLES, 3,5,3, GL_UNSIGNED_SHORT , Varptr(shtElements[0]) )

Well I don't know the language, but shouldn't the last parameter to glDrawRangeElements in case Key_3 be Varptr(shtElements[3])?

Remember, glDraw*Elements will start dereferncing from the pointer you provide irrespective of the range.

##### Share on other sites
First, your call for case 3 is identical to that of case 2, except the range of index values. So if case 2 draws the top half then so should case 3.

Second, you start and end values are the maximum and minimum values in the index array. For case 3, you say that no indices are outside the range [3, 5]. But clearly every index except the second last index is outside this range. I assume the call for case 3 would looks something like this (adjust the syntax for your language).
glDrawRangeElements(GL_TRIANGLES,                               1,    // Smallest value in the range of interest (index 3 to 5, see below) is 1.                               3,    // Largest index in the range of interest is 3.                               3,    // Draw 3 indices, making one triangle.               GL_UNSIGNED_SHORT,               Varptr(shtElements[3])    // Start drawing at index 3, which means index 3 to 5 since the number of indices to draw is 3.);

For the same reason, case 1 and 2, while not wrong in the sense that you're lying to OpenGL about the smallest and largest index value, are not really correct. Case 1 should have smallest and largest index set to 0 and 3, respectively, and case 2, 0 and 2.

Now while writing mu reply it seems like you misunderstand the start and end values. Seems like you think these values are represent what part of the index array to use, but they are not. OpenGL is perfectly capable of calculating those values itself from the start pointer and the number of indices to draw. What it's not capable of is to determine what the values of those indices are, i.e. the content of the index array.

##### Share on other sites
OK, but changing the pointers like that isn't an good idea for VBOs though or should i use gBufferSubData for every range change? Kinda kills the purpose though. How will i control regions with VBO?

##### Share on other sites
Quote:
 Original post by DreyOK, but changing the pointers like that isn't an good idea for VBOs though ...

Why do you thisnk that?

You are just providing an offset from the start of your index array basically. There is no additional cost in providing &indices[n] and &indices[0] ... the GPU just starts reading from a different memory address.

##### Share on other sites
because my orginal design idea was to have prepare the VBO once ( with glbindbuffer ) and then call on regions of the array as needed. So the array loaded was going to be the WHOLE mesh, and i was giong to call on glDraw"Range"Elements to render different parts under different matrices. It would have only taken one command before for VBO..now it seems like i have to do a few..which defeats the purpose somewhat.

##### Share on other sites
But you don't have to change any arrays, and what we're telling you to do is what you want to do. If you want OpenGL to draw 3 vertices, starting at the 3:rd index, then you pass a pointer (or offset, since you use VBO) to the 3:rd index, and set the size to 3.

Range in glDrawRangeElements does not refer to drawing a sub range of the index array. It tells OpenGL what the range of the index values, the values in the index array, is. For the purpose of only drawing certain parts of the object, then glDrawElements is just fine. glDrawRangeElements doesn't provide anything but the chance of a more optimized rendering. It doesn't provide anything that can't be done with glDrawElements.

##### Share on other sites
Oh, i understand that. I'm just worried about my VBOs working correctly now.

glGenBuffers 1, Varptr(intVertexBuffer)
glBindBuffer(GL_ARRAY_BUFFER, intVertexBuffer)
glBufferData(GL_ARRAY_BUFFER, SizeOf(fltVertex), Varptr(fltVertex[0]), GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, 0 )

in bufferdata i'll have to change to Varptr(fltVertex[3]) for this example. I was trying to avoid calling bindbuffer again. The idea was to do something like this.
Mesh.BeginRender() //if in VBO mode, binds buffers.  If in VA mode, sets pointersLoops for Num Of RefMesh  Loops for RefMesh.SegementUpdateList       // Model Transform matrix       Segement.Position.toMatrixLoad()      //       Mesh.Render( Segement.ElementRange )  // Range object containing starting and ending in the arrayEnd LoopMesh.EndRender()

It's rough peusocode, but it conveys the idea mostly.
I know it's not a big deal in VA(change pointers) but it is in VBO. Is there a way to get the same effect without rebinding?

##### Share on other sites
Unless what you're telling us is not whta you actually want, then the answer we have given you is the solution to your problem.

Create the VBO by uploading the mesh data once, and only once. No need to touch it any more. When drawing sub parts of the mesh, adjust the starting address passed to glDraw(Range)Elements.

That's all there is. Really.

##### Share on other sites
I had a post typed up but now i really understand what's goin on now. I can bind everything like normal except the indices array. I was binding that as well. That's where all this confusion came from. I guess it isn't really too bad a bottleneck to have the indice array stream from the RAM and nothing else.

I was passing a null as a pointer once i had the indice array loaded

							glGenBuffers 1, Varptr(intVertexBuffer)				glBindBuffer(GL_ARRAY_BUFFER, intVertexBuffer)				glBufferData(GL_ARRAY_BUFFER, SizeOf(fltVertex), Varptr(fltVertex[0]), GL_STATIC_DRAW)				glBindBuffer(GL_ARRAY_BUFFER, 0 )								glGenBuffers(1,  Varptr(intElementBuffer) )				glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, intElementBuffer)				glBufferData(GL_ELEMENT_ARRAY_BUFFER, SizeOf(shtElements), Varptr(shtElements[0]), GL_STATIC_DRAW)				glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0 )

Then i will have 3 modes. ALL VBO(including indices, non animated or non seperatable items), Partical VBO mode(likely excluding indice binding), and a VA mode. (if i'm understanding this correctly)

Thanks guys! :-D

1. 1
2. 2
3. 3
4. 4
frob
11
5. 5

• 12
• 16
• 13
• 20
• 12
• ### Forum Statistics

• Total Topics
632175
• Total Posts
3004584

×