Game Development Community

Creating 3D faces

by siba · in Torque 3D Beginner · 10/04/2012 (9:10 am) · 8 replies

Does Torque 3D have some built-in way for me to create 3D faces, in this case with 4 vertices connecting, along with coloring each vertex and texturing?

I'd like to make a 3rd party program for the game "Blockland" that comes with an easier way to create bricks for it

#1
10/04/2012 (9:23 am)
Well, yes kinnda.. Do you mean from code?
I made an object that can render tubes at any length and at any resolution given. You have direct access to the vertex buffer so you can just put anything you would like in it.
#2
10/04/2012 (9:29 am)
Moved to T3D Beginner.
#3
10/04/2012 (9:57 am)
Appologies, I was not able to find any "help" topic so I just went into my past help topics

@Lukas, thats the code I require
#4
10/04/2012 (12:02 pm)
Well I'll post it here then.
I have a helper function:
void Ribbon::initGFXResources()
{
   //if(smVertexBuffer != NULL)
      //return;
      
   GFXStateBlockDesc d;
   d.cullDefined = true;
   d.cullMode = GFXCullNone;
   d.fillMode = GFXFillSolid;
   
   smStateBlock = GFX->createStateBlock(d);

   smVertexBuffer.set(GFX, numOfArrows*resolution, GFXBufferTypeStatic);
   GFXVertexPC* verts = smVertexBuffer.lock();
   for(int i = 0; i < numOfArrows; i++)
   {
	   for(int resI = 0; resI < resolution; resI++)
	   {
		   F32 x = cos((360/(resolution)*resI)*M_PI/180);
		   F32 y = i;
		   F32 z = sin(((360/(resolution))*resI)*M_PI/180);
		   verts[resolution*i+resI].point = Point3F(x,y,z);
		   verts[resolution*i+resI].color = GFXVertexColor(ColorI(255, 255, 0, 255));
		   if( resI == 0 )
			   verts[resolution*i+resI].color = GFXVertexColor(ColorI(255, 0, 0, 255));
		   else if( resI == 1 )
			   verts[resolution*i+resI].color = GFXVertexColor(ColorI(0, 255, 0, 255));
		   else if( resI == 2 )
			   verts[resolution*i+resI].color = GFXVertexColor(ColorI(0, 0, 255, 255));
		   else if( resI == 3 )
			   verts[resolution*i+resI].color = GFXVertexColor(ColorI(255, 0, 255, 255));
	   }
   }
   //verts[0].color = verts[1].color = verts[2].color = verts[3].color = GFXVertexColor(ColorI(0, 255, 0, 255));
   smVertexBuffer.unlock();
   
   smPrimitiveBuffer.set(GFX, (numOfArrows-1)*resolution*6, (numOfArrows-1)*resolution*2, GFXBufferTypeStatic);
   U16* prims;
   smPrimitiveBuffer.lock(&prims);
   for(int meshIndex = 0; meshIndex < (numOfArrows-1); meshIndex++)
   {
	   for(int vertIndex = 0; vertIndex < resolution; vertIndex++)
	   {
		   
		   int lowleft = meshIndex*resolution+vertIndex;
		   int lowright = meshIndex*resolution+vertIndex+1;
		   if(lowright >= (meshIndex*resolution)+resolution)
			   lowright = meshIndex*resolution;
		   int upperleft = (meshIndex+1)*resolution+vertIndex;
		   int upperright = (meshIndex+1)*resolution+vertIndex+1;
		   if(upperright >= ((meshIndex+1)*resolution)+resolution)
			   upperright = (meshIndex+1)*resolution;
		   int index = (meshIndex*resolution*6) + vertIndex*6;
		   if((lowleft == 0 || lowright == 0 || upperleft == 0 || upperright == 0) && (lowleft == 15 || lowright == 15 || upperleft == 15 || upperright == 15))
			   int a = 2;
		   prims[index+0] = lowleft;
		   prims[index+1] = lowright;
		   prims[index+2] = upperleft;

		   prims[index+3] = lowright;
		   prims[index+4] = upperright;
		   prims[index+5] = upperleft;
	   }
   }
   smPrimitiveBuffer.unlock();
}
Splitting this into two comments
#5
10/04/2012 (12:03 pm)
And then the render functions:
void Ribbon::prepRenderImage( SceneRenderState* state )
{
   // This should be sufficient for most objects that don't manage zones, and
   //  don't need to return a specialized RenderImage...
   ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
   ri->renderDelegate.bind( this, &Ribbon::renderObject );
   ri->type = RenderPassManager::RIT_Editor;
   state->getRenderPass()->addInst(ri);
}

void Ribbon::renderObject(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance* overrideMat)
{
   initGFXResources();
   numOfArrows = 5;
   resolution = 3;
   for(U32 i = 0; i < GFX->getNumSamplers(); i++)
      GFX->setTexture(i, NULL);
   GFXTransformSaver saver;
   MatrixF mat = getRenderTransform();
   mat.scale(mObjScale);
   GFX->multWorld(mat);
   GFX->setStateBlock(smStateBlock);
   GFX->setVertexBuffer(smVertexBuffer);
   GFX->setPrimitiveBuffer(smPrimitiveBuffer);
   GFX->setupGenericShaders();
   GFX->drawIndexedPrimitive(GFXTriangleList, 0, 0, smVertexBuffer->mNumVerts, 0, smPrimitiveBuffer->mIndexCount/3);
}
#6
10/04/2012 (12:06 pm)
Actually the above code should create a square if you give it a resolution of 4 and a triangle at solution of 3 (numofarrows is kindda like a segment count just treat it as 1)
Edit: Even got an image of it:
imageshack.us/a/img210/6633/screenshot01500000.png
Although the above code wont have the rendering error.
#7
10/04/2012 (12:21 pm)
Wow.....I was hoping for something like a DrawFace(PosX,PosY,PosZ); or something, I still have a long way to go

I currently only know the basic layout of Torque Script
#8
10/04/2012 (12:31 pm)
Well, that is also slightly more complicated than it needs to be because it is for tubes at any given length and resolution...
GFXStateBlockDesc d;
   d.cullDefined = true;
   d.cullMode = GFXCullNone;
   d.fillMode = GFXFillSolid;
   
   smStateBlock = GFX->createStateBlock(d);

   smVertexBuffer.set(GFX, 4, GFXBufferTypeStatic);
   GFXVertexPC* verts = smVertexBuffer.lock();
   verts[0].point = Point3F(-1,0,-1);
   verts[1].point = Point3F(-1,0,1);
   verts[2].point = Point3F(1,0,-1);
   verts[3].point = Point3F(1,0,1);
   verts[0].color = ColorI(255,255,255,255);   

   smVertexBuffer.unlock();
   
   smPrimitiveBuffer.set(GFX, 0, 2, GFXBufferTypeStatic);
   U16* prims;
   smPrimitiveBuffer.lock(&prims);
   prims[0] = verts[0];
   prims[1] = verts[1];
   prims[2] = verts[2];
   prims[3] = verts[1];
   prims[4] = verts[2];
   prims[5] = verts[3];
   smPrimitiveBuffer.unlock();

Try swapping the initGFXResources with that piece of code and see if it makes it easier to understand.

Edit: Actually, there might even be some draw primitive functions integrated somewhere already. But they would basically do the same as the above, just wrapped into a function so you don't have to look at it.