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:
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.
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
#2
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.
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
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.
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 hereI 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.
Torque Owner Demolishun
DemolishunConsulting Rocks!
Has anyone done custom rendering using GUI drawing functions outside of the GuiControls?