lidingo
asked on
draw text in 3d world (pref c# other ok)
I would like to know how to draw text in a 3d world using directX. I use c# so i would like samples in c# code but if not possible other languages will be ok as long as i can translate easily.
I dont wont any 2d drawing samples! I´ve already seen them, but i cant find any 3d samples?
For example, i want to have a spinning cube and on every side i want to show the seconds since the program started or just the time right now. As long as its text thats changing.
In the long run i will be able to change the text fast so creating an image eveytime doesnt seem fast enough..
Is there an easy way to use drawtext using a position as x,y,z ?
You know what i mean :)
Thanks!
I dont wont any 2d drawing samples! I´ve already seen them, but i cant find any 3d samples?
For example, i want to have a spinning cube and on every side i want to show the seconds since the program started or just the time right now. As long as its text thats changing.
In the long run i will be able to change the text fast so creating an image eveytime doesnt seem fast enough..
Is there an easy way to use drawtext using a position as x,y,z ?
You know what i mean :)
Thanks!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Since it seems like this is the only solution i will give you the points.
Thanks for the help.
/Dj
Thanks for the help.
/Dj
Here is an example of doing this in a slightly different way. It eliminates the need for so many textures. This method only needs one. It also uses DrawText to update a texture then applies that single texture to the cube.
It is fromTom Miller's book on Managed DirectX. He has a chapter on Rendering to surfaces and another on 2d & 3d text. http://www.amazon.com/Managed-DirectX-Kick-Start-Programming/dp/0672325969/sr=1-1/qid=1161696045/ref=sr_1_1/104-8413604-7171909?ie=UTF8&s=books
I combined some sample code from each chapter and threw in a cube & an incrementer and here is the code. It assumes you have a mesh called "cubeExample1a.x" 2 folders up from the debug folder. Also, don't forget to add all the appropriate references (the directX ones). Let me know if you need any explainations of the code.
Although it may sound slow to you it does display faster than you are able to read it.
If you have trouble running it, I can upload the project file to ee-stuff.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D ;
namespace Chapter10Code
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private Device device = null;
private Mesh mesh = null;
private Material[] meshMaterials;
private Texture[] meshTextures;
private Texture renderTexture = null;
private Surface renderSurface = null;
private RenderToSurface rts = null;
private const int RenderSurfaceSize = 128;
System.Drawing.Font myFont = new System.Drawing.Font("Arial ", 36.0f, FontStyle.Bold);
private Microsoft.DirectX.Direct3D .Font my3DFont = null;
private string TexText;
private int increment = 1;
private int value = 0;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Cont ainer components = null;
private float angle = 0.0f;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
this.SetStyle(ControlStyle s.AllPaint ingInWmPai nt | ControlStyles.Opaque, true);
}
/// <summary>
/// We will initialize our graphics device here
/// </summary>
public void InitializeGraphics()
{
// Set our presentation parameters
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.AutoDepthSte ncilFormat = DepthFormat.D16;
presentParams.EnableAutoDe pthStencil = true;
// Create our device
device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertex Processing , presentParams);
device.DeviceReset +=new EventHandler(OnDeviceReset );
OnDeviceReset(device, null);
my3DFont = new Microsoft.DirectX.Direct3D .Font(devi ce,myFont) ;
// Load our mesh
LoadMesh(@"..\..\cubeExamp le1a.x");
}
private void OnDeviceReset(object sender, EventArgs e)
{
Device dev = (Device)sender;
if (dev.DeviceCaps.VertexProc essingCaps .SupportsD irectional Lights)
{
uint maxLights = (uint)dev.DeviceCaps.MaxAc tiveLights ;
if (maxLights > 0)
{
dev.Lights[0].Type = LightType.Directional;
dev.Lights[0].Diffuse = Color.White;
dev.Lights[0].Direction = new Vector3(0, -1, -1);
//dev.Lights[0].Commit();
dev.Lights[0].Enabled = true;
}
if (maxLights > 1)
{
dev.Lights[1].Type = LightType.Directional;
dev.Lights[1].Diffuse = Color.White;
dev.Lights[1].Direction = new Vector3(0, -1, 1);
//dev.Lights[1].Commit();
dev.Lights[1].Enabled = true;
}
}
rts = new RenderToSurface(dev, RenderSurfaceSize, RenderSurfaceSize,
Format.X8R8G8B8, true, DepthFormat.D16);
renderTexture = new Texture(dev, RenderSurfaceSize, RenderSurfaceSize, 1,
Usage.RenderTarget, Format.X8R8G8B8, Pool.Default);
renderSurface = renderTexture.GetSurfaceLe vel(0);
}
private void LoadMesh(string file)
{
ExtendedMaterial[] mtrl;
// Load our mesh
mesh = Mesh.FromFile(file, MeshFlags.Managed, device, out mtrl);
// If we have any materials, store them
if ((mtrl != null) && (mtrl.Length > 0))
{
meshMaterials = new Material[mtrl.Length];
meshTextures = new Texture[mtrl.Length];
// Store each material and texture
for (int i = 0; i < mtrl.Length; i++)
{
meshMaterials[i] = mtrl[i].Material3D;
if ((mtrl[i].TextureFilename != null) && (mtrl[i].TextureFilename != string.Empty))
{
// We have a texture, try to load it
meshTextures[i] = TextureLoader.FromFile(dev ice, @"..\..\" + mtrl[i].TextureFilename);
}
}
}
}
private void SetupCamera()
{
device.Transform.Projectio n = Matrix.PerspectiveFovLH((f loat)Math. PI / 4, this.Width / this.Height, 1.0f, 10000.0f);
device.Transform.View = Matrix.LookAtLH(new Vector3(0,0, 580.0f), new Vector3(), new Vector3(0,1,0));
}
private void RenderIntoSurface()
{
// Render to this surface
Viewport view = new Viewport();
view.Width = RenderSurfaceSize;
view.Height = RenderSurfaceSize;
view.MaxZ = 1.0f;
rts.BeginScene(renderSurfa ce, view);
device.Clear(ClearFlags.Ta rget | ClearFlags.ZBuffer, Color.DarkBlue, 1.0f, 0);
device.Transform.Projectio n = Matrix.PerspectiveFovLH((f loat)Math. PI / 4,
this.Width / this.Height, 1.0f, 10000.0f);
device.Transform.View = Matrix.LookAtLH(new Vector3(0,0, -580.0f),
new Vector3(), new Vector3(0, 1,0));
// DrawMesh(angle / (float)Math.PI, angle / (float)Math.PI * 2.0f,
// angle / (float)Math.PI / 4.0f, 0.0f, 0.0f, 0.0f);
// DrawMesh(angle / (float)Math.PI, angle / (float)Math.PI / 2.0f,
// angle / (float)Math.PI * 4.0f, 150.0f, -100.0f, 175.0f);
value = value + increment;
TexText = Convert.ToString(value);
if (value > 990) { value = 0; }
my3DFont.DrawText(null, TexText, 5, 5, Color.Red);
rts.EndScene(Filter.None);
}
protected override void OnPaint(System.Windows.For ms.PaintEv entArgs e)
{
RenderIntoSurface();
device.Clear(ClearFlags.Ta rget | ClearFlags.ZBuffer, Color.CornflowerBlue, 1.0f, 0);
SetupCamera();
device.BeginScene();
// Draw our Mesh
DrawMesh(angle / (float)Math.PI, angle / (float)Math.PI * 2.0f,
angle / (float)Math.PI / 4.0f, 0.0f, 0.0f, 0.0f);
using (Sprite s = new Sprite(device))
{
s.Begin(SpriteFlags.None);
s.Draw(renderTexture, new Rectangle(0, 0, RenderSurfaceSize, RenderSurfaceSize),
new Vector3(0, 0, 0), new Vector3(0, 0, 1.0f), Color.White);
s.End();
}
device.EndScene();
device.Present();
this.Invalidate();
}
private void DrawMesh(float yaw, float pitch, float roll, float x, float y, float z)
{
angle += 0.01f;
device.Transform.World = Matrix.RotationYawPitchRol l(yaw, pitch, roll) * Matrix.Translation(x, y, z);
for (int i = 0; i < meshMaterials.Length; i++)
{
device.Material = meshMaterials[i];
device.SetTexture(0, renderTexture);
mesh.DrawSubset(i);
}
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Cont ainer();
this.Size = new Size(800,600);
this.Text = "Form1";
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
using (Form1 frm = new Form1())
{
// Show our form and initialize our graphics engine
frm.Show();
frm.InitializeGraphics();
Application.Run(frm);
}
}
}
}
It is fromTom Miller's book on Managed DirectX. He has a chapter on Rendering to surfaces and another on 2d & 3d text. http://www.amazon.com/Managed-DirectX-Kick-Start-Programming/dp/0672325969/sr=1-1/qid=1161696045/ref=sr_1_1/104-8413604-7171909?ie=UTF8&s=books
I combined some sample code from each chapter and threw in a cube & an incrementer and here is the code. It assumes you have a mesh called "cubeExample1a.x" 2 folders up from the debug folder. Also, don't forget to add all the appropriate references (the directX ones). Let me know if you need any explainations of the code.
Although it may sound slow to you it does display faster than you are able to read it.
If you have trouble running it, I can upload the project file to ee-stuff.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D
namespace Chapter10Code
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private Device device = null;
private Mesh mesh = null;
private Material[] meshMaterials;
private Texture[] meshTextures;
private Texture renderTexture = null;
private Surface renderSurface = null;
private RenderToSurface rts = null;
private const int RenderSurfaceSize = 128;
System.Drawing.Font myFont = new System.Drawing.Font("Arial
private Microsoft.DirectX.Direct3D
private string TexText;
private int increment = 1;
private int value = 0;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Cont
private float angle = 0.0f;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
this.SetStyle(ControlStyle
}
/// <summary>
/// We will initialize our graphics device here
/// </summary>
public void InitializeGraphics()
{
// Set our presentation parameters
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.AutoDepthSte
presentParams.EnableAutoDe
// Create our device
device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertex
device.DeviceReset +=new EventHandler(OnDeviceReset
OnDeviceReset(device, null);
my3DFont = new Microsoft.DirectX.Direct3D
// Load our mesh
LoadMesh(@"..\..\cubeExamp
}
private void OnDeviceReset(object sender, EventArgs e)
{
Device dev = (Device)sender;
if (dev.DeviceCaps.VertexProc
{
uint maxLights = (uint)dev.DeviceCaps.MaxAc
if (maxLights > 0)
{
dev.Lights[0].Type = LightType.Directional;
dev.Lights[0].Diffuse = Color.White;
dev.Lights[0].Direction = new Vector3(0, -1, -1);
//dev.Lights[0].Commit();
dev.Lights[0].Enabled = true;
}
if (maxLights > 1)
{
dev.Lights[1].Type = LightType.Directional;
dev.Lights[1].Diffuse = Color.White;
dev.Lights[1].Direction = new Vector3(0, -1, 1);
//dev.Lights[1].Commit();
dev.Lights[1].Enabled = true;
}
}
rts = new RenderToSurface(dev, RenderSurfaceSize, RenderSurfaceSize,
Format.X8R8G8B8, true, DepthFormat.D16);
renderTexture = new Texture(dev, RenderSurfaceSize, RenderSurfaceSize, 1,
Usage.RenderTarget, Format.X8R8G8B8, Pool.Default);
renderSurface = renderTexture.GetSurfaceLe
}
private void LoadMesh(string file)
{
ExtendedMaterial[] mtrl;
// Load our mesh
mesh = Mesh.FromFile(file, MeshFlags.Managed, device, out mtrl);
// If we have any materials, store them
if ((mtrl != null) && (mtrl.Length > 0))
{
meshMaterials = new Material[mtrl.Length];
meshTextures = new Texture[mtrl.Length];
// Store each material and texture
for (int i = 0; i < mtrl.Length; i++)
{
meshMaterials[i] = mtrl[i].Material3D;
if ((mtrl[i].TextureFilename != null) && (mtrl[i].TextureFilename != string.Empty))
{
// We have a texture, try to load it
meshTextures[i] = TextureLoader.FromFile(dev
}
}
}
}
private void SetupCamera()
{
device.Transform.Projectio
device.Transform.View = Matrix.LookAtLH(new Vector3(0,0, 580.0f), new Vector3(), new Vector3(0,1,0));
}
private void RenderIntoSurface()
{
// Render to this surface
Viewport view = new Viewport();
view.Width = RenderSurfaceSize;
view.Height = RenderSurfaceSize;
view.MaxZ = 1.0f;
rts.BeginScene(renderSurfa
device.Clear(ClearFlags.Ta
device.Transform.Projectio
this.Width / this.Height, 1.0f, 10000.0f);
device.Transform.View = Matrix.LookAtLH(new Vector3(0,0, -580.0f),
new Vector3(), new Vector3(0, 1,0));
// DrawMesh(angle / (float)Math.PI, angle / (float)Math.PI * 2.0f,
// angle / (float)Math.PI / 4.0f, 0.0f, 0.0f, 0.0f);
// DrawMesh(angle / (float)Math.PI, angle / (float)Math.PI / 2.0f,
// angle / (float)Math.PI * 4.0f, 150.0f, -100.0f, 175.0f);
value = value + increment;
TexText = Convert.ToString(value);
if (value > 990) { value = 0; }
my3DFont.DrawText(null, TexText, 5, 5, Color.Red);
rts.EndScene(Filter.None);
}
protected override void OnPaint(System.Windows.For
{
RenderIntoSurface();
device.Clear(ClearFlags.Ta
SetupCamera();
device.BeginScene();
// Draw our Mesh
DrawMesh(angle / (float)Math.PI, angle / (float)Math.PI * 2.0f,
angle / (float)Math.PI / 4.0f, 0.0f, 0.0f, 0.0f);
using (Sprite s = new Sprite(device))
{
s.Begin(SpriteFlags.None);
s.Draw(renderTexture, new Rectangle(0, 0, RenderSurfaceSize, RenderSurfaceSize),
new Vector3(0, 0, 0), new Vector3(0, 0, 1.0f), Color.White);
s.End();
}
device.EndScene();
device.Present();
this.Invalidate();
}
private void DrawMesh(float yaw, float pitch, float roll, float x, float y, float z)
{
angle += 0.01f;
device.Transform.World = Matrix.RotationYawPitchRol
for (int i = 0; i < meshMaterials.Length; i++)
{
device.Material = meshMaterials[i];
device.SetTexture(0, renderTexture);
mesh.DrawSubset(i);
}
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Cont
this.Size = new Size(800,600);
this.Text = "Form1";
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
using (Form1 frm = new Form1())
{
// Show our form and initialize our graphics engine
frm.Show();
frm.InitializeGraphics();
Application.Run(frm);
}
}
}
}
ASKER
Hi again.
Thanks a lot for your help!
The problem still is that its using drawtext in 2d.
In the end i want the cube to be able to spin and the number to keep incrementing during the spin.
Lets say i want to show two sides of the cube and want to see both sides with there own incrementing numbers.
Starting to think i have to make my own drawtext function :(
If you should think of anything i would really appreciate it!
Thanks for your help!
/Dj
Thanks a lot for your help!
The problem still is that its using drawtext in 2d.
In the end i want the cube to be able to spin and the number to keep incrementing during the spin.
Lets say i want to show two sides of the cube and want to see both sides with there own incrementing numbers.
Starting to think i have to make my own drawtext function :(
If you should think of anything i would really appreciate it!
Thanks for your help!
/Dj
ASKER
The problem is i want to have several numbers and i want them to change from the values sent to them by a socket and they will sometimes change very fast. It doesnt seem like a good way to have a texture for every digit and then change them.
But if thats the only solution there is, its not much to do...
I will leave this for another day or two and is noone can come up with a better solution for me i will give you the points.
Thanks for your answer!
/Dj