Visual C++ .NET and DirectX, problems with DrawPrimitive

Hi. I've made a good start with Visual C++ .net express and direct3D. I have created a device and know it works, can perform some operations, however when I try to draw a simple object, say a triangle list with drawprimitive() I get this error message:

An unhandled exception of type 'System.InvalidOperationException' occurred in Microsoft.DirectX.dll

Additional information: Operation is not valid due to the current state of the object.

Here is my code, this program creates a form and DirectX device. If you comment out the drawprimtive line it works. I can change the color of the clean operation within the onpaint function and it will draw the window in red or white.

#pragma once

namespace Ruin {

using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace Microsoft::DirectX;
using namespace Microsoft::DirectX::Direct3D;

public ref class Form1 : public System::Windows::Forms::Form
{
private: Device ^device;

public:
Form1(void)
{
InitializeComponent();

// Get the ordinal for the default adapter
int adapterOrdinal = Microsoft::DirectX::Direct3D::Manager::Adapters->Default->Adapter;

//MessageBox::Show(Microsoft::DirectX::Direct3D::Manager::Adapters->Current->Adapter.ToString());

// Get our device capabilities so we can check them to set up the CreateFlags

Caps ^caps = Manager::GetDeviceCaps(adapterOrdinal, DeviceType::Hardware);
CreateFlags createFlags;

// Check the capabilities of the graphcis card is capable of
// performing the vertex-processing operations

// The HardwareVertexProcessing choice is the best

if (caps->DeviceCaps.SupportsHardwareTransformAndLight)
{
createFlags = CreateFlags::HardwareVertexProcessing;
}
else
{
createFlags = CreateFlags::SoftwareVertexProcessing;
}

// If the graphics card supports vertex processing check if the device can
// do rasterization, matrix transformations, and lighting and shading operations
// This combination provides the fastest game experience

if (caps->DeviceCaps.SupportsPureDevice && createFlags == CreateFlags::HardwareVertexProcessing)
{
createFlags = createFlags | CreateFlags::PureDevice;
}

// Set up the PresentParameters which determine how the device behaves

PresentParameters ^presentParams = gcnew PresentParameters();
presentParams->SwapEffect = SwapEffect::Discard;

// Make sure we are in windowed mode when we are debugging

//#if DEBUG
presentParams->Windowed = true;
//#endif

// Now create the device

device = gcnew Device(adapterOrdinal, DeviceType::Hardware, this, createFlags, presentParams);
this->SetStyle ( ControlStyles::AllPaintingInWmPaint|ControlStyles::Opaque, true );
//
//TODO: Add the constructor code here
//
}

protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}

private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;

#pragma 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>
void InitializeComponent(void)
{
this->SuspendLayout();
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->BackColor = System::Drawing::SystemColors::GradientActiveCaption;
this->ClientSize = System::Drawing::Size(510, 393);
this->Name = L"Form1";
this->Text = L"Ruin";
this->Paint += gcnew System::Windows::Forms::PaintEventHandler(this, &Form1::Form1_Paint);
this->ResumeLayout(false);

}
#pragma endregion

private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e) {
}

private: System::Void Form1_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) {
this->Invalidate();
device->Clear(ClearFlags::Target, Color::Red, 1.0f, 0); // changed this from black to red and works fine!
// Tell DirectX we are about to draw something
device->BeginScene();
device->VertexFormat = CustomVertex::TransformedColored::Format;
device->DrawUserPrimitives(PrimitiveType::TriangleList, 1, createVertexBuffer()); // THIS LINE CAUSES EXCEPTION
// Tell DirectX that we are done drawing
device->EndScene();
// Flip the back buffer to the front
device->Present();
}

private: array<CustomVertex::TransformedColored^> ^createVertexBuffer() {
array<CustomVertex::TransformedColored^> ^verts = gcnew array<CustomVertex::TransformedColored^>(3);

verts[0] = gcnew CustomVertex::TransformedColored(
this->Width / 2.0F, this->Height / 4.0F, 0.5F, 1.0F, Color::Blue.ToArgb());
verts[1] = gcnew CustomVertex::TransformedColored(
this->Width * 3.0F / 4.0F, this->Height * 3.0F / 4.0F, 0.5F, 1.0F, Color::Green.ToArgb());
verts[2] = gcnew CustomVertex::TransformedColored(
this->Width / 4.0F, this->Height * 3.0F / 4.0F, 0.5F, 1.0F, Color::Red.ToArgb());
return verts;
}
};
}

I looked the error up on msdn and it I think it means that somehow the device is not in the correct mode to draw that type of primitive. I've tried a few different things with that and still get the same message. I found something on the internet that says basically the same thing, however, this person tried using an index buffer and it worked. I don't know how to create an index buffer yet. I will post my findings with that. Any help would be appreciated!



Answer this question

Visual C++ .NET and DirectX, problems with DrawPrimitive

  • augustyn

    Moving the thread to the DirectX Groups, as the guys there will be able to help.



  • Visual C++ .NET and DirectX, problems with DrawPrimitive