Game Development Community

setBlend question

by Ian Omroth Hardingham · in Torque 3D Professional · 05/27/2010 (5:52 am) · 2 replies

I am having difficulty drawing a set of textured triangles as part of a custom 3d object.

I am calling

GFX->drawPrimitive( GFXTriangleList, 0, 2 );

And the stateblock I'm using is set up with this:

desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);

However, even completely transparent pixels of my texture are being written, overwriting the stuff behind.

If I add this to the stateBlock setup:

desc.setAlphaTest(true, GFXCmpGreater);

Then the transparent pixels do not write, which leads me to believe that either my setBlend call is false, or... well I don't know what else!

Anyone got any idea?

Thanks,
Ian

#1
05/27/2010 (6:00 am)
It gets thicker! If I call:

desc.setBlend(true, GFXBlendZero, GFXBlendOne);

Then black rectangles are produced.

I have a feeling I've set something up wrong - it appears to be taking no account of the existing background..
#2
05/27/2010 (6:05 am)
For reference, here is most of the relevant code for this object:

void Billboard::createGeometry()
{
	if (isObjectBB)
		return;

   // Fill the vertex buffer
   VertexType *pVert = NULL;

   mVertexBuffer.set( GFX, 6, GFXBufferTypeStatic );
   pVert = mVertexBuffer.lock();


	F32 halfX = mObjScale.x * 0.5;
	F32 halfZ = mObjScale.z * 0.5;


	// have to be anticlockwise

	pVert[0].point = Point3F(-halfX,0,halfZ);
	pVert[0].normal = Point3F(0,-1,0);
	pVert[0].texCoord = Point2F(0,1);

	pVert[1].point = Point3F(halfX,0,halfZ);
	pVert[1].normal = Point3F(0,-1,0);
	pVert[1].texCoord = Point2F(1,1);

	pVert[2].point = Point3F(-halfX,0,-halfZ);
	pVert[2].normal = Point3F(0,-1,0);
	pVert[2].texCoord = Point2F(0,0);

	

	pVert[3].point = Point3F(halfX,0,-halfZ);
	pVert[3].normal = Point3F(0,-1,0);
	pVert[3].texCoord = Point2F(1,0);

	pVert[4].point = Point3F(-halfX,0,-halfZ);
	pVert[4].normal = Point3F(0,-1,0);
	pVert[4].texCoord = Point2F(0,0);

	pVert[5].point = Point3F(halfX,0,halfZ);
	pVert[5].normal = Point3F(0,-1,0);
	pVert[5].texCoord = Point2F(1,1);

	


   mVertexBuffer.unlock();

   // Set up our normal and reflection StateBlocks
   GFXStateBlockDesc desc;

 
   desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha); 
   desc.samplersDefined = true;

//desc.setAlphaTest(true, GFXCmpGreater);

   desc.samplers[0] = GFXSamplerStateDesc::getClampLinear();

   // The normal StateBlock only needs a default StateBlock
   mNormalSB = GFX->createStateBlock( desc );

   // The reflection needs its culling reversed
   desc.cullDefined = true;
   desc.cullMode = GFXCullCW;
   mReflectSB = GFX->createStateBlock( desc );
}

bool Billboard::prepRenderImage( SceneState *state, const U32 stateKey, 
                                         const U32 startZone, const bool modifyBaseZoneState)
{
	if (isObjectBB)
		return false;

   // Do a little prep work if needed
   if ( mVertexBuffer.isNull() )
      createGeometry();

   // Make sure we haven't already been processed by this state
   if ( isLastState( state, stateKey ) )
      return false;

   // Update our state
   setLastState(state, stateKey);

   // If we are actually rendered then create and submit our RenderInst
   if ( state->isObjectRendered( this ) ) 
   {
      // Allocate an ObjectRenderInst so that we can submit it to the RenderPassManager
      ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();

      // Now bind our rendering function so that it will get called
      ri->renderDelegate.bind( this, &Billboard::render );

      // Set our RenderInst as a standard object render
      ri->type = RenderPassManager::RIT_Object;

      // Set our sorting keys to a default value
      ri->defaultKey = 0;
      ri->defaultKey2 = 0;

      // Submit our RenderInst to the RenderPassManager
      state->getRenderPass()->addInst( ri );
   }

   return false;
}

void Billboard::render( ObjectRenderInst *ri, SceneState *state, BaseMatInstance *overrideMat )
{
	if (isObjectBB)
		return;

	//GFX->getDrawUtil()->drawBitmapStretch(mTextureObject, RectI(0,0,200,200), GFXBitmapFlip_None, GFXTextureFilterLinear);

	// crazy
   //if ( overrideMat )
   //   return;

   if ( mVertexBuffer.isNull() )
      return;

   PROFILE_SCOPE(RenderObjectExample_Render);

   // Set up a GFX debug event (this helps with debugging rendering events in external tools)
   GFXDEBUGEVENT_SCOPE( RenderObjectExample_Render, ColorI::RED );

   // GFXTransformSaver is a handy helper class that restores
   // the current GFX matrices to their original values when
   // it goes out of scope at the end of the function
   GFXTransformSaver saver;

   // Calculate our object to world transform matrix
   MatrixF objectToWorld = getRenderTransform();
   objectToWorld.scale( getScale() );

   // Apply our object transform
   GFX->multWorld( objectToWorld );

   // Deal with reflect pass otherwise
   // set the normal StateBlock
   if ( state->isReflectPass() )
      GFX->setStateBlock( mReflectSB );
   else
      GFX->setStateBlock( mNormalSB );

   // Set up the "generic" shaders
   // These handle rendering on GFX layers that don't support
   // fixed function. Otherwise they disable shaders.


	GFXTextureObject* tex = getTextureObject();
	GFX->setTexture(0, tex);


   GFX->setupGenericShaders( GFXDevice::GSModColorTexture );

   // Set the vertex buffer
   GFX->setVertexBuffer( mVertexBuffer );



   // Draw our triangles
   GFX->drawPrimitive( GFXTriangleList, 0, 2 );

}