Sign in to follow this  

VertexBuffer creation in December 2005 SDK (C#)

This topic is 4376 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having trouble with the last argument in the vertex buffer constructor. It's an "EventHandler" named "createdEvent", and when I pass my "vb_Created" method, I get an "InvalidCallException". Here's part of my code.
using System;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX.Generic;
using Microsoft.DirectX.Direct3D.CustomVertex;

class Program
{
	Device device = null;
	VertexBuffer vb = null;
	
	public void Init()
	{
		//...
		vb = new VertexBuffer(device, 4, Usage.WriteOnly, PositionColored.Format, Pool.Managed, vb_Created);
	}
	
	void vb_Created(object sender, EventArgs e)
	{
		VertexBuffer vb = (VertexBuffer)sender;
	
		PositionColored[] vertices = new PositionColored[4];
		vertices[0] = new PositionColored(-1.0f, -1.0f, 5.0f, Color.Red.ToArgb());     // 0
		vertices[1] = new PositionColored(-1.0f, 1.0f, 5.0f, Color.Blue.ToArgb());     // 1
		vertices[2] = new PositionColored(1.0f, -1.0f, 5.0f, Color.Green.ToArgb());    // 2
		vertices[3] = new PositionColored(1.0f, 1.0f, 5.0f, Color.Yellow.ToArgb());    // 3 
	
		GraphicsBuffer<PositionColored> gb = vb.Lock<PositionColored>(0, 4, LockFlags.None);
		gb.Write(vertices[0]);
		gb.Write(vertices[1]);
		gb.Write(vertices[2]);
		gb.Write(vertices[3]);
		vb.Unlock();
	}
}

Earlier versions of the SDK didn't have the "createdEvent" argument, so I'm not sure how to use it and can't find any documentation for it. Does anyone know how to set up a vertex buffer correctly in C# with the December 2005 SDK?

Share this post


Link to post
Share on other sites
You need to use:

new EventHandler(vb_Created)

As the last argument. If you start typing in new, you'll get an autocomplete thingy. Press Tab twice and it'll add a function for you :).

I actually was having problems with it, I couldn't figure out how to get the vertex buffer from the call. I ended up not using it and just adding the code right after creation :).

Share this post


Link to post
Share on other sites
It still gives me the same error. I replaced

vb = new VertexBuffer(device, 4, Usage.WriteOnly, PositionColored.Format, Pool.Managed, vb_Created);

with

vb = new VertexBuffer(device, 4, Usage.WriteOnly, PositionColored.Format, Pool.Managed, new EventHandler(vb_Created));

I also tried passing null for the event handler, but it gives the same error.

The double tabbing to auto create the code only works when I use "vb.Created +="

If you have a working example for the december sdk, maybe you can show it to me. If I could just create the vertex buffer without any events, I would. But it seems that this sdk forces me to use one.

Share this post


Link to post
Share on other sites
Quote:
Original post by Proudest
It still gives me the same error. I replaced

vb = new VertexBuffer(device, 4, Usage.WriteOnly, PositionColored.Format, Pool.Managed, vb_Created);

with

vb = new VertexBuffer(device, 4, Usage.WriteOnly, PositionColored.Format, Pool.Managed, new EventHandler(vb_Created));

I also tried passing null for the event handler, but it gives the same error.


Well, I'm no Einstein, but this sorta tells me you're doing something else wrong. I guess one of the other arguments is incorrect. I use null and it works fine.

The first possible thing I see is the size. Note this should be the size in bytes, not the size in vertices. You need to change that to 4 * sizeof(Positioned.Colored);

That's all I see right now, though I'm not sure if the WriteOnly flag is acceptable for a managed resource, though it probably is :).

Hope this helps.

Share this post


Link to post
Share on other sites
I see one problem, and that's that the second parameter to the VertexBuffer constructor needs to be the size of the buffer in bytes. Could be that it's complaining about the fact that even a single PositionColored structure takes more than 4 bytes to represent.

Share this post


Link to post
Share on other sites
There is an overload that takes the Vertex Count, but it requires that you pass the Type of the vertex in. As others have said, for that version of new you should be passing the size in bytes, or (since you seem to be using the built in vertex formats anyway) use the overload that takes the type.

Share this post


Link to post
Share on other sites
Quote:
Original post by DrunkenHyena
There is an overload that takes the Vertex Count, but it requires that you pass the Type of the vertex in. As others have said, for that version of new you should be passing the size in bytes, or (since you seem to be using the built in vertex formats anyway) use the overload that takes the type.


The overload that takes a Type argument no longer exists in MDX for .NET 2.0, which seems to be what he's using. That functionality has been replaced with the inclusion of the generic Lock<> method. I should make sure to note that the number passed into the second parameter to the generic Lock call should remain the number of elements, although if you use the non-generic version it take the size in bytes.

Share this post


Link to post
Share on other sites
You guys are right, the error occurs in the "sizeInBytes" argument. I tested it by changing the value to 16 and that line of code didn't give the error any more. Instead an error was produced when locking the vertex buffer with "numberElementsToLock" having a value of 4, because it was inconsistent with 16 bytes.

The problem is, I can't use "4 * sizeof(PositionColored)" because the compiler says "'...PositionColored' does not have a predefined size, therefore sizeof can only be used in an unsafe context".

Share this post


Link to post
Share on other sites
You can allow unsafe code by changing the appropriate setting in your project's properties (in VS2003 that's under configuration - build - set allow Unsafe code blocks to true).

Alternatively you can use System.Runtime.InteropServices.Marshal.SizeOf() to the same effect.

Share this post


Link to post
Share on other sites
Quote:
Original post by remigius
Alternatively you can use System.Runtime.InteropServices.Marshal.SizeOf() to the same effect.


Thanks, I think it will work now that I passed the sizeInBytes as

"4 * Marshal.SizeOf(new PositionColored()"

No compiler/runtime errors, I just need to attempt to render it now.

Share this post


Link to post
Share on other sites
The polygons either aren't rendering or aren't visible, I don't know why. Maybe the vertex buffer isn't being loaded from the graphics buffer correctly. Here's the relevant code:


using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using Microsoft.DirectX.Generic;
using Microsoft.DirectX.Direct3D.CustomVertex;
using System.Runtime.InteropServices;

class Program : Form
{
Device device = null;
VertexBuffer vb = null;

public void Init()
{
PresentParameters pp = new PresentParameters();
pp.IsWindowed = true;
pp.SwapEffect = SwapEffect.Discard;
pp.AutoDepthStencilFormat = DepthFormat.D16;
pp.EnableAutoDepthStencil = true;

device = new Device(0, DeviceType.Hardware, this.Handle, CreateFlags.HardwareVertexProcessing, pp);

device.Transform.World = Matrix.Identity;
device.Transform.View = Matrix.Identity;
float aspect = (float)ClientSize.Width / (float)ClientSize.Height;
device.Transform.Projection = Matrix.PerspectiveFieldOfViewLeftHanded((float)Math.PI / 3.0f, aspect, 0.1f, 1000.0f);
device.RenderState.Lighting = false;
device.RenderState.FillMode = FillMode.Solid;
device.RenderState.CullMode = Cull.None;
device.VertexFormat = PositionColored.Format;

vb = new VertexBuffer(device, 6 * Marshal.SizeOf(new PositionColored()), Usage.WriteOnly, PositionColored.Format, Pool.Managed, vb_Created);
vb.Created += new EventHandler(vb_Created);
vb_Created(vb, null);
}

void vb_Created(object sender, EventArgs e)
{
VertexBuffer vb = (VertexBuffer)sender;

PositionColored[] vertices = new PositionColored[6];
vertices[0] = new PositionColored(-1.0f, -1.0f, 5.0f, Color.Red.ToArgb());
vertices[1] = new PositionColored(-1.0f, 1.0f, 5.0f, Color.Yellow.ToArgb());
vertices[2] = new PositionColored(1.0f, -1.0f, 5.0f, Color.Green.ToArgb());
vertices[3] = new PositionColored(-1.0f, 1.0f, 5.0f, Color.Violet.ToArgb());
vertices[4] = new PositionColored(1.0f, 1.0f, 5.0f, Color.Blue.ToArgb());
vertices[5] = new PositionColored(1.0f, -1.0f, 5.0f, Color.Orange.ToArgb());

GraphicsBuffer<PositionColored> gb = vb.Lock<PositionColored>(0, 6, LockFlags.None);
gb.Write(vertices);
vb.Unlock();
}

void renderFrame()
{
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.LightBlue, 1.0f, 0);
device.BeginScene();

device.SetStreamSource(0, vb, 0);
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 2);

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




I can't find anything wrong with this code. I also don't have any comparison, because I can't find any .NET 2.0 documentation for this SDK. If anyone can test this code with .Net 2.0 and the latest SDK and help me find the problem, it would be appreciated.

Share this post


Link to post
Share on other sites
First off, I think it would be more elegant to use:
Marshal.SizeOf( typeof(PositionColored) )
...instead of passing it a new instance of the actual vertex type.

As for your triangles not rendering, it's tough to just off the top of my head judge if you've set everything you need to, but I'd suggest trying it with TransformedColored vertices first, which will give you an indication of whether the problem is with your rendering code or the way you have the transformation pipeline set up.

Share this post


Link to post
Share on other sites
Quote:
Original post by sirob

device.SetStreamSource(0, vb, 0);


That's the overload I used. Use the 4 argument overload, dunno what's wrong with this one.


I was having this same problem. But as sirob says, using the 4 argument overload works:
device.SetStreamSource( 0, vb, 0, TransformedColored.StrideSize );

Share this post


Link to post
Share on other sites
Quote:
Original post by chadmv
Quote:
Original post by sirob

device.SetStreamSource(0, vb, 0);


That's the overload I used. Use the 4 argument overload, dunno what's wrong with this one.


I was having this same problem. But as sirob says, using the 4 argument overload works:
device.SetStreamSource( 0, vb, 0, TransformedColored.StrideSize );


Thanks guys, that did the trick.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Thanks, I think it will work now that I passed the sizeInBytes as

"4 * Marshal.SizeOf(new PositionColored())"


Why not just doing :

4 * PositionColored.StrideSize;

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Quote:
Thanks, I think it will work now that I passed the sizeInBytes as

"4 * Marshal.SizeOf(new PositionColored())"


Why not just doing :

4 * PositionColored.StrideSize;


Thanks, that's probably how it was meant to be done, I haven't used stridesize before so didn't know what it was for.

Share this post


Link to post
Share on other sites

This topic is 4376 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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