I have been going through tutorials trying to simple draw a quad apply a texture and then rotate the quad. It was bad enough just finding tutorials to draw a quad, the sdk examples jump from drawing a triangle to drawing a cylinder !
Anyway! I set up my quad and am using index buffering to display my triangle strip. I managed to get a quad up an apply a texture, eventually. My problem now is I can't figure out how to apply any transformations. Everything i do has no effect. I expect it is something pretty dumb, it's been a lot of fun moving to managed direct x so I hoping I progress a bit futher with it. Perhaps I am making things a little hard for myself using index buffering but it made more sense to me creating a quad using 4 vertexes.
I am using managed direct x 9 and C#.
As you can see i robbed the sdk tutorial code for the transformation part. I actually tried altering tutorial 3 ("Direct3D Tutorial 3 - Matrices") of the SDK examples to just add my quad but then that just displays a blank screen.
I hope it isnt a problem posting all my code, i was worried that it might be a problem with the way i am setting up the app.
Cheers for any help at all!
code:
using System;using System.Drawing;using System.Windows.Forms;using Microsoft.DirectX;using Microsoft.DirectX.Direct3D;namespace Augur{ public class Entry : Form{ // Global variables for this project Device device = null; // Rendering device VertexBuffer vertexBuffer = null; IndexBuffer indexBuffer = null; Texture texture = null; PresentParameters presentParams = new PresentParameters(); CustomVertex.TransformedTextured[] verts = null; public Entry(){ // Set the initial size of our form this.ClientSize = new System.Drawing.Size(400,600); // And it's caption this.Text = "Augur";} // Application entry point static void Main(){ using (Entry frm = new Entry()){ if(!frm.InitGraphics()){ MessageBox.Show("Could not initialise Direct3D."); return;} frm.Show(); // While the form is still valid, render and process messages while(frm.Created){ frm.Render(); Application.DoEvents();} } } private bool InitGraphics(){ // // Initialise Graphics Window // try{ PresentParameters presentParams = new PresentParameters();presentParams.Windowed= true; // We don't want to run fullscreenpresentParams.SwapEffect = SwapEffect.Discard; // Discard the framespresentParams.EnableAutoDepthStencil = true; // Turn on a Depth stencilpresentParams.AutoDepthStencilFormat = DepthFormat.D16; // And the stencil formatdevice = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams); //Create a devicedevice.DeviceReset += new System.EventHandler(this.OnResetDevice); this.OnCreateDevice(device, null); this.OnResetDevice(device, null); return true;} catch (DirectXException){ return false;} } public void OnCreateDevice(object sender, EventArgs e){ Device dev = (Device)sender; // Now Create the VBvertexBuffer = new VertexBuffer(typeof(CustomVertex.TransformedTextured), 4, dev, Usage.WriteOnly, CustomVertex.TransformedTextured.Format, Pool.Default);vertexBuffer.Created += new System.EventHandler(this.OnCreateVertexBuffer); this.OnCreateVertexBuffer(vertexBuffer, null);} public void OnResetDevice(object sender, EventArgs e){ Device dev = (Device)sender; // Turn off culling, so we see the front and back of the triangledev.RenderState.CullMode = Cull.None; // Turn off D3D lightingdev.RenderState.Lighting = false; // Turn on the ZBufferdev.RenderState.ZBufferEnable = true; //load texturetexture = TextureLoader.FromFile(dev, Application.StartupPath + @"\..\..\gfx\ship1.bmp");} public void OnCreateVertexBuffer(object sender, EventArgs e){ verts = new CustomVertex.TransformedTextured[4];verts[0] = new CustomVertex.TransformedTextured(100.0f, 200.0f, 1.0f, 1, 0.0f, 0.0f);verts[1] = new CustomVertex.TransformedTextured(150.0f, 200.0f, 1.0f, 1, 1.0f, 0.0f);verts[2] = new CustomVertex.TransformedTextured(100.0f, 250.0f, 1.0f, 1, 0.0f, 1.0f);verts[3] = new CustomVertex.TransformedTextured(150.0f, 250.0f, 1.0f, 1, 1.0f, 1.0f); // Fill index buffer ushort[] indices = { 0, 1, 2, 3 };indexBuffer = new IndexBuffer(typeof(ushort), 4, device, Usage.WriteOnly, Pool.Managed);indexBuffer.SetData(indices, 0, 0); } private void SetupMatrices(){ // For our world matrix, we will just rotate the object about the y-axis. // Set up the rotation matrix to generate 1 full rotation (2*PI radians) // every 1000 ms. To avoid the loss of precision inherent in very high // floating point numbers, the system time is modulated by the rotation // period before conversion to a radian angle. int iTime = Environment.TickCount % 1000; float fAngle = iTime * (2.0f * (float)Math.PI) / 1000.0f;device.Transform.World = Matrix.RotationY(fAngle); // Set up our view matrix. A view matrix can be defined given an eye point, // a point to lookat, and a direction for which way is up. Here, we set the // eye five units back along the z-axis and up three units, look at the // origin, and define "up" to be in the y-direction.device.Transform.View = Matrix.LookAtLH(new Vector3(0.0f, 3.0f, -5.0f), new Vector3(0.0f, 0.0f, 10.0f), new Vector3(0.0f, 1.0f, 0.0f)); // For the projection matrix, we set up a perspective transform (which // transforms geometry from 3D view space to 2D viewport space, with // a perspective divide making objects smaller in the distance). To build // a perpsective transform, we need the field of view (1/4 pi is common), // the aspect ratio, and the near and far clipping planes (which define at // what distances geometry should be no longer be rendered).device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, 1.0f, 1.0f, 5000.0f);} private void InitializeComponent(){ this.SuspendLayout(); // // Entry // this.ClientSize = new System.Drawing.Size(292, 266); this.Name = "Entry"; this.Load += new System.EventHandler(this.Entry_Load); this.ResumeLayout(false);} protected override void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e){ if ((int)(byte)e.KeyChar == (int)System.Windows.Forms.Keys.Escape) this.Close(); // Esc was pressed} protected override void OnPaint(System.Windows.Forms.PaintEventArgs e){ this.Render(); // Render on painting} //render scene private void Render(){ //if (device == null) return; //Clear the backbuffer to a blue colordevice.Clear( ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.Blue, 1.0f, 0);device.VertexFormat = CustomVertex.TransformedTextured.Format; //Begin the scenedevice.BeginScene(); SetupMatrices(); device.SetTexture(0, texture); SetupMatrices(); // Rendering of scene objects can happen herevertexBuffer.SetData(verts, 0, 0); device.SetStreamSource( 0, vertexBuffer, 0); device.Indices = indexBuffer; device.DrawIndexedPrimitives( PrimitiveType.TriangleStrip, 0, 0, 4, 0, 2); //End the scenedevice.EndScene(); device.Present(); } private void Entry_Load(object sender, EventArgs e){ } } } |

Cant get transformations working.
The Enforcer
Damn, that's really dumb in hindsight..
This is what I am liking about managed directx though. I can spend more time understanding the actual graphical concepts rather than worrying and getting confused by the code like I did when i was coding in C++.
Thanks a lot! :D
edit: Yay! it works :D
Mike Dimmick
It basically takes a triangle and spins it.
Some of the code looks like this.
Setting up the triangle
CustomVertex.PositionColored[] triangle = new CustomVertex.PositionColored[3];
triangle[0] = new CustomVertex.PositionColored(-1.0f, 0.0f, 0.0f, Color.Red.ToArgb());
triangle[1] = new CustomVertex.PositionColored(-1.0f, 2.0f, 0.0f, Color.Blue.ToArgb());
triangle[2] = new CustomVertex.PositionColored( 1.0f, 0.0f, 0.0f, Color.Yellow.ToArgb());
vb = new VertexBuffer(typeof(CustomVertex.PositionColored), 3, renderer.Device, Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Managed);
vb.SetData(triangle, 0, LockFlags.None);
And then rendering it will look like this.
Rendering
Device.Transform.World = Matrix.Translation(0.0f, 0.0f, 0.0f) * Matrix.RotationX(angle);
Device.SetStreamSource(0, vb, 0);
Device.VertexFormat = CustomVertex.PositionColored.Format; Device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 1);
I hope this helps.
Take care.
Don Griest
Let's pretend that someone else has the exact same problem but with the unmanaged C++ version.
Why doesn't this rotate or do anything! Note: I cut out all the stuff from the framework that I didn't touch.
#include
"DXUT.h"#include
"resource.h"//TODO: Comment this out to start as a D3D9 app
#define
STARTWITHD3D10namespace
D3D10{
ID3D10DepthStencilView *g_pDSV = NULL;
ID3D10Texture2D* g_pDepthStencil = NULL;
};
CEnumDeviceInfo g_deviceInfo;
IDirect3DVertexBuffer9 *g_pVB = NULL;
struct
CUSTOMVERTEX{
float x, y, z, rhw;DWORD color;
};
#define
D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)CUSTOMVERTEX vertices[] =
{
{ 150.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, },
{ 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
{ 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },
};
// Forward Declarations
BOOL GameInit();
BOOL GameShutdown();
void
UpdateMatrices(IDirect3DDevice9 *);//--------------------------------------------------------------------------------------
// Render the scene
//--------------------------------------------------------------------------------------
void
CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ){
HRESULT hr;
// Clear the render target and the zbufferV( pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 45, 50, 170), 1.0f, 0) );
// Render the scene if( SUCCEEDED( pd3dDevice->BeginScene() ) ){
UpdateMatrices(pd3dDevice);
pd3dDevice->SetStreamSource(0, g_pVB, 0,
sizeof(CUSTOMVERTEX));pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
V( pd3dDevice->EndScene() );
pd3dDevice->Present(NULL, NULL, NULL, NULL);
}
}
//--------------------------------------------------------------------------------------
// Handle messages to the application
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
bool* pbNoFurtherProcessing, void* pUserContext ){
switch(uMsg){
case WM_COMMAND: switch(LOWORD(wParam)){
case ID_FILE_EXIT:PostQuitMessage(0);
return 0;}
return 0;}
void
UpdateMatrices(IDirect3DDevice9 *pD3DDevice){
// For our world matrix, we will just rotate the object about the y-axis.D3DXMATRIXA16 matWorld;
// Set up the rotation matrix to generate 1 full rotation (2*PI radians) // every 1000 ms. To avoid the loss of precision inherent in very high // floating point numbers, the system time is modulated by the rotation // period before conversion to a radian angle.UINT iTime = timeGetTime() % 1000;
FLOAT fAngle = (
float)iTime * (2.0f * D3DX_PI) / 1000.0f;D3DXMatrixRotationY( &matWorld, fAngle );
pD3DDevice->SetTransform( D3DTS_WORLD, &matWorld );
// Set up our view matrix. A view matrix can be defined given an eye point, // a point to lookat, and a direction for which way is up. Here, we set the // eye five units back along the z-axis and up three units, look at the // origin, and define "up" to be in the y-direction.D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
pD3DDevice->SetTransform( D3DTS_VIEW, &matView );
// For the projection matrix, we set up a perspective transform (which // transforms geometry from 3D view space to 2D viewport space, with // a perspective divide making objects smaller in the distance). To build // a perpsective transform, we need the field of view (1/4 pi is common), // the aspect ratio, and the near and far clipping planes (which define at // what distances geometry should be no longer be rendered).D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4.0f, 1.0f, 1.0f, 100.0f );
pD3DDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
BOOL GameInit()
{
IDirect3DDevice9 *g_pD3DDevice = NULL;
g_pD3DDevice = DXUTGetD3D9Device();
// Turn off culling, so we see the front and back of the triangleg_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
// Turn off D3D lighting, since we are providing our own vertex colorsg_pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
if(g_pD3DDevice == NULL) return E_FAIL; if( FAILED( g_pD3DDevice->CreateVertexBuffer(3 * sizeof(CUSTOMVERTEX),0,
D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT,
&g_pVB,
NULL )))
return E_FAIL;VOID *pVertices;
if( FAILED( g_pVB->Lock(0, sizeof(vertices), (void**)&pVertices, 0))) return E_FAIL;memcpy(pVertices, vertices,
sizeof(vertices));g_pVB->Unlock();
SAFE_RELEASE(g_pD3DDevice);
PrintError(L
"Game Inititalized."); return TRUE;}
//--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR,
int ){
// Enable run-time memory check for debug builds.#if
defined(DEBUG) | defined(_DEBUG)_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
//g_deviceInfo = new CEnumDeviceInfo; // Set the d3d9 callback functionsDXUTSetCallbackD3D9DeviceCreated( OnD3D9CreateDevice );
DXUTSetCallbackD3D9DeviceReset( OnD3D9ResetDevice );
DXUTSetCallbackD3D9DeviceLost( OnD3D9LostDevice );
DXUTSetCallbackD3D9DeviceDestroyed( OnD3D9DestroyDevice );
DXUTSetCallbackD3D9FrameRender( OnD3D9FrameRender );
DXUTSetCallbackD3D9DeviceAcceptable( IsD3D9DeviceAcceptable );
// Set the d3d10 callback functions#ifdef
STARTWITHD3D10DXUTSetCallbackD3D10DeviceAcceptable( IsD3D10DeviceAcceptable );
DXUTSetCallbackD3D10DeviceCreated( OnD3D10CreateDevice );
DXUTSetCallbackD3D10SwapChainResized( OnD3D10ResizedSwapChain );
DXUTSetCallbackD3D10SwapChainReleasing( OnD3D10ReleasingSwapChain );
DXUTSetCallbackD3D10DeviceDestroyed( OnD3D10DestroyDevice );
DXUTSetCallbackD3D10FrameRender( OnD3D10FrameRender );
#endif
DXUTSetCallbackMsgProc( MsgProc );
DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
DXUTSetCallbackFrameMove( OnFrameMove );
// TODO: Perform any application-level initialization here // Initialize DXUT and create the desired Win32 window and Direct3D device for the applicationDXUTInit(
true, true ); // Parse the command line, and show msgboxes on errorDXUTSetCursorSettings(
true, true ); // Show the cursor and clip it when in full screenDXUTCreateWindow( L
"DirectX Project",NULL,
NULL,
LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1)));
DXUTCreateDevice(
true, 640, 480 );GameInit();
// Start the render loopDXUTMainLoop();
// TODO: Perform any application-level cleanup here return DXUTGetExitCode();}