• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
masterbubu

Gpu skinning and VBO

8 posts in this topic

Hi,

 

I have used for some time a gpu skeleton system that preforms well with vertex arrays.

 

I decided to try use VBOs, with the same setup as I have now,and just replace the vertex arrays with VBOs. ( vertices, weights, indices ).

 

For some reason the I get bad deformations. 

 

However, if I keep the vertices data on vbo, and the weights/indices at vertex arrays, the renders looks fine.

 

I'm asking for some direction to explore, assuming that the weights and the indices are stored properly on the VBOs,

 

is the data on VA stored differently then VBO? I'm just trying to figure what can cause the problem.

 

tnx smile.png

 

 

 

0

Share this post


Link to post
Share on other sites

I'm asking for some direction to explore, assuming that the weights and the indices are stored properly on the VBOs,

I really would double check your assumption first, a little bug while building/using the VBOs ? Can you post some code ?

2

Share this post


Link to post
Share on other sites

Having done GPU skinning with VBOs, I can tell you it works.

 

Getting the offsets right in the OpenCL kernel (which is what I'm using, you could also could instead reasonably be using the transform feedback buffer; you didn't say) was somewhat tricky. As requested above, post some code.

0

Share this post


Link to post
Share on other sites

Hi, I cut some parts of the code that relevant to the issue.

 

I still did not manage to spot the problematic area.

 

Please note that the same code and shaders works for VA, but not for VBO.

struct sBoneData
{
	vec4 vWeights,
	vIndices;
};

Vertex Arrays

	glVertexAttribPointer( iPositionAttribLoc, 3, GL_FLOAT, GL_FALSE,  sizeof( vec3 ), &pGeo->vVertices[0].x );
    glEnableVertexAttribArray( iPositionAttribLoc );

	glVertexAttribPointer( iBoneWeightsAttribLoc, 4, GL_FLOAT, GL_FALSE, sizeof( sBoneData ), &pGeo->vBonesData[0].vWeights.x );
	glEnableVertexAttribArray( iBoneWeightsAttribLoc );
	           
	glVertexAttribPointer( iBoneIndexesAttribLoc, 4, GL_FLOAT, GL_FALSE, sizeof( sBoneData ), &pGeo->vBonesData[0].vIndices.x );
	glEnableVertexAttribArray( iBoneIndexesAttribLoc );
	

	unsigned int *ptr = &pGeo->vFaces[ m_pObj->iFacesStartPos ].uIndex[ 0 ];
	unsigned int  sz = (unsigned int)( m_pObj->iFacesEndPos - m_pObj->iFacesStartPos ) * 3;
	glDrawElements( GL_TRIANGLES, m_uNumElements, GL_UNSIGNED_INT, 0 );

VBO

Generate ...
{
	
	glGenBuffers(3, m_Buffers);

	glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[0]);
	
	size_t size = sizeof(vec3) * pGeo->vVertices.size(); 

	glBufferData(GL_ARRAY_BUFFER, size ,0 , GL_STATIC_DRAW);

	size_t startOff = 0,
		   currSize = sizeof(vec3) *pGeo->vVertices.size();
	
	m_VertexOffset = startOff;

	glBufferSubData(GL_ARRAY_BUFFER, startOff, currSize, &pGeo->vVertices[0].x );

	glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[1]);

	// Indices and weights
	size_t size2 = sizeof(vec4) *pGeo->vBonesData.size() * 2; 

	glBufferData(GL_ARRAY_BUFFER, size2 ,0 , GL_STATIC_DRAW);

	startOff = 0;
	currSize = sizeof(vec4) *pGeo->vBonesData.size();
	m_BonesWeightsOffset = startOff;

	glBufferSubData(GL_ARRAY_BUFFER, startOff, currSize, &pGeo->vBonesData[0].vWeights.x );

	startOff += currSize;
	currSize = sizeof(vec4) *pGeo->vBonesData.size();
	m_BonesIndicesOffset = startOff;

	glBufferSubData(GL_ARRAY_BUFFER, startOff,currSize,	&pGeo->vBonesData[0].vIndices.x  );

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_Buffers[2]);

	unsigned int *ptr = &pGeo->vFaces[ m_pObj->iFacesStartPos ].uIndex[ 0 ];
	unsigned int  sz = (unsigned int)( m_pObj->iFacesEndPos - m_pObj->iFacesStartPos ) * 3;
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GL_UNSIGNED_INT) * sz,ptr, GL_STATIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);


Bind ...
{
	glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[0]);
		
	if ( handlers[0] != -1 && m_VertexOffset != -1)
	{
		//glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[0]);
		glEnableVertexAttribArray( handlers[0] );
		glVertexAttribPointer( handlers[0] ,3,GL_FLOAT, GL_FALSE,  sizeof( vec3 ), reinterpret_cast<void*>( m_VertexOffset ));
	}
	{
		
	glBindBuffer(GL_ARRAY_BUFFER, m_Buffers[1]);

	if ( handlers[5] != -1 &&  m_BonesWeightsOffset != -1 )
	{
		glVertexAttribPointer( handlers[1], 4, GL_FLOAT, GL_FALSE, sizeof( sBoneData ), reinterpret_cast<void*>(m_BonesWeightsOffset) );
		glEnableVertexAttribArray( handlers[1] );
	}
	if ( handlers[6] != -1 &&  m_BonesIndicesOffset != -1 )
	{
		glVertexAttribPointer( handlers[2], 4, GL_FLOAT, GL_FALSE, sizeof( sBoneData ), reinterpret_cast<void*>(m_BonesIndicesOffset) );
		glEnableVertexAttribArray( handlers[2] );
	}
      
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_Buffers[2]);
}

Draw ...
{
	glDrawElements( GL_TRIANGLES, m_uNumElements, GL_UNSIGNED_INT, 0 );
}

UnBind ...

	for ( int i = 0 ; i < size ; ++i )
		if ( handlers[i] != -1 )
			glDisableVertexAttribArray( handlers[i] );

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
	
	

 

 

0

Share this post


Link to post
Share on other sites

I got it working on GL ES 2 with VBOs, so it's definitely possible.

 

I'm not really seeing anything wrong with the CPU side code.  I guess make double sure all offsets, strides, and sizes are correct.  Make sure inside the shader the float bone indices are cast to int.

 

I'm not 100% sure since I didn't look at the generating code too carefully, but I'd recommend using interleaved VBOs where each vertex in the VBO is like (position, normal, texCoord, boneWeights, boneIndices) rather than having a block that's (position, position, position, ... texCoord, texCoord, texCoord... etc...) since this should improve cache locality when accessing VBO data in the shader.

 

And it looks like you were doing something with ELEMENT_ARRAY_BUFFER but not calling glDrawRangeElements.  Maybe you have some index buffer object but aren't using it and are instead drawing "garbage" by just drawing the straight VBO as is.  

Edited by ill
0

Share this post


Link to post
Share on other sites

And it looks like you were doing something with ELEMENT_ARRAY_BUFFER but not calling glDrawRangeElements.  

 

The OP is using glDrawElements:

glDrawElements( GL_TRIANGLES, m_uNumElements, GL_UNSIGNED_INT, 0 );


One limitation that comes to mind - particularly if using GL ES - is that you may not support 32-bit indices in hardware.  True, the worst this should so is drop you back to software emulation in the vertex pipeline, but that's assuming a good conformant driver.  May be worth switching to GL_UNSIGNED_SHORT with 16-bit indices all the same.

0

Share this post


Link to post
Share on other sites

Oh that's right, I'm so used to seeing glDrawRangeElements that I automatically assumed he wasn't using IBO when I saw that call.

 

Yeah another thing on hardware is indices have to be 16 bit.  I had a horrible mistake where I did make it use 16 bit indices since it would otherwise result in INVALID_ENUM but I didn't make the array itself be an array of 16 bit indices.  The PC version of my engine was using 32 bit indices and I didn't change my mesh loading code to account for that at the time and spent about 3 days wondering why my meshes weren't rendering right.  So be sure it's an array of 16 bit indices CPU side before uploading it as well or the data will be complete garbage.

 

Now both my PC and mobile engines use 16 bit indices and it's all good.

0

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  
Followers 0