Game Development Community

Upside Down Rendering Issues

by Demolishun · in Torque 3D Professional · 02/23/2013 (10:26 pm) · 3 replies

I am doing some custom RTT stuff and I cannot figure out how to properly create a set of matrices that work with the existing draw functions in GFX->getDrawUtils(). Here is what I am working on:
GFXTexHandle tmpTexHandle = mTextureBuffer.getPointer();

      RectI viewport(0,0,tmpTexHandle->getWidth(),tmpTexHandle->getHeight());

      // Save previous render settings.
      // This preserves transforms and restores 
      // them when this object goes out of scope.
      GFXTransformSaver transSaver;
      GFXFrustumSaver frustSaver;

      // grab a copy of all matrices for doing 3D rtt
      MatrixF worldMatrix = GFX->getWorldMatrix();
      MatrixF viewMatrix = GFX->getViewMatrix();
      MatrixF projectionMatrix = GFX->getProjectionMatrix();
                 
      
      // prepare render texture
      GFXTextureTargetRef mGFXTextureTarget;
      mGFXTextureTarget = GFX->allocRenderToTextureTarget();        
      mGFXTextureTarget->attachTexture(GFXTextureTarget::Color0,tmpTexHandle);
      // save render target and set new render target
      GFX->pushActiveRenderTarget();      
      GFX->setActiveRenderTarget(mGFXTextureTarget);

      //GFX->setViewport( viewport ); // this is done in setActiveRenderTarget
      //GFX->setClipRect(viewport); 

      // setup frustrum
      F32 left, right, top, bottom;
      F32 fnear = -0.001f;
      F32 ffar = 10.0f;
      // handy dandy tool!
      MathUtils::makeFrustum( &left, &right, &top, &bottom, M_HALFPI_F, 1.0f, fnear );      
      GFX->setFrustum( left, right, bottom, top, fnear, ffar);  
      //MatrixF outMat;      
      //     
       
      // this is set for 2D rendering just like in GUI canvas      
      GFX->setProjectionMatrix(MatrixF::Identity);
      GFX->setViewMatrix(MatrixF::Identity);  
      GFX->setWorldMatrix(MatrixF::Identity);  
      //MatrixF invView(true);
      //GFX->setWorldMatrix(invView);
      //invView.inverse();
      //GFX->setViewMatrix(invView);

      
      

      // set ortho for 2D?  
      /*
      MatrixF outMat;
      MathUtils::makeOrthoProjection(&outMat,-1.0f,-1.0f,1.0f,1.0f,0.1f,-10.0f,false);
      GFX->setOrtho(-1.0f,-1.0f,1.0f,1.0f,0.1f,-10.0f);
      GFX->setProjectionMatrix(outMat);       
      */       

      // setup more crap
      if(GFX->isFrustumOrtho())
         GFX->clear(GFXClearTarget/*|GFXClearZBuffer*/,ColorI(0,64,0),1.0f,0);
      else
         GFX->clear(GFXClearTarget/*|GFXClearZBuffer*/,ColorI(0,0,64),1.0f,0);
      
      GFX->setStateBlock( mNormalSB );

      // gui preparation for rendering
      //GFX->setClipRect(viewport);
      
      GFX->setupGenericShaders( GFXDevice::GSModColorTexture );       

      // draw background      
      GFX->getDrawUtil()->setBitmapModulation(ColorI(255,255,255));            
                
      // lets use the warning texture for stuff that needs a texture
      //GFX->setTexture(0, mWarningTexture);      

      // debug draw the frustum
      GFX->getDrawUtil()->drawFrustum(GFX->getFrustum(),ColorI(255,0,0));

      // drawing a line
      GFX->getDrawUtil()->drawLine(Point2F(-1.0f,0.0f),Point2F(1.0f,0.0f),ColorI(255,255,255));             

      GFXTransformSaver trans2DSaver2;

      // do 3D render
      MatrixF outMat(true);      
      MathUtils::makeProjection(&outMat,M_HALFPI_F,1.0f,fnear,ffar,true);      
      outMat.setColumn( 3, Point3F(0.0f,0.0f,0.0f) );
      GFX->setProjectionMatrix(outMat);
      /*
      Point4F tmpP;
      tmpP = viewMatrix.getColumn4F(0);
      Con::printf("0 %.2f,%.2f,%.2f,%.2f",tmpP.x,tmpP.y,tmpP.z,tmpP.w);
      tmpP = viewMatrix.getColumn4F(1);
      Con::printf("1 %.2f,%.2f,%.2f,%.2f",tmpP.x,tmpP.y,tmpP.z,tmpP.w);
      tmpP = viewMatrix.getColumn4F(2);
      Con::printf("2 %.2f,%.2f,%.2f,%.2f",tmpP.x,tmpP.y,tmpP.z,tmpP.w);
      tmpP = viewMatrix.getColumn4F(3);
      Con::printf("3 %.2f,%.2f,%.2f,%.2f",tmpP.x,tmpP.y,tmpP.z,tmpP.w);
      */
      viewMatrix.identity();
      GFX->setWorldMatrix(outMat.inverse());
      //viewMatrix.setPosition(Point3F(0.0f,0.0f,-1.0f));
      //viewMatrix.
      //viewMatrix.setRow(4,Point3F(0.0f,0.0f,-1.0f));
      
      GFX->setViewMatrix(viewMatrix);      
      //GFX->setWorldMatrix(outMat.inverse());
      

      //GFX->getDrawUtil()->drawText(mFont, Point2I(-5,-5), "Ooh, text...");
      
      MatrixF newtrans = GFX->getWorldMatrix();
      newtrans = newtrans.set(EulerF(0.0f,mRotParm2,0.0f));  
      //newtrans.setColumn(3, ); 
      newtrans.setPosition(Point3F(0.0f,0.0f,mRotParm3+10.0f));
      //GFX->setWorldMatrix(MatrixF::Identity);
      GFX->multWorld(newtrans);  
      //MatrixF vm = GFX->getWorldMatrix();
      //GFX->setViewMatrix(vm.inverse());
      
      F32 colorMod = mRotParm3/10.0f*128;
      GFX->getDrawUtil()->setBitmapModulation(ColorI(255+colorMod,255+colorMod,255+colorMod));
      GFX->setTexture(0,mWarningTexture);
      draw2DSquare(Point3F(0.0f,0.0f,0.0f),1.5f,0.0f);//mRotParm2); 

      trans2DSaver2.restore();

      // write some text      
      GFX->disableShaders();
      viewMatrix = GFX->getViewMatrix();
      viewMatrix.scale(0.03f);
      GFX->setViewMatrix(viewMatrix);
      GFX->getDrawUtil()->drawText(mFont, Point2I(0,0), "Ooh, text...",0,255,0.0f);     

      // resolve texture
      mGFXTextureTarget->resolve();
            
      // restore render target settings
      GFX->popActiveRenderTarget();

The problem is the text is upside down (so is some of the other rendering, but I am not showing the function I made that is based upon a draw util function.) I cannot figure out how to properly build the matrices.

If I try calling setClipRect() I cannot get anything to show up right. I know this is a fundamental lack of understanding how things are put together in T3D. I did find an article that talked about how DX9 works, but it does not match 1:1 the T3D implementation: zophusx.byethost11.com/tutorial.php?lan=dx9&num=8

I think I am making progress, but I want to figure out why the upside down thing is occurring.

About the author

I love programming, I love programming things that go click, whirr, boom. For organized T3D Links visit: http://demolishun.com/?page_id=67


#1
02/25/2013 (8:11 am)
<bump>
Has anyone done custom rendering using GUI drawing functions outside of the GuiControls?
#2
03/01/2013 (1:51 am)
I don't have my code in front of me or anything, but I was working on rendering guis to material surfaces(with the intention of doing stuff like 3d scopes). I got so far as getting GUIs to render to a material of choice, but I encountered the same behavior as you, where the rendered gui element was upside-down in respect to the material uv's.
I ended up having to put it on the back-burner for other codestuffs and haven't had a chance to revisit it, but it definitely looks like it does something kinda weird with the gui/material orientations.
#3
03/01/2013 (9:48 am)
Here is how to setup matrices for GUI drawing function rendering (the way GUI controls set them up):
// setup for render to texture done before now

      // this may or may not be necessary, remember to preserve the old frustum
      // setup frustrum
      F32 left, right, top, bottom;
      F32 fnear = -0.001f;
      F32 ffar = 1000.0f;
      
      MathUtils::makeFrustum( &left, &right, &top, &bottom, M_HALFPI_F, 1.0f, fnear );      
      
      GFX->setFrustum( left, right, bottom, top, fnear, ffar);

      ...
   
      // make sure to preserve what you change and restore when done
      GFX->setClipRect(viewport);
      GFX->setViewMatrix(MatrixF::Identity);
      // the world matrix is already set by setClipRect

      // draw GUI functions here like drawText

      // resolve rtt stuff here

I actually do a mixture of perspective and GUI rendering in my test widget. I will do a quick cleanup on that code and get that released as a resource.