Sign in to follow this  
blinkster

Problem with vertex color

Recommended Posts

blinkster    122
Hi, I've got a problem with vertex colors and my vertex buffer object render-function. My function is as follow:
UINT uiOffset;
	UINT uiNumTexPasses;

	uiNumTexPasses = 0;
	uiOffset = 0;

        // NOTICE!
	//glPushAttrib(GL_CURRENT_BIT);

	if(nBuffer >= m_nNumVBO)
		return FATE_INVALID;

	glEnableClientState( GL_VERTEX_ARRAY );	
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_pVBO[nBuffer].nVertID);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_pVBO[nBuffer].nIndID);

	if(m_pVBO[nBuffer].dwFlags & VF_XYZ)
	{
		glEnableClientState(GL_VERTEX_ARRAY);
    	glVertexPointer(3, GL_FLOAT, m_pVBO[nBuffer].uiVertexsize, (char*)NULL);
		uiOffset += sizeof(FLOAT)*3;
	}
	if(m_pVBO[nBuffer].dwFlags & VF_NORMALS)
	{
		glEnableClientState(GL_NORMAL_ARRAY);
		glNormalPointer(GL_FLOAT, m_pVBO[nBuffer].uiVertexsize, 
			            (const GLvoid*)uiOffset);
		uiOffset += sizeof(FLOAT)*3;
	}

	if(m_pVBO[nBuffer].dwFlags & VF_DIFFUSE_RGB)
	{
		if(!(glIsEnabled(GL_COLOR_ARRAY)))
		{
		glEnableClientState(GL_COLOR_ARRAY);
		glColorPointer(3, GL_FLOAT, m_pVBO[nBuffer].uiVertexsize, (const GLvoid*) uiOffset);
		uiOffset += sizeof(FLOAT) * 3;
	    }
	}
	else
	{
		if(glIsEnabled(GL_COLOR_ARRAY))
		{
			glDisableClientState(GL_COLOR_ARRAY);
		}
	}

	if(m_pVBO[nBuffer].dwFlags & VF_TEX0)
	{
	    glActiveTextureARB(GL_TEXTURE0_ARB); 
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, Skin.nTexture[0]);

		glClientActiveTexture(GL_TEXTURE0_ARB);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glTexCoordPointer(2, GL_FLOAT, m_pVBO[nBuffer].uiVertexsize, 
			              (const GLvoid*) uiOffset);

		uiOffset += sizeof(FLOAT)*2;
		uiNumTexPasses++;
	}// do this with stage 1, 2, 3... (I didnt past it here!)
	
	if(m_pVBO[nBuffer].nNumIndices > 0)
	{
	    glDrawElements(GL_TRIANGLES, m_pVBO[nBuffer].nNumIndices, GL_UNSIGNED_SHORT, 0);	
	}
	else
		glDrawArrays(GL_TRIANGLES, 0, m_pVBO[nBuffer].nNumVertices);



	if(m_pVBO[nBuffer].dwFlags & VF_XYZ) 
	    glDisableClientState( GL_VERTEX_ARRAY );
	if(m_pVBO[nBuffer].dwFlags & VF_NORMALS)
	    glDisableClientState( GL_NORMAL_ARRAY );
	if(m_pVBO[nBuffer].dwFlags & VF_DIFFUSE_RGB)
		glDisableClientState(GL_COLOR_ARRAY);

	glDisableClientState( GL_TEXTURE_COORD_ARRAY );	
	if(Skin.bAlpha) glDisable(GL_BLEND);
	

	// NOTICE!
        //glPopAttrib();

The problem is that if I render an object with vertex color(with flag VF_DIFFUSE_RGB set in the code) it works, but other objects without vertex color are rendered with color, too, although I call glDisableClientState(GL_COLOR_ARRAY); if the VF_DIFFUSE_RGB flag werent set! Strangely enough there is no problem if I call glPushAttrib() and glPopAttrib()(see my marks in the code). My problem is that I have absolutely no idea what is wrong in the code, and I want to fix the problem without using glPushAttrib(). Please help me and excuse my "non-good" english. ;)

Share this post


Link to post
Share on other sites
nts    968
Are you disabling the texture stages if they aren't needed and also the texture coords (if not needed) for each unit?

Share this post


Link to post
Share on other sites
TomasH    360
A vertex always has a color. It is equal to the current color at the time you call glVertex* (or the vertex is drawn any other way, like glDrawArrays.) If you haven't set the current color, it is equal to white.

Drawing an object with glDrawArrays and color array enabled will change the current color.
So what you need to do, is to set color to white when you draw a "non-colored object"

(The same goes for normals, vertex coordinates etc. All of these are just states that you can change with glNormal*, glTexCoord* and so on. These will be changed when you call glDrawArrays and have the corresponding array enabled.)

Share this post


Link to post
Share on other sites
James Trotter    432
glPushAttrib stores certain OpenGL states and allows you to restore them with glPopAttrib. In this case GL_CURRENT_BIT will store the state of the current colour, and it will be restored after the vbo has been rendered.

It might be simpler to just set the colour to white (i.e. glColor3f(1.0f, 1.0f, 1.0)), after rendering the vbo.

Share this post


Link to post
Share on other sites
blinkster    122
Quote:
Original post by nts
Are you disabling the texture stages if they aren't needed and also the texture coords (if not needed) for each unit?

I do, but I didnt past it in the code(so the code does not become too long).

@ThomasH & JamesTrotter
Thank you. It works with setting the color to white. But what I still dont understand is why OpenGL still uses the current color, although I called glDisableClientState(GL_COLOR_ARRAY)? I thought, when I call glDisableClientState(GL_COLOR_ARRAY) a color is set but not used!?

Share this post


Link to post
Share on other sites
Aeluned    196
OpenGL will *always* use the current color to color the vertex, there's no getting around that.
By disabling the color array you are no longer sending new colors to the OpenGL state machine, but the color state is still set from the *last* color it used before (in this case, perhaps the last entry in your color array).

Share this post


Link to post
Share on other sites
Name_Unknown    100
Quote:
Original post by blinkster
Hi,
I've got a problem with vertex colors and my vertex buffer object render-function. My function is as follow:
*** Source Snippet Removed ***
The problem is that if I render an object with vertex color(with flag VF_DIFFUSE_RGB set in the code) it works, but other objects without vertex color are rendered with color, too, although I call glDisableClientState(GL_COLOR_ARRAY); if the VF_DIFFUSE_RGB flag werent set! Strangely enough there is no problem if I call glPushAttrib() and glPopAttrib()(see my marks in the code).
My problem is that I have absolutely no idea what is wrong in the code, and I want to fix the problem without using glPushAttrib(). Please help me and excuse my "non-good" english. ;)



why do you enable vertex arrays twice.. why do you mix and match VBOs like that? I am not sure if it works well like that.. it might, but I wouldn't do it. Either use VBOs for everything or nothing. If the data is dynamic use GL_DYNAMIC_DRAW. Binding vbuffers is pretty fast don't worry about it.

I don't bother with glIsEnabled anyways, I just do it, it doesn't seem to hurt very much, and I don't bother to test at the end I just disable everything. I have not seen any hurt in my performance doing this, it is client side so I think it is a pretty quick thing to do.

But if you disable color array it will use the last color you set with glColorxx. So set glColor4f(1,1,1,1) when turning it off instead.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this