Sign in to follow this  
transformation

[.net] MDX - Can't get a friggin triangle to show.

Recommended Posts

I'm having problems getting a triangle on screen. I'm going crazy trying to figure out why it's not showing. Any help would be so appreciated. Here's my render function:
public int c = 0;
void Render()
{
    c++;

    Device.Transform.Projection = Dx.Matrix.PerspectiveFovLH( 
        (float)Math.PI / 4.0f, 
        TerrainPanel.Width / TerrainPanel.Height, 
        1.0f, 
        100.0f 
        );

    Device.Transform.View = Dx.Matrix.LookAtLH(
        new Dx.Vector3( 0, 0, -5.0f ), 
        new Dx.Vector3( 0, 0, 0 ),
        new Dx.Vector3( 0, 1, 0 )
        );

    Device.Transform.World = Dx.Matrix.Identity;

    Device.RenderState.Lighting = false;
    Device.RenderState.CullMode = D3d.Cull.None;

    Device.Clear( 
        D3d.ClearFlags.Target | D3d.ClearFlags.ZBuffer, 
        c, 
        1.0f, 
        0 
        );

    D3d.CustomVertex.PositionColored[] verts = new D3d.CustomVertex.PositionColored[3];

    verts[0].Position = new Dx.Vector3( 0.0f, 1.0f, 1.0f );
    verts[0].Color = System.Drawing.Color.White.ToArgb();

    verts[1].Position = new Dx.Vector3( -1.0f, -1.0f, 1.0f );
    verts[1].Color = System.Drawing.Color.White.ToArgb();

    verts[2].Position = new Dx.Vector3( 1.0f, -1.0f, 1.0f );
    verts[2].Color = System.Drawing.Color.White.ToArgb();

    Device.BeginScene();
    
    Device.VertexFormat = D3d.CustomVertex.PositionColored.Format;
    Device.DrawUserPrimitives( D3d.PrimitiveType.TriangleList, 1, verts );

    Device.EndScene();
    Device.Present();
}

And here's how I initialize d3d:
public void Initialize()
{
    PresentParams = new D3d.PresentParameters();

    PresentParams.Windowed = true;
    PresentParams.SwapEffect = D3d.SwapEffect.Discard;
    PresentParams.AutoDepthStencilFormat = D3d.DepthFormat.D16;
    PresentParams.EnableAutoDepthStencil = true;

    Device = new D3d.Device( 0, D3d.DeviceType.Hardware, TerrainPanel, 
        D3d.CreateFlags.SoftwareVertexProcessing, PresentParams );
}

I'm rendering into a panel control. I know the rendering is going fine because my back buffer color is changing continuously. But why isn't my triangle showing? Am I blind~?!?!

Share this post


Link to post
Share on other sites
Nope; you're not blind. They really aren't showing up. ;) I took a try at it, but also got no success. I've managed to get TransformColored vertices to work in the past, however:


void Render()
{
d3d.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
d3d.BeginScene();

d3d.VertexFormat = CustomVertex.TransformedColored.Format;

CustomVertex.TransformedColored[] verts = new CustomVertex.TransformedColored[3];
verts[0] = new CustomVertex.TransformedColored(
Width/2, Height/4, 0.5f, 1, Color.Blue.ToArgb());
verts[1] = new CustomVertex.TransformedColored(
Width*3/4, Height*3/4, 0.5f, 1, Color.Green.ToArgb());
verts[2] = new CustomVertex.TransformedColored(
Width/4, Height*3/4, 0.5f, 1, Color.Red.ToArgb());

d3d.VertexFormat = CustomVertex.TransformedColored.Format;
d3d.DrawUserPrimitives(PrimitiveType.TriangleList, 1, verts);

d3d.EndScene();
d3d.Present();
}




Hopefully it's of some use to you. :/

Share this post


Link to post
Share on other sites
I haven't looked over your code, but a common reason why polys don't display is becausee you defined the vertices in the right order. Back face culling is turned on by default, and the "front" and "back" of the polygon are defined by the order in which you specify the vertices.

Check this page out for more information.

Share this post


Link to post
Share on other sites
HopeDagger: That works, but still can't get the 3D to work.

I can't figure out what's wrong. I've been using the c++ d3d api for like the past 3+ years or something, and this would be like a 2 minute job if I were in a c++ environment. I'm freaking out right now.


capn_midnight:

back face culling is off (it's there in the code)

Share this post


Link to post
Share on other sites
So I took your code, and I was able to get it to work without any trouble. I've removed some of the aliasing of namespacing that you used. I've pasted the relevant code. Note that I did this using C# 2.0. I assume you're using 1.1, and have tried to remove the 2.0 specific stuff, so you may have to remove some using stuff.


using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

namespace GraphicsTest
{
public class Form1 : Form
{
Device device;
public int c = 0;
public Form1()
{
this.Setstyle(Controlstyles.AllPaintingInWmPaint | Controlstyles.Opaque, true);
InitializeComponent();
}

public void Initialize()
{
PresentParameters presentParams = new PresentParameters();

presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.AutoDepthStencilFormat = DepthFormat.D16;
presentParams.EnableAutoDepthStencil = true;

device = new Device(0, DeviceType.Hardware, this,
CreateFlags.SoftwareVertexProcessing, presentParams);
}

public void Render()
{
c++;

device.Transform.Projection = Matrix.PerspectiveFovLH(
(float)Math.PI / 4.0f,
this.Width / this.Height,
1.0f,
100.0f
);

device.Transform.View = Matrix.LookAtLH(
new Vector3(0, 0, -5.0f),
new Vector3(0, 0, 0),
new Vector3(0, 1, 0)
);

device.Transform.World = Matrix.Identity;

device.RenderState.Lighting = false;
device.RenderState.CullMode = Cull.None;

device.Clear(
ClearFlags.Target | ClearFlags.ZBuffer,
c,
1.0f,
0
);

CustomVertex.PositionColored[] verts = new CustomVertex.PositionColored[3];

verts[0].Position = new Vector3(0.0f, 1.0f, 1.0f);
verts[0].Color = System.Drawing.Color.White.ToArgb();

verts[1].Position = new Vector3(-1.0f, -1.0f, 1.0f);
verts[1].Color = System.Drawing.Color.White.ToArgb();

verts[2].Position = new Vector3(1.0f, -1.0f, 1.0f);
verts[2].Color = System.Drawing.Color.White.ToArgb();

device.BeginScene();

device.VertexFormat = CustomVertex.PositionColored.Format;
device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, verts);

device.EndScene();
device.Present();
}
}
}


And of course, the lovely main method. Since your code looks fine, I'm going to guess that the problem is in the main method.

using System;
using System.Windows.Forms;

namespace GraphicsTest
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualstyles();
Form1 f = new Form1();
f.Initialize();
f.Show();
while(f.Created)
{
Application.DoEvents();
f.Render();
}
}
}
}

Share this post


Link to post
Share on other sites
Thanks for giving it a go nickwinters. How could the main method cause a triangle not to show? I'm rendering into a panel control so my main is a bit different, and so is my main loop - which is not inside the main function.

Let me try rendering to the form and see if that works.

*checks*

Ok, if I render directly to the main form itself, the triangle shows. But if I swithc back to rendering in the panel, the triangle ceases to show. So now what? My Main looks like this:


static void Main()
{
using( MainForm form = new MainForm() )
{
form.Initialize();
form.Show();
Application.Run(form);
}
}


and I have this line in my MainForm constructor:

Application.Idle += new EventHandler( this.Application_Idle );

and my Application_Idle function looks like this:


protected virtual void Application_Idle( object sender, EventArgs e )
{
while( AppStillIdle )
{
Render();
}
}

protected virtual bool AppStillIdle
{
get
{
Message msg;
return !PeekMessage(out msg, IntPtr.Zero, 0, 0, 0);
}
}

[StructLayout(LayoutKind.Sequential)]
protected struct Message
{
public IntPtr hWnd;
public int msg;
public IntPtr wParam;
public IntPtr lParam;
public uint time;
public System.Drawing.Point p;
}

[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("User32.dll", CharSet=CharSet.Auto)]
protected static extern bool PeekMessage(out Message msg, IntPtr hWnd, uint messageFilterMin, uint messageFilterMax, uint flags);

Share this post


Link to post
Share on other sites
So ya, Tom Miller has said that's the "proper" way to do rendering loops and whatnot. I haven't found any problems with the earlier ways in his books, and have been unable to get the newer ways to compile, but if you can get it to work, go for it.

So now I've only changed one line of code, the creation of the device to

device = new Device(0, DeviceType.Hardware, panel1,
CreateFlags.SoftwareVertexProcessing, presentParams);

where panel1 is the name of the panel. It works fine. The background of the form outside the panel is no longer rendered, but to get that working, I just commented out

this.Setstyle(Controlstyles.AllPaintingInWmPaint | Controlstyles.Opaque, true);

-Nick

Share this post


Link to post
Share on other sites
Ok, I tried all that and nothing works. I think I've found the problem though. I resized my panel and then the rendering worked. It seems that certain panel sizes work and others do not. The following works:

472, 437
304, 240
248, 152
240, 240
300, 300

The following do not:

288, 320
112, 304
112, 152

If the width and height of the panel are equal, then the triangle renders. If the width is greather then the height then also the triangle renders. But if the height is greater then the width, the triangle doesn't show.

Is this weird? Is there a solution? Is this normal behavior?

Share this post


Link to post
Share on other sites
Just a stab in the dark here:

If TerrainPanel.Width and TerrainPanel.Height are integers, then when you divide them in the perspective matrix call, they are divided as integers. So, if the height is greater than the width, the result will be 0, which probably screws up the matrix enough to make it not work.

Try this instead:
(float)TerrainPanel.Width / (float)TerrainPanel.Height

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this