How make a DirectX app runs on Windows Forms (using C++)

Well, i'm making a simple directX application based on my studies on this book Introduction to 3D Game Programing with DirectX 9.0, the problem it's how i make the scene created runs inside a windows form to be more clear, i'm trying to render my scene inside a form but don't know how call a specific function to do that.

Another thing, the code i'm posting here create by itself a window and i know that to runs on windows form i'll need erase thoses line of code, 'cause that i needed know how do that using a windows form.

I'm using native C++ language and the code of the program i trying to run is down below.

Thanks for any help (i really need do that).


xfile.cpp

#include "d3dUtility.h"
#include <fstream>
#include <vector>

//
// Globals
//

IDirect3DDevice9* Device = 0;

const int Width = 640;
const int Height = 480;

ID3DXMesh* Mesh[4] = {0, 0, 0, 0};
D3DXMATRIX Worlds[4];

std::vector<D3DMATERIAL9> Mtrls(0);
std::vector<IDirect3DTexture9*> Textures(0);



// Classes and Structures

struct Vertex
{
Vertex(){}
Vertex(float x, float y, float z,
float nx, float ny, float nz, float u, float v)
{
_x = x; _y = y; _z = z;
_nx = nx; _ny = ny; _nz = nz;
_u = u; _v = v;
}

float _x, _y, _z, _nx, _ny, _nz, _u, _v;

static const DWORD FVF;

};
const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;

//
// Framework functions

bool Setup()
{
HRESULT hr = 0;

//
// Load the XFile data.


ID3DXBuffer* adjBuffer = 0;
ID3DXBuffer* mtrlBuffer = 0;
DWORD numMtrls = 0;
int j=0;
for(j=0; j<4; j++)
{

hr = D3DXLoadMeshFromX(
"mesh.x",
D3DXMESH_MANAGED,
Device,
&adjBuffer,
&mtrlBuffer,
0,
&numMtrls,
&Mesh[j]);

if(FAILED(hr))
{
::MessageBox(0, "D3DXLoadMeshFromX() - FAILED", 0, 0);
return false;
}

//
// Extract the materials, and load textures.


if( mtrlBuffer != 0 && numMtrls != 0 )
{
D3DXMATERIAL* mtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();

for(int i = 0; i < numMtrls; i++)
{
// the MatD3D property doesn't have an ambient value set
// when its loaded, so set it now:

mtrls[ i].MatD3D.Ambient = mtrls[ i].MatD3D.Diffuse;

// save the ith material
Mtrls.push_back( mtrls[ i].MatD3D );

// check if the ith material has an associative texture

if( mtrls[ i].pTextureFilename != 0 )
{
// yes, load the texture for the ith subset

IDirect3DTexture9* tex = 0;
D3DXCreateTextureFromFile(
Device,
mtrls[ i].pTextureFilename,
&tex);

// save the loaded texture

Textures.push_back( tex );
}
else
{
// no texture for the ith subset

Textures.push_back( 0 );
}
}
}
d3d::Release<ID3DXBuffer*>(mtrlBuffer); // done w/ buffer

//
// Optimize the mesh.


hr = Mesh[j]->OptimizeInplace(
D3DXMESHOPT_ATTRSORT |
D3DXMESHOPT_COMPACT |
D3DXMESHOPT_VERTEXCACHE,
(DWORD*)adjBuffer->GetBufferPointer(),
0, 0, 0);

d3d::Release<ID3DXBuffer*>(adjBuffer); // done w/ buffer

if(FAILED(hr))
{
::MessageBox(0, "OptimizeInplace() - FAILED", 0, 0);
return false;
}

//
// Fill in vertices

Vertex* v = 0;
Mesh[j]->LockVertexBuffer(0, (void**)&v);

Mesh[j]->UnlockVertexBuffer();

//
// Define the triangles of the box

WORD* i = 0;
Mesh[j]->LockIndexBuffer(0, (void**)&i);


Mesh[j]->UnlockIndexBuffer();

}
//
// Build world matrices - position the objects in world space.


D3DXMatrixTranslation(&Worlds[0], 0.0f, 4.0f, 0.0f);
D3DXMatrixTranslation(&Worlds[1], 0.0f, -4.0f, 0.0f);
D3DXMatrixTranslation(&Worlds[2], -4.0f, 0.0f, 0.0f);
D3DXMatrixTranslation(&Worlds[3], 4.0f, 0.0f, 0.0f);

char *v_ = 0;
Mesh[0]->LockVertexBuffer(0, (void**)&v_);
for (int i = 0; i < Mesh[0]->GetNumVertices(); i++)
{
Vertex *const vv = (Vertex *const)v_;
vv->_x -=4.0; vv->_y +=0.0; vv->_z +=0.0;
v_ += Mesh[0]->GetNumBytesPerVertex();
}
Mesh[0]->UnlockVertexBuffer();



//
// Set texture filters.
//

Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

//
// Set Lights.


D3DXVECTOR3 dir(1.0f, -1.0f, 1.0f); //direcao da luz
D3DXCOLOR col(1.0f, 1.0f, 1.0f, 1.0f);//cor da luz a incidir no Mesh
D3DLIGHT9 light = d3d::InitDirectionalLight(&dir, &col);

Device->SetLight(0, &light);
Device->LightEnable(0, true);
Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
Device->SetRenderState(D3DRS_SPECULARENABLE, true);

//
// Set camera.

D3DXVECTOR3 pos(4.0f, 4.0f, -13.0f);
D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f)
D3DXMATRIX V;
D3DXMatrixLookAtLH(
&V,
&pos,
&target,
&up);


Device->SetTransform(D3DTS_VIEW, &V);//metodo q recebe info da camera

//
// Set projection matrix.


D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(
&proj,
D3DX_PI * 0.5f, // 90 - degree
(float)Width / (float)Height,
1.0f,
1000.0f);

Device->SetTransform(D3DTS_PROJECTION, &proj);

return true;

}

void Cleanup()
{

for(int j=0; j<4; j++)
{
d3d::Release<ID3DXMesh*>(Mesh[j]);

for(int i = 0; i < Textures.size(); i++)
d3d::Release<IDirect3DTexture9*>( Textures[ i] );
}
}



bool Display(float timeDelta) // that is the function to render the scene
{
if( Device )
{
/*
//
// Update: Rotate the mesh.
//

static float y = 0.0f;
D3DXMATRIX yRot;
D3DXMatrixRotationY(&yRot, y);
y += timeDelta;

if( y >= 6.28f )
y = 0.0f;

D3DXMATRIX World = yRot;

Device->SetTransform(D3DTS_WORLD, &World);
*/
//
// Render


Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
Device->BeginScene();

for(int j=0; j<4; j++)
{
Device->SetTransform(D3DTS_WORLD, &Worlds[j]);

for(int i = 0; i < Mtrls.size(); i++)
{
Device->SetMaterial( &Mtrls[ i] ); //seta materiais
Device->SetTexture(0, Textures[ i]); //seta texturas
Mesh[j]->DrawSubset(i);
}
}

Device->EndScene();
Device->Present(0, 0, 0, 0);
}
return true;
}

//
// WndProc
//
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch( msg )
{
case WM_DESTROY:
::PostQuitMessage(0);
break;

case WM_KEYDOWN:
if( wParam == VK_ESCAPE )
::DestroyWindow(hwnd);
break;
}
return ::DefWindowProc(hwnd, msg, wParam, lParam);
}

//
// WinMain



int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE prevInstance,
PSTR cmdLine,
int showCmd)
{
if(!d3d::InitD3D(hinstance,
Width, Height, true, D3DDEVTYPE_HAL, &Device))
{
::MessageBox(0, "InitD3D() - FAILED", 0, 0);
return 0;
}

if(!Setup())
{
::MessageBox(0, "Setup() - FAILED", 0, 0);
return 0;
}

d3d::EnterMsgLoop( Display ); // that its a function created on d3dutility.h to create a window using windows API, the argumment it's display, that is used to render.
Cleanup();

Device->Release();

return 0;
}


d3dUtility.h

#ifndef __d3dUtilityH__
#define __d3dUtilityH__

#include <d3dx9.h>
#include <string>

namespace d3d
{
bool InitD3D(
HINSTANCE hInstance, // [in] Application instance.
int width, int height, // [in] Backbuffer dimensions.
bool windowed, // [in] Windowed (true)or full screen (false).
D3DDEVTYPE deviceType, // [in] HAL or REF
IDirect3DDevice9** device);// [out]The created device.

int EnterMsgLoop(
bool (*ptr_display)(float timeDelta));

LRESULT CALLBACK WndProc(
HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam);

template<class T> void Release(T t)
{
if( t )
{
t->Release();
t = 0;
}
}

template<class T> void Delete(T t)
{
if( t )
{
delete t;
t = 0;
}
}

const D3DXCOLOR WHITE( D3DCOLOR_XRGB(255, 255, 255) );
const D3DXCOLOR BLACK( D3DCOLOR_XRGB( 0, 0, 0) );
const D3DXCOLOR RED( D3DCOLOR_XRGB(255, 0, 0) );
const D3DXCOLOR GREEN( D3DCOLOR_XRGB( 0, 255, 0) );
const D3DXCOLOR BLUE( D3DCOLOR_XRGB( 0, 0, 255) );
const D3DXCOLOR YELLOW( D3DCOLOR_XRGB(255, 255, 0) );
const D3DXCOLOR CYAN( D3DCOLOR_XRGB( 0, 255, 255) );
const D3DXCOLOR MAGENTA( D3DCOLOR_XRGB(255, 0, 255) );

//
// Lights
//

D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color);
D3DLIGHT9 InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color);
D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color);

//
// Materials
//

D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p);

const D3DMATERIAL9 WHITE_MTRL = InitMtrl(WHITE, WHITE, WHITE, BLACK, 2.0f);
const D3DMATERIAL9 RED_MTRL = InitMtrl(RED, RED, RED, BLACK, 2.0f);
const D3DMATERIAL9 GREEN_MTRL = InitMtrl(GREEN, GREEN, GREEN, BLACK, 2.0f);
const D3DMATERIAL9 BLUE_MTRL = InitMtrl(BLUE, BLUE, BLUE, BLACK, 2.0f);
const D3DMATERIAL9 YELLOW_MTRL = InitMtrl(YELLOW, YELLOW, YELLOW, BLACK, 2.0f);
}

#endif // __d3dUtilityH__



The d3dUtility.cpp


#include "d3dUtility.h"

bool d3d::InitD3D(
HINSTANCE hInstance,
int width, int height,
bool windowed,
D3DDEVTYPE deviceType,
IDirect3DDevice9** device)
{
//
// Create the main application window.
//

WNDCLASS wc;

wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)d3d::WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = "Direct3D9App";

if( !RegisterClass(&wc) )
{
::MessageBox(0, "RegisterClass() - FAILED", 0, 0);
return false;
}

HWND hwnd = 0;
hwnd = ::CreateWindow("Direct3D9App", "Direct3D9App",
WS_EX_TOPMOST,
0, 0, width, height,
0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/);

if( !hwnd )
{
::MessageBox(0, "CreateWindow() - FAILED", 0, 0);
return false;
}

::ShowWindow(hwnd, SW_SHOW);
::UpdateWindow(hwnd);

//
// Init D3D:
//

HRESULT hr = 0;

// Step 1: Create the IDirect3D9 object.

IDirect3D9* d3d9 = 0;
d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

if( !d3d9 )
{
::MessageBox(0, "Direct3DCreate9() - FAILED", 0, 0);
return false;
}

// Step 2: Check for hardware vp.

D3DCAPS9 caps;
d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);

int vp = 0;
if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

// Step 3: Fill out the D3DPRESENT_PARAMETERS structure.

D3DPRESENT_PARAMETERS d3dpp;
d3dpp.BackBufferWidth = width;
d3dpp.BackBufferHeight = height;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hwnd;
d3dpp.Windowed = windowed;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.Flags = 0;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

// Step 4: Create the device.

hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT, // primary adapter
deviceType, // device type
hwnd, // window associated with device
vp, // vertex processing
&d3dpp, // present parameters
device); // return created device

if( FAILED(hr) )
{
// try again using a 16-bit depth buffer
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT,
deviceType,
hwnd,
vp,
&d3dpp,
device);

if( FAILED(hr) )
{
d3d9->Release(); // done with d3d9 object
::MessageBox(0, "CreateDevice() - FAILED", 0, 0);
return false;
}
}

d3d9->Release(); // done with d3d9 object

return true;
}

int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) )
{
MSG msg;
::ZeroMemory(&msg, sizeof(MSG));

static float lastTime = (float)timeGetTime();

while(msg.message != WM_QUIT)
{
if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
else
{
float currTime = (float)timeGetTime();
float timeDelta = (currTime - lastTime)*0.001f;

ptr_display(timeDelta);

lastTime = currTime;
}
}
return msg.wParam;
}

D3DLIGHT9 d3d::InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color)
{
D3DLIGHT9 light;
::ZeroMemory(&light, sizeof(light));

light.Type = D3DLIGHT_DIRECTIONAL;
light.Ambient = *color * 0.4f;
light.Diffuse = *color;
light.Specular = *color * 0.6f;
light.Direction = *direction;

return light;
}

D3DLIGHT9 d3d::InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color)
{
D3DLIGHT9 light;
::ZeroMemory(&light, sizeof(light));

light.Type = D3DLIGHT_POINT;
light.Ambient = *color * 0.4f;
light.Diffuse = *color;
light.Specular = *color * 0.6f;
light.Position = *position;
light.Range = 1000.0f;
light.Falloff = 1.0f;
light.Attenuation0 = 1.0f;
light.Attenuation1 = 0.0f;
light.Attenuation2 = 0.0f;

return light;
}

D3DLIGHT9 d3d::InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color)
{
D3DLIGHT9 light;
::ZeroMemory(&light, sizeof(light));

light.Type = D3DLIGHT_SPOT;
light.Ambient = *color * 0.4f;
light.Diffuse = *color;
light.Specular = *color * 0.6f;
light.Position = *position;
light.Direction = *direction;
light.Range = 1000.0f;
light.Falloff = 1.0f;
light.Attenuation0 = 1.0f;
light.Attenuation1 = 0.0f;
light.Attenuation2 = 0.0f;
light.Theta = 0.5f;
light.Phi = 0.7f;

return light;
}

D3DMATERIAL9 d3d::InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p)
{
D3DMATERIAL9 mtrl;
mtrl.Ambient = a;
mtrl.Diffuse = d;
mtrl.Specular = s;
mtrl.Emissive = e;
mtrl.Power = p;
return mtrl;
}


That is the 3 sources, i hope reading them help to someone to give me a light about what to do about the forms.


Thanks in advance


Answer this question

How make a DirectX app runs on Windows Forms (using C++)

  • VoiceOfExperience

    Sorry about double post, was not me, was my friend (he and i are making that program, he handle the windows form part and i the directx part).

    Anyway, thanks for the help

    =]


  • RizwanSharp

    Tonight (local time here at this moment is 9h23 so for you to know it still a bit till night :) ) or tomorrow I'll try to put a sample here.


  • Stephen Bowman

    Hi,
    in the creation of the device, use the form's handle as the window attribute in the present parameters structure:

    PresentParameters pp;
    pp.hDeviceWindow = (HWND)form->Handle;

    That should work. I wrote a simple tutorial it may help you:
    http://n0n4m3.gamedev-pt.net/ pag=managed_directx1&language=en


  • rodniko

    The samples I posted were made in VS .Net 2005. The project doesn't open that's strange.. I'll check it later when I get home.

    As for your second question, if you're using VS 2005 express then you need to download the windows platform sdk:
    http://www.microsoft.com/downloads/details.aspx FamilyId=E15438AC-60BE-41BD-AA14-7F1E0F19CA0D&displaylang=en




  • Ron L

    Oh, thanks, let me make some questions about the code.

    I put my code in native C++ on DXTutorial1_C++CLI_mix.cpp (the main part like my xfile.cpp code)

    I can call the includes normally on DXTutorial1_C++CLI_mix.cpp for example : include <vector.h> or something similar

    The function to render the application (the 3d part of it) it's automatically called to works on form or i need use her as an argument of some function of windows form


    And before anything sorry my noobiness and thanks for your help =]





  • Sam Fowler

    Tks n0n4m3,

    But you dont have a sample, with a form with a picture (triangule) inside, using Windows Form and C++

    A code sample for me looks.....because I haven’t experience and I’m confused.

    Tks advanced.



  • Mehdi Mahdloo

    Thanks a lot n0n4m3 =]



  • yhong

    Sorry about the delay, I've been at the beach the whole weekend without internet.. but I did your sample:
    http://n0n4m3.gamedev-pt.net/DXTutorial1_C++CLI_mix.zip

    hope it helps.


  • i7hira7

    My friend posted the wrong code hehe (that source was a test)

    The real Sources.

    Comments: I Think there something missing in code, almost certain is hwnd parameter, and another parameters to build the scene. Look carefull at InitD3D, there can be the source of the bugs (one of them).

    The problem it's 5 things i think:
    - wrong parameters in some parts (especially the WinApi ones, like hwnd)
    -the way i created the device, i think it's all right but...
    -the InitD3D function it's something linked with the WinApi part that i told above
    -Load the function to render, or the bool Display () to be more precise.
    -the place where the d3dutility.cpp d3dutility.h and xfile.cpp are placed.


    Form1.cpp

    #include "stdafx.h"
    #include "Form1.h"

    using namespace Directxtest01;

    int APIENTRY _tWinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPTSTR lpCmdLine,
    int nCmdShow)
    {
    System::Threading::Thread::CurrentThread->ApartmentState = System::Threading::ApartmentState::STA;
    Application::Run(new Form1());
    return 0;
    }

    Form1.h

    #include "xfile.cpp"
    #include "d3dUtility.h"
    #include "d3dUtility.cpp"
    #pragma once

    namespace Directxtest01
    {
    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;

    /// <summary>
    /// Summary for Form1
    ///
    /// WARNING: If you change the name of this class, you will need to change the
    /// 'Resource File Name' property for the managed resource compiler tool
    /// associated with all .resx files this class depends on. Otherwise,
    /// the designers will not be able to interact properly with localized
    /// resources associated with this form.
    /// </summary>
    public __gc class Form1 : public System::Windows::Forms::Form
    {
    public:
    Form1(void)
    {
    InitializeComponent();
    }

    protected:
    void Dispose(Boolean disposing)
    {
    if (disposing && components)
    {
    components->Dispose();
    }
    __super::Dispose(disposing);
    }
    private: System::Windows::Forms::Button * button1;

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

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    void InitializeComponent(void)
    {
    this->button1 = new System::Windows::Forms::Button();
    this->SuspendLayout();
    //
    // button1
    //
    this->button1->Location = System::Drawing::Point(176, 184);
    this->button1->Name = S"button1";
    this->button1->TabIndex = 0;
    this->button1->Text = S"button1";
    this->button1->Click += new System::EventHandler(this, button1_Click);
    //
    // Form1
    //
    this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
    this->ClientSize = System::Drawing::Size(448, 350);
    this->Controls->Add(this->button1);
    this->Name = S"Form1";
    this->Text = S"Form1";
    this->Load += new System::EventHandler(this, Form1_Load);
    this->ResumeLayout(false);

    }
    private: System::Void Form1_Load(System::Object * sender, System::EventArgs * e)
    {
    //Display();
    //Cleanup();
    //Device->Release();
    }

    private: System::Void button1_Click(System::Object * sender, System::EventArgs * e)
    {
    if(!d3d::InitD3D(hinstance,
    Width, Height, true, D3DDEVTYPE_HAL, &Device)) // there is some error here, those parameters don't looks right, please check d3dUtility to see more about that InitD3D
    {
    ::MessageBox(0, "InitD3D() - FAILED", 0, 0);

    }

    if(!Setup())
    {
    ::MessageBox(0, "Setup() - FAILED", 0, 0);

    }
    Display(); //i tried call that function to render the scene, but dont seens to work.
    Cleanup();
    Device->Release();
    }

    };
    }

    stdafx.cpp

    // stdafx.cpp : source file that includes just the standard includes
    // Directxtest01.pch will be the pre-compiled header
    // stdafx.obj will contain the pre-compiled type information

    #include "stdafx.h"


    stdafx.h

    // stdafx.h : include file for standard system include files,
    // or project specific include files that are used frequently, but
    // are changed infrequently
    #pragma once


    #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
    // C RunTime Header Files
    #include <stdlib.h>
    #include <malloc.h>
    #include <memory.h>
    #include <tchar.h>

    // TODO: reference additional headers your program requires here


    xfile.cpp

    #include "d3dUtility.h"
    #include <fstream>
    #include <vector>

    //
    // Globals
    //

    IDirect3DDevice9* Device = 0;

    const int Width = 640;
    const int Height = 480;

    ID3DXMesh* Mesh[4] = {0, 0, 0, 0};
    D3DXMATRIX Worlds[4];

    std::vector<D3DMATERIAL9> Mtrls(0);
    std::vector<IDirect3DTexture9*> Textures(0);

    // Classes and Structures

    struct Vertex
    {
    Vertex(){}
    Vertex(float x, float y, float z,
    float nx, float ny, float nz, float u, float v)
    {
    _x = x; _y = y; _z = z;
    _nx = nx; _ny = ny; _nz = nz;
    _u = u; _v = v;
    }

    float _x, _y, _z, _nx, _ny, _nz, _u, _v;

    static const DWORD FVF;

    };

    const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;

    //
    // Framework functions

    bool Setup()
    {
    HRESULT hr = 0;

    //
    // Load the XFile data.


    ID3DXBuffer* adjBuffer = 0;
    ID3DXBuffer* mtrlBuffer = 0;
    DWORD numMtrls = 0;
    int j=0;
    for(j=0; j<4; j++)
    {
    hr = D3DXLoadMeshFromX("mesh.x",
    D3DXMESH_MANAGED,
    Device,
    &adjBuffer,
    &mtrlBuffer,
    0,
    &numMtrls,
    &Mesh[j]);

    if(FAILED(hr))
    {
    ::MessageBox(0, "D3DXLoadMeshFromX() - FAILED", 0, 0);
    return false;
    }

    //
    // Extract the materials, and load textures.


    if( mtrlBuffer != 0 && numMtrls != 0 )
    {
    D3DXMATERIAL* mtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer();

    for(int i = 0; i < numMtrls; i++)
    {
    // the MatD3D property doesn't have an ambient value set
    // when its loaded, so set it now:

    mtrls[ i].MatD3D.Ambient = mtrls[ i].MatD3D.Diffuse;

    // save the ith material
    Mtrls.push_back( mtrls[ i].MatD3D );

    // check if the ith material has an associative texture

    if( mtrls[ i].pTextureFilename != 0 )
    {
    // yes, load the texture for the ith subset

    IDirect3DTexture9* tex = 0;
    D3DXCreateTextureFromFile(
    Device,
    mtrls[ i].pTextureFilename,
    &tex);

    // save the loaded texture

    Textures.push_back( tex );
    }
    else
    {
    // no texture for the ith subset

    Textures.push_back( 0 );
    }
    }
    }
    d3d::Release<ID3DXBuffer*>(mtrlBuffer); // done w/ buffer

    //
    // Optimize the mesh.


    hr = Mesh[j]->OptimizeInplace(
    D3DXMESHOPT_ATTRSORT |
    D3DXMESHOPT_COMPACT |
    D3DXMESHOPT_VERTEXCACHE,
    (DWORD*)adjBuffer->GetBufferPointer(),
    0, 0, 0);

    d3d::Release<ID3DXBuffer*>(adjBuffer); // done w/ buffer

    if(FAILED(hr))
    {
    ::MessageBox(0, "OptimizeInplace() - FAILED", 0, 0);
    return false;
    }

    //
    // Fill in vertices

    Vertex* v = 0;
    Mesh[j]->LockVertexBuffer(0, (void**)&v);

    Mesh[j]->UnlockVertexBuffer();


    WORD* i = 0;
    Mesh[j]->LockIndexBuffer(0, (void**)&i);


    Mesh[j]->UnlockIndexBuffer();

    }
    //
    // Build world matrices - position the objects in world space.


    D3DXMatrixTranslation(&Worlds[0], 0.0f, 4.0f, 0.0f);
    D3DXMatrixTranslation(&Worlds[1], 0.0f, -4.0f, 0.0f);
    D3DXMatrixTranslation(&Worlds[2], -4.0f, 0.0f, 0.0f);
    D3DXMatrixTranslation(&Worlds[3], 4.0f, 0.0f, 0.0f);

    char *v_ = 0;
    Mesh[0]->LockVertexBuffer(0, (void**)&v_);
    for (int i = 0; i < Mesh[0]->GetNumVertices(); i++)
    {
    Vertex *const vv = (Vertex *const)v_;
    vv->_x -=4.0; vv->_y +=0.0; vv->_z +=0.0;
    v_ += Mesh[0]->GetNumBytesPerVertex();
    }
    Mesh[0]->UnlockVertexBuffer();


    //
    // Set texture filters.
    //

    Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    Device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

    //
    // Set Lights.


    D3DXVECTOR3 dir(1.0f, -1.0f, 1.0f); //direcao da luz
    D3DXCOLOR col(1.0f, 1.0f, 1.0f, 1.0f);//cor da luz a incidir no Mesh
    D3DLIGHT9 light = d3d::InitDirectionalLight(&dir, &col);

    Device->SetLight(0, &light);
    Device->LightEnable(0, true);
    Device->SetRenderState(D3DRS_NORMALIZENORMALS, true);
    Device->SetRenderState(D3DRS_SPECULARENABLE, true);

    //
    // Set camera.

    D3DXVECTOR3 pos(4.0f, 4.0f, -13.0f);
    D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
    D3DXMATRIX V;
    D3DXMatrixLookAtLH(
    &V,
    &pos,
    &target,
    &up);


    Device->SetTransform(D3DTS_VIEW, &V);//metodo q recebe info da camera

    //
    // Set projection matrix.


    D3DXMATRIX proj;
    D3DXMatrixPerspectiveFovLH(
    &proj,
    D3DX_PI * 0.5f, // 90 - degree
    (float)Width / (float)Height,
    1.0f,
    1000.0f);

    Device->SetTransform(D3DTS_PROJECTION, &proj);

    return true;
    }

    void Cleanup()
    {

    for(int j=0; j<4; j++)
    {
    d3d::Release<ID3DXMesh*>(Mesh[j]);

    for(int i = 0; i < Textures.size(); i++)
    d3d::Release<IDirect3DTexture9*>( Textures[ i] );
    }


    }



    bool Display() // that is the function to render the scene
    {
    if( Device )
    {
    //
    // Render

    Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
    Device->BeginScene();

    for(int j=0; j<4; j++)
    {
    Device->SetTransform(D3DTS_WORLD, &Worlds[j]);
    for(int i = 0; i < Mtrls.size(); i++)
    {
    Device->SetMaterial( &Mtrls[ i] ); //seta materiais
    Device->SetTexture(0, Textures[ i]); //seta texturas
    Mesh[j]->DrawSubset(i);
    }
    }
    Device->EndScene();
    Device->Present(0, 0, 0, 0);
    }
    return true;

    }
    //That part of code i dont think is need but to know what the stand alone app did i post here
    /*LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    {
    switch( msg )
    {
    case WM_DESTROY:
    ::PostQuitMessage(0);
    break;

    case WM_KEYDOWN:
    if( wParam == VK_ESCAPE )
    ::DestroyWindow(hwnd);
    break;
    }
    return ::DefWindowProc(hwnd, msg, wParam, lParam);
    }*/


    d3dUtility.cpp

    #include "d3dUtility.h"

    //here starts one of the sources of the problem i think
    bool d3d::InitD3D(
    HINSTANCE hInstance,
    int width, int height,
    bool windowed,
    D3DDEVTYPE deviceType,
    IDirect3DDevice9** device)
    {

    //
    // Init D3D:
    //

    // Step 1: Create the IDirect3D9 object.

    IDirect3D9* d3d9 = 0;
    d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

    if( !d3d9 )
    {
    ::MessageBox(0, "Direct3DCreate9() - FAILED", 0, 0);
    return false;
    }

    // Step 2: Check for hardware vp.

    D3DCAPS9 caps;
    d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);

    int vp = 0;
    if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
    vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
    else
    vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;

    // Step 3: Fill out the D3DPRESENT_PARAMETERS structure.

    D3DPRESENT_PARAMETERS d3dpp;
    d3dpp.BackBufferWidth = width;
    d3dpp.BackBufferHeight = height;
    d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
    d3dpp.BackBufferCount = 1;
    d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
    d3dpp.MultiSampleQuality = 0;
    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow = hwnd;
    d3dpp.Windowed = windowed;
    d3dpp.EnableAutoDepthStencil = true;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
    d3dpp.Flags = 0;
    d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

    // Step 4: Create the device.

    hr = d3d9->CreateDevice(
    D3DADAPTER_DEFAULT, // primary adapter
    deviceType, // device type
    hwnd, // window associated with device
    vp, // vertex processing
    &d3dpp, // present parameters
    device); // return created device

    if( FAILED(hr) )
    {
    // try again using a 16-bit depth buffer
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

    hr = d3d9->CreateDevice(
    D3DADAPTER_DEFAULT,
    deviceType,
    hwnd,
    vp,
    &d3dpp,
    device);

    if( FAILED(hr) )
    {
    d3d9->Release(); // done with d3d9 object
    ::MessageBox(0, "CreateDevice() - FAILED", 0, 0);
    return false;
    }
    }

    d3d9->Release(); // done with d3d9 object

    return true;
    }

    D3DLIGHT9 d3d::InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color)
    {
    D3DLIGHT9 light;
    ::ZeroMemory(&light, sizeof(light));

    light.Type = D3DLIGHT_DIRECTIONAL;
    light.Ambient = *color * 0.4f;
    light.Diffuse = *color;
    light.Specular = *color * 0.6f;
    light.Direction = *direction;

    return light;
    }

    D3DLIGHT9 d3d::InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color)
    {
    D3DLIGHT9 light;
    ::ZeroMemory(&light, sizeof(light));

    light.Type = D3DLIGHT_POINT;
    light.Ambient = *color * 0.4f;
    light.Diffuse = *color;
    light.Specular = *color * 0.6f;
    light.Position = *position;
    light.Range = 1000.0f;
    light.Falloff = 1.0f;
    light.Attenuation0 = 1.0f;
    light.Attenuation1 = 0.0f;
    light.Attenuation2 = 0.0f;

    return light;
    }

    D3DLIGHT9 d3d::InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color)
    {
    D3DLIGHT9 light;
    ::ZeroMemory(&light, sizeof(light));

    light.Type = D3DLIGHT_SPOT;
    light.Ambient = *color * 0.4f;
    light.Diffuse = *color;
    light.Specular = *color * 0.6f;
    light.Position = *position;
    light.Direction = *direction;
    light.Range = 1000.0f;
    light.Falloff = 1.0f;
    light.Attenuation0 = 1.0f;
    light.Attenuation1 = 0.0f;
    light.Attenuation2 = 0.0f;
    light.Theta = 0.5f;
    light.Phi = 0.7f;

    return light;
    }

    D3DMATERIAL9 d3d::InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p)
    {
    D3DMATERIAL9 mtrl;
    mtrl.Ambient = a;
    mtrl.Diffuse = d;
    mtrl.Specular = s;
    mtrl.Emissive = e;
    mtrl.Power = p;
    return mtrl;
    }

    d3dUtility.h

    #ifndef __d3dUtilityH__
    #define __d3dUtilityH__

    #include <d3dx9.h>
    #include <d3dx9mesh.h>
    #include <string>

    namespace d3d
    {

    //here too can be something nasty to erase
    // d3d::InitD3D(
    bool InitD3D(
    HINSTANCE hInstance, // [in] Application instance.
    int width, int height, // [in] Backbuffer dimensions.
    bool windowed, // [in] Windowed (true)or full screen (false).
    D3DDEVTYPE deviceType, // [in] HAL or REF
    IDirect3DDevice9** device);// [out]The created device.



    template<class T> void Release(T t)
    {
    if( t )
    {
    t->Release();
    t = 0;
    }
    }

    template<class T> void Delete(T t)
    {
    if( t )
    {
    delete t;
    t = 0;
    }
    }

    const D3DXCOLOR WHITE( D3DCOLOR_XRGB(255, 255, 255) );
    const D3DXCOLOR BLACK( D3DCOLOR_XRGB( 0, 0, 0) );
    const D3DXCOLOR RED( D3DCOLOR_XRGB(255, 0, 0) );
    const D3DXCOLOR GREEN( D3DCOLOR_XRGB( 0, 255, 0) );
    const D3DXCOLOR BLUE( D3DCOLOR_XRGB( 0, 0, 255) );
    const D3DXCOLOR YELLOW( D3DCOLOR_XRGB(255, 255, 0) );
    const D3DXCOLOR CYAN( D3DCOLOR_XRGB( 0, 255, 255) );
    const D3DXCOLOR MAGENTA( D3DCOLOR_XRGB(255, 0, 255) );

    //
    // Lights
    //

    D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color);
    D3DLIGHT9 InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color);
    D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color);

    //
    // Materials
    //

    D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p);

    const D3DMATERIAL9 WHITE_MTRL = InitMtrl(WHITE, WHITE, WHITE, BLACK, 2.0f);
    const D3DMATERIAL9 RED_MTRL = InitMtrl(RED, RED, RED, BLACK, 2.0f);
    const D3DMATERIAL9 GREEN_MTRL = InitMtrl(GREEN, GREEN, GREEN, BLACK, 2.0f);
    const D3DMATERIAL9 BLUE_MTRL = InitMtrl(BLUE, BLUE, BLUE, BLACK, 2.0f);
    const D3DMATERIAL9 YELLOW_MTRL = InitMtrl(YELLOW, YELLOW, YELLOW, BLACK, 2.0f);
    }

    #endif // __d3dUtilityH__


  • Strandberg

    n0n4m3, the samples what u post, I don’t compiled it, show me a error, when I open the archive .vcproj, don’t open the project, I try open in VS.Net 2003 and VS.Net 2005, in 2003 ocurred erro of version, but in 2005 don’t open this projet, What i do

    The second link of sample what u post, I see what the code went compiled using VS.NET 2005 and u use the include d3d9.h, but I copy the archives to my project, and when I compiled ask me very includes (archives .h) with: objbase.h, winnt.h, winuser.h, etc, I saw what this archives was in the SDK`s folder, of VS.Net 2003, I copy to folder VS.Net 2005, and show me a very errors with archive winnt.h. How U does

    Tks......and sorry my poor english......



  • Sweeps78

    n0n4m3, I try compiled your code and that’s right, OK, but I’ll try load a mesh, using the event of d3dx9.h "D3DXLoadMeshFromX", but a parameter what his use, what is a name of file .x, if i put D3DXLoadMeshFromX("mesh.x",...,....,....,...,..); show me the error "D3DXLoadMeshFromX : cannot convert parameter 1 from 'const char [7]' to 'LPCWSTR'", and not compiled, do you know what this Look a code...

    File "Form1.h":--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    #include <d3dx9.h>

    #include <string.h>

    #include <fstream>

    #pragma once

    namespace DXSample

    {

    using namespace System;

    using namespace System::Windows::Forms;

    using namespace System::Drawing;

    using namespace Microsoft::DirectX;

    using namespace Microsoft::DirectX::Direct3D;

    /// <summary>

    /// Summary for DXSampleForm

    ///

    /// WARNING: If you change the name of this class, you will need to change the

    /// 'Resource File Name' property for the managed resource compiler tool

    /// associated with all .resx files this class depends on. Otherwise,

    /// the designers will not be able to interact properly with localized

    /// resources associated with this form.

    /// </summary>

    public ref class DXSampleForm : public System::Windows::Forms::Form

    {

    public:

    #pragma region Constructors

    /// <summary>

    /// Constructor

    /// </summary>

    DXSampleForm(void)

    {

    InitializeComponent();

    InitializeDevice();

    }

    #pragma endregion

    protected:

    #pragma region Destructors

    /// <summary>

    /// Clean up any resources being used.

    /// </summary>

    ~DXSampleForm()

    {

    if (components)

    {

    delete components;

    }

    }

    #pragma endregion

    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();

    //

    // DXSampleForm

    //

    this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);

    this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;

    this->ClientSize = System::Drawing::Size(970, 614);

    this->Name = L"DXSampleForm";

    this->Text = L"DxSampleForm";

    this->ResumeLayout(false);

    }

    #pragma endregion

    #pragma region Attribute members

    /// <summary>

    /// Our DirectX device.

    /// </summary>

    private: Device^ device;

    #pragma endregion

    #pragma region Methods

    /// <summary>

    /// Initializes our Direct3D device.

    /// </summary>

    public: void InitializeDevice()

    {

    // initialize our present parameters structure

    PresentParameters^ presentParams = gcnew PresentParameters();

    presentParams->Windowed = true;

    presentParams->SwapEffect = SwapEffect::Discard;

    // this is only needed for the GDI+ rendering

    presentParams->PresentFlag = PresentFlag::LockableBackBuffer;

    // create our device

    device = gcnew Device(0, DeviceType::Hardware, this->Handle, CreateFlags::HardwareVertexProcessing, presentParams);

    }

    #pragma endregion

    #pragma region Overriden methods

    /// <summary>

    /// Override the OnPaintBackground event. Clears the back buffer and renders a rectangle using GDI+.

    /// </summary>

    /// <param name="e"></param>

    protected: virtual void OnPaintBackground(System::Windows::Forms::PaintEventArgs^ e) override

    {

    ID3DXMesh* Mesh;

    ID3DXBuffer* adjBuffer = 0;

    ID3DXBuffer* mtrlBuffer = 0;

    DWORD numMtrls = 0;

    D3DXLoadMeshFromXW("mesh.x",D3DXMESH_MANAGED,&device,&adjBuffer,&mtrlBuffer,0,&numMtrls,&Mesh); -->Here show error!!

    // clear the device with a blue color

    device->Clear(ClearFlags::Target, Color::DarkSlateBlue, 1.0f, 0);

    // acquire access to the back buffer

    Surface^ backbuffer;

    backbuffer = device->GetBackBuffer(0, 0, Microsoft::DirectX::Direct3D::BackBufferType::Mono);

    Graphics^ graphics = backbuffer->GetGraphics();

    // D3DXLoadMeshFromX("mesh.x",D3DXMESH_MANAGED,device,&adjBuffer,&mtrlBuffer,0,&numMtrls,&mesh);

    // draw a rectangle using GDI+

    graphics->DrawRectangle(Pens::Beige, 10, 20, 50, 150);

    // release

    backbuffer->ReleaseGraphics();

    delete backbuffer;

    // swap the screen buffer and back buffer to present our new data

    device->Present();

    }

    #pragma endregion

    };

    }

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    File "testedirectx.cpp"----------------------------------------------------------------------------------------------------------------------------------------------------------------

    // DXTutorial1_C++CLI.cpp : main project file.

    #include "stdafx.h"

    #include "Form1.h"

    using namespace DXSample;

    [STAThreadAttribute]

    int main(array<System::String ^> ^args)

    {

    // Enabling Windows XP visual effects before any controls are created

    Application::EnableVisualStyles();

    Application::SetCompatibleTextRenderingDefault(false);

    // Create the main window and run it

    Application::Run(gcnew DXSampleForm());

    return 0;

    }

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    So, what I Load a mesh (file .x) in this form

    Very Tks..................and sorry my poor english!!!



  • pangitko79

    Actually we doing with native 'cause was the only way i knew to do the program in DirectX.
    My friend made the layout using windows form and i doing the directX part (almost done), we need to know how link one with another, that is the real reason. So if you could show to me and my friend above how to do this using native c++ we'll be really glad.=]

    Thanks, and sorry for the bother.






  • DotanP

    "I put my code in native C++ on DXTutorial1_C++CLI_mix.cpp (the main part like my xfile.cpp code)"

    * You can put your code anywhere you want, as far as I know, there are no restrictions about mixing an header file that contains managed and unmanaged classes.

    I can call the includes normally on DXTutorial1_C++CLI_mix.cpp for example : include <vector.h> or something similar

    * Yes you can, be careful with the order of the includes. Use this order:
    - stdafx.h (if you're using precompiled headers)
    - native c++ includes
    - managed c++ includes

    The function to render the application (the 3d part of it) it's automatically called to works on form or i need use her as an argument of some function of windows form

    * I didn't understand your question. In this example the I'm only cleaning the buffer to display a color. You can call your render function there or you can do your render there instead of calling a function.


    And before anything sorry my noobiness

    * Everyone is noob in something ;)


    and thanks for your help =]

    * Any time :)



  • ksona

    I don't have any but with some time I could make one. Can't you guys use c++/cli it would ease the process a bit more (although it's not complicated doing it with native c++).


  • How make a DirectX app runs on Windows Forms (using C++)