DrawText : Need a full working example
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 21/07/2012 at 11:54, xxxxxxxx wrote:
This is apparently an issue in the way a Tag's "Draw()" routine is called vs other plugin types (Generator, Tool, etc). If a Tag's Draw() routine alters the BaseDraw Matrix (ie. bd->SetMatrix_Screen()), then it needs to set it back (example code from all other plugin types don't do this)...
... DrawText("Hello World", 256, 256, bd); //Draw text on the screen at x,y position 256,256 //--------------------------------------------------------------------------------------- // There appears to be a difference (bug?) in the behavior of a (expression) Tag that // alters the BaseDraw Matrix (ie. bd->SetMatrix_Screen()) vs. how other objects // (Generators, Tools, etc.) that alter it when drawing into the viewport... // // If a (expression) Tag alters the matrix, it needs to set it back to what it was before // returning (examples of other object/plugin types don't do this). //--------------------------------------------------------------------------------------- bd->SetMatrix_Matrix(op, bh->GetMg()); ...
...I'm not sure if the above is exactly the correct matrix to use, but it seems to work.
Note that this is only an issue when OpenGL is enabled - this seems to be the same issue that Rui is having with his plugin.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 21/07/2012 at 12:16, xxxxxxxx wrote:
Thank you.
That fixed the invisible faces problem.Any ideas on how to make the text show in front of the object?
I'm thinking maybe: bd->SetMatrix_Screen(); is not the correct thing to use?I also vaguely remember reading something Matthias posted about using BaseDraw inside of the handles method to get a different result. Possibly related to visibility. But I can't remember the specifics.
Not sure if that has anything to do with this problem.
This whole drawing subject needs to be much better documented. I hope Yannick is working on it.-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 21/07/2012 at 12:24, xxxxxxxx wrote:
I hadn't looked into the depth issue yet (except to note that it does display in front of the object it's attached to - if that's the selected object).
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 21/07/2012 at 12:59, xxxxxxxx wrote:
That's strange.
In the example I posted + your addition. The text is always a background type object and gets hidden by any object in the scene. No matter what's selected.I'm using R12 to test this. Not sure if that makes any difference.
I still need to convert it to R13. Because R13 does not have a TextHeight() function anymore.
Not sure if anything else has been changed between R12 & R13 for BD.-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 21/07/2012 at 13:25, xxxxxxxx wrote:
Yeah, may be a difference in versions. BTW, look for GetTextHeight(), instead.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 08:22, xxxxxxxx wrote:
This seems to be rather a question about BaseDraw::DrawTexture. My old DrawText routine was just one (and probably the easiest) way to draw text through the GeClipMap class.
I'll have to check how this works in the current release. Sorry, can't check for older versions than R13.
cheers,
Matthias -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 08:33, xxxxxxxx wrote:
R13 is fine Matthias.
I will be forcing myself to dump R12 entirely when R14 comes out. Even if I hate working in it.Your old code works pretty darn well for me(with Giblet's addition). With the small problem that the text is always a background object instead of a foreground object.
That's really the only problem that I would like to see solved.-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 27/08/2012 at 11:26, xxxxxxxx wrote:
Hurray!!
I figured out a way to make this darned thing work!!
It turns out that the bitmap text object getting covered by objects in the scene is an OpenGL bug(or limitation). And it only works properly on a very few select video cards.
But I found a way to force it to work with all video cards.The trick:
There needs to be a dummy 2D object(with no length) listed in the code first.
Then the you can add GeClipMap() objects like the bitmap text object. And they no longer get covered up by that OpenGL error.Here's an example from a tag based plugin with a switch to turn GeClipMap() text objects on/off:
Bool SimpleTag::Draw(BaseTag *tag, BaseObject *op, BaseDraw *bd, BaseDrawHelp *bh ) { //bd = doc->GetActiveBaseDraw(); //This is not needed because BaseDraw is already created in the parenths //if(bd) return FALSE; if(tag->GetData().GetBool(MYBOX)) //If the 'MYBOX' checkbox attribute is enabled { //There is an OpenGL problem with most video cards that makes the drawn object get covered up by objects in the scene //This is a work around to deal with that problem //We need to draw a dummy 2D object first...Then draw the actual object we want to see as a 2D HUD object bd->SetMatrix_Screen(); //Use the screen's matrix to draw on bd->DrawLine2D(Vector(0, 0, 0), Vector(0, 0, 0)); //Draw a line with a zero length<---This is our dummy object bd->SetDepth(TRUE); //This fixes drawing problems when using 2D functions //Now we can create the text HUD object that we want to see in the view AutoAlloc<GeClipMap> cm; //Create an instance of the GeClipMap class if(!cm) return FALSE; String text = "Hello World"; //The text that we will see in the HUD cm->Init(0, 0, 32); //Initializes the GeClipMap class to use this variable(cm) as 32 bit cm->BeginDraw(); //Start drawing the object. This must be used before drawing the text LONG width = cm->GetTextWidth(text); //Gets the width of the text LONG height = cm->GetTextHeight(); //Gets the width of the text cm->EndDraw(); //Tell C4D we're done drawing the text cm->Destroy(); //Release any memory used by the GeClipMap class cm->Init(width, height, 32); cm->BeginDraw(); cm->SetColor(255, 255, 255, 255); //Sets the color of the text to white cm->TextAt(0,0,text); cm->EndDraw(); bd->SetMatrix_Screen(); //We always need a matrix to draw things...In this case we'll use the screen's matrix bd->SetLightList(BDRAW_SETLIGHTLIST_NOLIGHTS); //Use other options for different results if desired //Now we create the four vector variables that will determine the Size&Shape of the text we're drawing //NOTE: We're creating a four point plane that has a text image on it...Not text created with a bunch of vectors Vector *padr = bNew Vector[4]; Vector *cadr = bNew Vector[4]; Vector *vnadr = bNew Vector[4]; Vector *uvadr = bNew Vector[4]; LONG xpos=255; //The X screen location of the left upper corner of the plane object the text bitmap is on LONG ypos=255; //The Y screen location of the left upper corner of the plane object the text bitmap is on //Now we set the actual vector postions for the four point plane object that holds the text bitmap padr[0] = Vector(xpos,ypos,0); padr[1] = Vector(xpos+width,ypos,0); padr[2] = Vector(xpos+width,ypos+height,0); padr[3] = Vector(xpos,ypos+height,0); //Now we set the color vector values for the plane object //We set it to white because we'll be using an alpha on it later on cadr[0] = Vector(1,1,1); cadr[1] = Vector(1,1,1); cadr[2] = Vector(1,1,1); cadr[3] = Vector(1,1,1); //Now we set up the normals directions for the four point plane object that holds the text bitmap vnadr[0] = Vector(0,0,1); vnadr[1] = Vector(0,0,1); vnadr[2] = Vector(0,0,1); vnadr[3] = Vector(0,0,1); //Now we set up the UV's for the four point plane object that holds the text bitmap uvadr[0] = Vector(0,0,0); uvadr[1] = Vector(1,0,0); uvadr[2] = Vector(1,1,0); uvadr[3] = Vector(0,1,0); BaseBitmap *cmbmp = NULL; cmbmp = cm->GetBitmap(); //Get the bitmap we're using and assign it to a variable(cmbmp) if(!cmbmp) return FALSE; BaseBitmap *bmp = NULL; bmp = cmbmp->GetClone(); //Get a copy of that bitmap variable so we can create an alpha version of it if(!bmp) return FALSE; BaseBitmap *alpha = NULL; alpha = bmp->GetInternalChannel(); //Get at the RGBA channels of the bitmap copy if(!alpha) alpha = bmp->AddChannel(TRUE, FALSE); //Makes the copy an alpha type of bitmap if(!alpha) { BaseBitmap::Free(bmp); return FALSE; } //Apply the alpha bitmap to the solution so only the text is visible on the screen LONG x,y; for(y=0; y<height; y++) { for(x=0; x<width; x++) { UWORD r; bmp->GetPixel(x,y,&r,&r,&r); bmp->SetAlphaPixel(alpha, x, y, r); //r is the opacity } } bd->DrawTexture(bmp,padr,cadr,vnadr,uvadr,4,DRAW_ALPHA_NORMAL,DRAW_TEXTUREFLAGS_0); //Does that actual drawing of the bitmap to the screen BaseBitmap::Free(bmp); //Free any memory used by BaseBitmap bDelete(padr); bDelete(cadr); //Delete all the empty pointers bDelete(vnadr); bDelete(uvadr); //2D drawing functions disable the Z buffer making object's in the scene half invisible //There are two ways to fix this: bd->SetDepth(TRUE); //This fixes the OpenGL problem //bd->SetMatrix_Matrix(op, bh->GetMg(),5); //This also fixes the OpenGL problem } return TRUE; }
@Matthias,
I would like to post a working example plugin of this on my website.
Do you mind if I post an example that uses some of your code you've posted here?
I'll give you credit in the source files.-ScottA
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 20/11/2012 at 01:06, xxxxxxxx wrote:
I know this thread is old, but I wanted to add that you may also use a SceneHook for drawing your 2D stuff.
The problem does not occur then.I wrote an article on the C4Dprogramming blog about that:
http://c4dprogramming.wordpress.com/2012/11/15/2d-drawing-using-a-scenehook/The example plugin in the article keeps it simple by just drawing 2D circles, but all I wrote there also applies to drawing text.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 20/11/2012 at 08:37, xxxxxxxx wrote:
Thanks for posting this.
Most of the time when I draw something on the screen I want it to always show up regardless of what's selected in the scene. So I will probably continue to use my Dummy2D object rather than create a whole new scene hook. It's much quicker and simpler.
But it's nice to know that a scene hook will give use more control over it.I still think this is a bug. And we should be able to set the Z-depth values in our code to force 2D objects to the front of the screen without it causing other drawing problems.
-ScottA