PDA

View Full Version : how to do model clothing & multi-model texturing.



Deepak Roy Chittajallu
11-17-2004, 12:48 PM
hello,

I have created a model of the female body. the model is made up of 3 disjoint sub-models :

- one semi superellipsoid model for each breast( left and right) which can be deformbed by varying a set of parameters of the superellipsoid.

- and one model of the underlying body without the breast taken from a vrml file on which i have manually placed the two breast models close to the body.

but the problem is u can see the gaps between the breasts and the body.

My boss asked me to cover the above mentioned 3 models with a new surface like a cloth - so that it appears like a continuous smooth surface.

for, this i got an idea - i will retrieve the depth buffer and create a surface at a little lesser depth than my model and thus the viewer will not be able to see the gaps.

I retrieved the depth buffer, but somehow my depth buffer returns 1 every where which means nothin is being written into it.also it seems to be very slow.

if you have any ideas of a method for my task, please help me.

also my texture mapping is not working well - it was giving all wierd results. even though i am replaceing GL_REPLACE. i have to apply a skin texture to all the models in combination

here is my code in windows:

void CGLModelView::OnDraw(CDC* pDC)
{
CDocument* pDoc = GetDocument();
// TODO: add draw code here

wglMakeCurrent( pDC->m_hDC , m_hGLRC );

// glClearDepth( 1.0 );

glClearColor( 0.0f , 0.0f , 0.0f , 0.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glEnable( GL_DEPTH_TEST );

glEnable( GL_LIGHTING );
glEnable( GL_LIGHT0 );

glColorMaterial( GL_FRONT_AND_BACK , GL_DIFFUSE );
glEnable( GL_COLOR_MATERIAL );

glMatrixMode( GL_MODELVIEW );
glLoadIdentity();

CRect r;
GetClientRect(&r);

int depth = -(m_intPerspectiveZFar - m_intPerspectiveZNear);

double w = r.Width() / 2.0;
double h = r.Height() / 2.0;

double g = 240.0 / 255.0;

glBegin( GL_QUADS );

glNormal3f( 0.0 , 0.0 , 1.0 );

glColor3f( g /1.5 , g / 1.5 , g );
glVertex3d( -w , h , depth );

glColor3f( g / 3 , g / 3 , g / 1.5 );
glVertex3d( w , h , depth );

glColor3f( g / 3 , g / 3 , g / 3 );
glVertex3d( w , -h , depth );

glColor3f( g / 3 , g / 3 , g / 1.5 );
glVertex3d( -w , -h , depth );

glEnd();

if( m_uViewType != VIEW_PERSPECTIVE )
{
depth = -depth;

GLdouble m[4][4] = { { w / m_dblOrthoScale , 0 , 0 , 0} , { 0 , h / m_dblOrthoScale , 0 , 0 } , { 0 , 0 , 1.0 , 0 } , { 0 , 0 , 0 , 1} };

glMultMatrixd( &m[0][0] );
}

glTranslated( m_dblXTranslation , m_dblYTranslation , m_dblZTranslation );

glRotatef( m_intXAngle , 1.0 , 0.0 , 0.0 );
glRotatef( m_intYAngle , 0.0 , 1.0 , 0.0 );
glRotatef( m_intZAngle , 0.0 , 0.0 , 1.0 );

glCallList( ID_DISPLAY_LIST_GRID );

glEnable( GL_TEXTURE_2D );

//glDisable( GL_LIGHTING );
//glDisable( GL_COLOR_MATERIAL );

glCallList( ID_MODEL_DISPLAY_LIST );

glDisable( GL_TEXTURE_2D );

glFlush();

SwapBuffers( pDC->m_hDC );

wglMakeCurrent( NULL , NULL );
}

int CGLModelView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: Add your specialized creation code here

CClientDC dc(this);

PIXELFORMATDESCRIPTOR pfd;

memset( &pfd , 0 , sizeof( PIXELFORMATDESCRIPTOR ) );

pfd.nSize = sizeof( PIXELFORMATDESCRIPTOR );
pfd.cColorBits = 24;
pfd.cRedBits = 8;
pfd.cGreenBits = 8;
pfd.cBlueBits = 8;
pfd.cDepthBits = 32;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.iLayerType = PFD_MAIN_PLANE;

int nPixelFormatIndex = ChoosePixelFormat( dc.m_hDC , &pfd );
if( nPixelFormatIndex == 0 )
{
TRACE( "Choose Pixel Format Failed %d\r\n" , GetLastError() );
return -1;
}
TRACE( "Pixel Format Found, index - %d" , nPixelFormatIndex );

BOOL blnResult = SetPixelFormat( dc.m_hDC , nPixelFormatIndex , &pfd );
if( !blnResult )
{
TRACE( "Set Pixel Format Failed,error - %d" , GetLastError() );
return -1;
}

// create a rendering context using the client dc

m_hGLRC = wglCreateContext( dc.m_hDC );

if( !m_hGLRC )
{
TRACE( "wglCreateContext failde %X\r\n" , GetLastError() );
return -1;
}

blnResult = wglMakeCurrent( dc.m_hDC , m_hGLRC );
if( !blnResult )
{
TRACE( "wglMakeCurrent failed %d" , GetLastError() );
return -1;
}

glClearColor( 0.0f , 0.0f , 0.0f , 0.0f );
glClear( GL_COLOR_BUFFER_BIT );

BuildGridDisplayList();

glGenTextures( 1 , &nGLTextureName );

glBindTexture( GL_TEXTURE_2D , nGLTextureName );

glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

BuildModelDisplayList();

wglMakeCurrent( NULL , NULL );

ReleaseDC( &dc );

SetProjectionMatrix();

return 0;
}

void CGLModelView::LoadTextureFile( CString strTextureFile )
{
CImage temp;

temp.Load( strTextureFile );

CClientDC dc(this);

wglMakeCurrent( dc.m_hDC , m_hGLRC );

GLint internalformat = temp.GetBPP() / 8;

GLenum fmt;

if( temp.IsIndexed() )
fmt = GL_COLOR_INDEX;
else
{
switch( internalformat )
{
case 3:

fmt = GL_RGB;
break;

case 4:

fmt = GL_RGBA;
break;

default :
MessageBox( "Error Loading Texture File into video memory : Invalid format" );
return;
}

}

glTexImage2D( GL_TEXTURE_2D , 0 , internalformat , temp.GetWidth() , temp.GetHeight() , 0 , fmt , GL_UNSIGNED_BYTE , temp.GetBits() );

wglMakeCurrent( NULL , NULL );

temp.Detach();
Invalidate(true);
}

void CGLModelView::BuildModelDisplayList()
{
glNewList(ID_MODEL_DISPLAY_LIST , GL_COMPILE );

glBegin( GL_QUADS );

glNormal3f( 0.0 , 0.0 , 1.0 );

glTexCoord2f( 0.0 , 0.0 );
glColor3f( 1.0 , 0.0 , 0.0 );
glVertex3f( -3.0 , -3.0 , 0.0 );

glTexCoord2f( 1.0 , 0.0 );
glColor3f( 0.0 , 1.0 , 0.0 );
glVertex3f( 3.0 , -3.0 , 0.0 );

glTexCoord2f( 1.0 , 1.0 );
glColor3f( 0.0 , 0.0 , 1.0 );
glVertex3f( 3.0 , 3.0 , 0.0 );

glTexCoord2f( 0.0 , 1.0 );
glColor3f( 0.0 , 1.0 , 0.0 );
glVertex3f( -3.0 , 3.0 , 0.0 );

glEnd();

glEndList();
}
please help me - i am still pretty much mediocre in opengl though i am good at programming.

please help me with this task .... its really urgent.

Deepak Roy chittajallu
cdeepakroy@yahoo.com

jwatte
11-17-2004, 08:04 PM
What you need is to hire an artist to make a useable model for you. Or just go to a site like turbosquid.com and buy a ready-made model. Or buy something cheap from a contracting house like New Pencil.

MikeC
11-18-2004, 10:45 AM
What you also need is to stop posting the exact same question in multiple forums (http://www.opengl.org/discussion_boards/cgi_directory/ultimatebb.cgi?ubb=recent_user_posts;u=00014970) . Double-posting is bad. Quadruple-posting is downright rude.

Aeluned
11-19-2004, 01:58 PM
My boss asked me to do something...
here is all my code....
it's urgent....
fix it...

you've got to be joking.

we're all thrilled that you're good at programming.

Korval
11-19-2004, 03:08 PM
You're asking to do full cloth modelling on an arbitrary surface. This is not something that gets done in the "urgent" timeframe. Plus, it has very little to do with OpenGL itself; the real problem is one of physics and collision detection.

I'd go with Jwatte's suggestion: get an artists. Programmers shouldn't be making character models.

Deepak Roy Chittajallu
11-19-2004, 04:16 PM
well!

keeping aside all the criticism i had to face...well i wrote a few things bad....i shouldnt have put all the code in.....shouldnt have posted the same question in multiple rooms....to all those i caused inconvenience i sencerely apologize......i am extremely sorry

let me put the qustion this way

i have got a 3D model - vrml file - of the female body wihtout breasts( flat surface near breast) - and i have mathematically modelled the female breast using a deformable model which is gonna be used in computer aided breast reconstructive surgery. the mathematical model has a few parameters changing which would deform the breast surface in various ways. the problem is i have manually set the origins of the mathematical breast models to be close to the 3D vrml female torso model. but whatever u do, u can see that the models are decoupled. so inorder to mask it and make the visualization look nice, i have to model a cloth surface over the 3 models so it appears as a single continuous surface.

note: the outer cloth surface should also deform accordingly whenever the change of mathematical model parameters changes the breast surface shape underneath.

yes i understand that this is a physics problem.

i went over a few clothing techniques on the interent and a few journals - but in all those places the clothing takes into accout gravity and all the other factors. but in my case my objective is different - i just wanna hide the gaps. if i take all the physical factors into account it will slow down my application further.

jwatte
11-19-2004, 07:26 PM
You still need an artist; it doesn't matter what your application is.

For example, the artist could mark which vertices in the mesh would correspond to the breast area, and your exporter would export the indices of these breasts. Your physics would then read in this information, and place the vertices at the right place. Render using the regular triangle list, and you have a whole, seamless, mesh.

That's how any shipping product I know about (including ours, which features body shape adjustments), does it.

If you find that the mathematical model is not controllable or realistic enough, you could have the artist model a bunch of different extremes as morph targets on the original mesh, and then export the mesh + the morph targets, and blend between those targets based on parameters. That's usually a lot easier to get looking realistic than a fully procedural morph.

If for some reason you absolutely cannot involve a professional whose job it is to know and model human anatomy (i e, a character artist), then I would cut out a hole in the flat area of the VRML model using a modeling tool, and make sure that the procedural breasts also had a hole on the back, with as many edges along the hole edges on each. Then I would match up each vertex on an edge loop to the closest un-matched vertex on the other model. I'd calculate the average distance between each of the matched pairs, and offset the breasts by that much; then I'd weld the vertex pairs to their pairwise positions.

I hope you understand "weld" and "edge loop" and "morph target" -- if not, I suggest you find a good primer on 3d character modeling, although sadly I don't know of any title to recommend.