PDA

View Full Version : Problems with glDrawArrays.



rnodal
06-06-2008, 10:27 PM
Hello all:

I'm having a difficult time rendering quads using glDrawArrays.

// Safe model view matrix and do transformations.
// Remember that transformation are done from bottom to top in term
// of code.So do rotations first then move etc.
glMatrixMode(GL_MODELVIEW);
glPushMatrix();


// Enable blending and 2D texture.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);


// Check that we have at least an image to render.
if(this->imagesToRender > 0)
{
// Temp image.
// Image *image;
// Sort images bsaed on their texture name.
// std::sort(this->imagesToRender.begin(), this->imagesToRender.end(), Image());

// Enable arrays.
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

GLuint texture;

for(int i = 0; i < (int)this->texturesUsed.size(); i++)
{

texture = this->getTexture(*(this->texturesUsed.at(i)))->texture;

// Bind texture.
glBindTexture(GL_TEXTURE_2D, texture);



glColorPointer(4, GL_FLOAT, sizeof(ColorRGBA), this->colorList);
glTexCoordPointer(2, GL_FLOAT, sizeof(TextureCoordinate), this->textureCoordinatesList);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), this->verticesList);

glDrawArrays(GL_QUADS, 0, this->imagesToRender);


}


// Disable arrays.
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);


} // Done rendering images.



// Clear textures used.
this->texturesUsed.clear();

// Reset number of images to render;
this->imagesToRender = 0;


// Restore model view matrix.
glPopMatrix();


// check if we have to change current projection mode
if(this->currentProjectionMode == ORTHOGRAPHIC)
{
this->updateProjection(true);
}



// we are done with orthographic projection so enable depth test again
glEnable(GL_DEPTH_TEST);



// Disable blending.
glDisable(GL_BLEND);


// Disable 2D texture.
glDisable(GL_TEXTURE_2D);



// since we have ended a 2D scene it is NOT safe
// to call render functions
this->safeToRender = false;


I'm very knew to opengl so I have no clue what I may be missing.
They only thing that I can think of is that I'm not "pointing" to the right direction when using "gl*Pointer" functions. The idea is to render all images in one shot and keeping state changes to the minimum. I'm also trying to keep the code compatible at least with OpenGL 1.1 and later so it can be used in older video cards. Any help, tips etc is very welcome. Very eager to lean OpenGL the right way. Thank!

-r

-NiCo-
06-07-2008, 03:25 AM
I did not check the entire code block but I believe the problem is the third parameter of
glDrawArrays(GL_QUADS, 0, this->imagesToRender);



The command
void DrawArrays( enum mode, int first, sizei count );
constructs a sequence of geometric primitives using elements first through
first + count − 1 of each enabled array. mode specifies what kind of primi-
tives are constructed;

rnodal
06-07-2008, 09:55 AM
I managed to get images to render at whatever position I want. The only problem that I'm having is that the images border shakes a little bit. Is there any command that I should issue to prevent this?


This is how I calculate each vertex:


// Left upper corner vertex.
x = imagePtr->xposition - imagePtr->xhotspot;
this->verticesList[vertexIndex] = x;
this->vertexIndex++;

y = imagePtr->yposition - imagePtr->yhotspot;
this->verticesList[vertexIndex] = y;
this->vertexIndex++;

this->verticesList[vertexIndex] = z;
this->vertexIndex++;




// Right upper corner.
x = x + imagePtr->width;
this->verticesList[vertexIndex] = x;
this->vertexIndex++;

y = y;
this->verticesList[vertexIndex] = y;
this->vertexIndex++;

this->verticesList[vertexIndex] = z;
this->vertexIndex++;



// Right bottom corner.
x = x;
this->verticesList[vertexIndex] = x;
this->vertexIndex++;

y = y + imagePtr->height;
this->verticesList[vertexIndex] = y;
this->vertexIndex++;

this->verticesList[vertexIndex] = z;
this->vertexIndex++;

// Left bottom corner.
x = imagePtr->xposition - imagePtr->xhotspot;
this->verticesList[vertexIndex] = x;
this->vertexIndex++;

y = y;
this->verticesList[vertexIndex] = y;
this->vertexIndex++;

this->verticesList[vertexIndex] = z;
this->vertexIndex++;




Also, most of the time I will be rendering images that are part of a bigger texture so when should you I use:


glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);


When I create the big texture or when I render the smaller quad with part of the texture?

Thanks a lot.

-NiCo-
06-07-2008, 01:26 PM
I managed to get images to render at whatever position I want. The only problem that I'm having is that the images border shakes a little bit. Is there any command that I should issue to prevent this?

Define 'shake'. Does it happen when you move the quad or what do you mean by 'shake'?



Also, most of the time I will be rendering images that are part of a bigger texture so when should you I use:


glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);


When I create the big texture or when I render the smaller quad with part of the texture?


Mipmapping is only useful when the texture is being minified e.g. when drawing a big texture in a smaller viewport.

rnodal
06-07-2008, 05:56 PM
Mipmapping is only useful when the texture is being minified e.g. when drawing a big texture in a smaller viewport.

If I remove that code when I create the texture containing the images then the images will not show and only the quad will be displayed.


Define 'shake'. Does it happen when you move the quad or what do you mean by 'shake'?
The edges of the images do not look the same every frame. There seems to be a flickering going on.

The demo(demo003 under output folder) is available for download from the svn repository in sourceforge.net:
easyge.svn.sourceforge.net/svnroot/easyge

I really don't have words to describe the issue so if you don't mind, please take a look at it so you can get a better picture of what the problem may be. Thanks a lot!

-r

V-man
06-07-2008, 06:27 PM
If I remove that code when I create the texture containing the images then the images will not show and only the quad will be displayed.

http://www.opengl.org/wiki/index.php/Texture_Mapping


Some people make the mistake of not calling glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, MinFilter); and they get the default state GL_LINEAR_MIPMAP_NEAREST and they don't define the mipmaps, so the texture is considered incomplete and you just get a white texture.

rnodal
06-07-2008, 06:49 PM
Thanks for pointing that out and sorry for making you take the time to point such mistake.

-R

rnodal
06-08-2008, 09:14 AM
An update. If I disable the color array the right number of images render but they all render in green. If I place glColor4f before glDrawArrays all the images render fine but I lose the ability to render quads with different colors. I can't figure out whats wrong with my color array code. I store my color components, red,green, blue, alpha in a one dimensional array and they are stored as float so I have this:


glColorPointer(4, GL_FLOAT, 0, this->colorList);


I don't understand why only some of the images are visible and others are not. Also the image that I'm rendering is 64x64, the images is a circle so the "flickering" that I'm talking about is that in some frames the border of the circle instead of being a curve is a straight line. It varies depending on the movement direction. For example if the images is moving up or down only then the top and bottom borders will suffer, if the image is moving left, right, up, down then all of the borders will be affected. This also happens with images that are rectangular.


-r