|
Hi together,
i am currently working on a WPF-based software for some basic CAD-funtionality. I herefore used this example Direct2DonWPF for using DirectX / D2D in a WPF control, which is working fine. I can draw what i want and the performance is good - EXCEPT the flickering when i draw to fast (>25fps). With GDI+ i was able to activate Doublebuffering and everything was fine. Now i'd need to implement the SwapChain from DirectX to get rid of this problem. Unfortunately, i found many tutorials and examples dealing with this issue, but none of them implements the SwapChain and D2D in WPF. I tried hours on hours to get it working, but on some random point i can't get it working.
Could someone help me understanding how to implement the SwapChain in the previously linked example, using D3DImage control etc.?
Thanks for your help,
Max
|
|
|
|
|
I would like to model the 3d object, consisted of two parts (A1 and A2). The angle between A1 and A2 is 150°. A1 and A2 are cylinders. The 3D object (A1 and A2) is lying on the XY plane.
I would like to rotate the 3d object around the A1 axis. The render plane has to be XZ. I don’t know how to rotate the 3d object around A1 axis. I use different combinations of the following functions:
D3DXMatrixRotationY(&R11, D3DX_PI * D3DXToRadian(0));
D3DXMatrixRotationAxis(&A1, &D3DXVECTOR3 (0.0f, 1.0f, 0.0f), D3DXToRadian(30));
D3DXMatrixRotationZ(&R12, D3DXToRadian(20));
D3DXMatrixTranslation(&T11, 20.0f, 5.0f, 0.0f);
D3DXMatrixRotationX(&R13, D3DXToRadian(40));
HR(gd3dDevice->SetTransform(D3DTS_WORLD, &(R11 * A1 * R13)));
Unfortunately I don’t understand how to create a child object (A2). When I rotate the object A1, the child object A2 has to be rotated automatically around the A1 axis.
Could you help to resolve the problem?
Regards
|
|
|
|
|
I would like to control two 3D objects separately using direct3d library.
I drawn one cube and one cylinder. Unfortunately when I move the cube by the keyboard, I move the cylinder too. How to move only one of the 3d objects?
Regards
My code is here:
#include <windows.h>
#include "CubeDemo.h"
#include "d3dApp.h"
#include "GfxStats.h"
#include "Vertex.h"
#include "DirectInput.h"
#include <crtdbg.h>
#include <list>
#include "d3dUtil.h"
CubeDemo::CubeDemo(HINSTANCE hInstance, std::string winCaption,
D3DDEVTYPE devType, DWORD requestedVP)
: D3DApp(hInstance, winCaption, devType, requestedVP), MAX_SPEED(1500.0f), ACCELE(1000.0f)
{
mGfxStats = new GfxStats();
mCameraRadius = 10.0f;
mCameraRotationY = 1.2 * D3DX_PI;
xPos = 0.0f;
yPos = 0.0f;
mCameraHeight = 1.0f;
HR(D3DXCreateCylinder(gd3dDevice, 4.0f, 5.0f, 6.0f, 10, 4, &mCylinder, 0));
int numCylVerts = mCylinder->GetNumVertices() * 14;
int numCylTris = mCylinder->GetNumFaces() * 14;
mGfxStats->addVertices(mNumGridVertices);
mGfxStats->addVertices(numCylVerts);
mGfxStats->addTriangles(mNumGridTriangles);
mGfxStats->addTriangles(numCylTris);
buildGeoBuffers();
buildFX();
buildVertexBuffer();
buildIndexBuffer();
onResetDevice();
InitAllVertexDeclarations();
checkDeviceCaps();
}
void CubeDemo::buildFX()
{
ID3DXBuffer* errors = 0;
HR(D3DXCreateEffectFromFile(gd3dDevice, "transform.fx",
0, 0, D3DXSHADER_DEBUG, 0, &mFX, &errors));
if( errors )
MessageBox(0, (char*)errors->GetBufferPointer(), 0, 0);
mhTech = mFX->GetTechniqueByName("TransformTech");
mhWVP = mFX->GetParameterByName(0, "gWVP");
}
bool CubeDemo::checkDeviceCaps()
{
D3DCAPS9 caps;
HR(gd3dDevice->GetDeviceCaps(&caps));
if (caps.VertexShaderVersion < D3DVS_VERSION(3, 0))
return false;
if (caps.VertexShaderVersion < D3DPS_VERSION(3, 0))
return true;
}
void CubeDemo::drawCylinders()
{
D3DXMATRIX T, R;
D3DXMatrixRotationX(&R, D3DX_PI * 0.5f);
int z = 30;
D3DXVECTOR3 pos(100, 0, 0);
D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMatrixLookAtLH(&mView, &pos, &target, &up);
D3DXMatrixTranslation(&T, -100.0f, 3.0f, (float)z);
HR(mFX->SetMatrix(mhWVP, &(R * T * mView * mProj)));
HR(mFX->CommitChanges());
HR(mCylinder->DrawSubset(0));
}
void CubeDemo::buildVertexBuffer()
{
HR(gd3dDevice->CreateVertexBuffer(8 * sizeof (VertexPos), D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &mVB, 0));
VertexPos* v = 0;
HR(mVB->Lock(0, 0, (void**)&v, 0));
v[0] = VertexPos(-1.0f, -1.0f, -1.0f);
v[1] = VertexPos(-1.0f, 1.0f, -1.0f);
v[2] = VertexPos( 1.0f, 1.0f, -1.0f);
v[3] = VertexPos( 1.0f, -1.0f, -1.0f);
v[4] = VertexPos(-1.0f, -1.0f, 1.0f);
v[5] = VertexPos(-1.0f, 1.0f, 1.0f);
v[6] = VertexPos( 1.0f, 1.0f, 1.0f);
v[7] = VertexPos( 1.0f, -1.0f, 1.0f);
HR(mVB->Unlock());
}
void CubeDemo::buildIndexBuffer()
{
HR(gd3dDevice->CreateIndexBuffer(36 * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &mIB, 0));
WORD* k = 0;
HR(mIB->Lock(0, 0, (void**)&k, 0));
k[0] = 0; k[1] = 1; k[2] = 2;
k[3] = 0; k[4] = 2; k[5] = 3;
k[6] = 4; k[7] = 6; k[8] = 5;
k[9] = 4; k[10] = 7; k[11] = 6;
k[12] = 4; k[13] = 5; k[14] = 1;
k[15] = 4; k[16] = 1; k[17] = 0;
k[18] = 3; k[19] = 2; k[20] = 6;
k[21] = 3; k[22] = 6; k[23] = 7;
k[24] = 1; k[25] = 5; k[26] = 6;
k[27] = 1; k[28] = 6; k[29] = 2;
k[30] = 4; k[31] = 0; k[32] = 3;
k[33] = 4; k[34] = 3; k[35] = 7;
HR(mIB->Unlock());
}
CubeDemo::~CubeDemo()
{
delete mGfxStats;
ReleaseCOM(mVB);
ReleaseCOM(mIB);
ReleaseCOM(mCylinder);
DestroyAllVertexDeclarations();
}
void CubeDemo::onLostDevice()
{
mGfxStats->onLostDevice();
}
void CubeDemo::onResetDevice()
{
mGfxStats->onResetDevice();
buildProjMtx();
}
void CubeDemo::buildProjMtx()
{
float w = (float)md3dPP.BackBufferWidth;
float h = (float)md3dPP.BackBufferHeight;
D3DXMatrixPerspectiveFovLH(&mProj, D3DX_PI * 0.25f, w/h,
1.0f, 5000.0f);
}
void CubeDemo::updateScene(float dt)
{
mGfxStats->setVertexCount(8);
mGfxStats->setTriCount(12);
mGfxStats->update(dt);
gDInput->poll();
if( gDInput->keyDown(DIK_W) )
xPos = xPos + 0.001f;
if( gDInput->keyDown(DIK_S) )
xPos = xPos - 0.001f;
if( gDInput->keyDown(DIK_A) )
yPos = yPos - 0.001f;
if( gDInput->keyDown(DIK_D) )
yPos = yPos + 0.001f;
mCameraRotationY += gDInput->mouseDX() / 50.0f;
mCameraRadius += gDInput->mouseDY() / 50.0f;
if( fabsf(mCameraRotationY) >= 2.0f * D3DX_PI )
mCameraRotationY = 0.0f;
if( mCameraRadius < 5.0f )
mCameraRadius = 5.0f;
buildViewMtx();
}
void CubeDemo::buildViewMtx()
{
D3DXVECTOR3 pos(0, 0, 100);
D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 up(1.0f, 0.0f, 0.0f);
D3DXMatrixLookAtLH(&mView, &pos, &target, &up);
}
void CubeDemo::drawScene()
{
HR(gd3dDevice->Clear(0, 0,
D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0));
HR(gd3dDevice->BeginScene());
HR(gd3dDevice->SetStreamSource(0, mVB, 0, sizeof(VertexPos)));
HR(gd3dDevice->SetIndices(mIB));
HR(gd3dDevice->SetVertexDeclaration(VertexPos::Decl));
HR(mFX->SetTechnique(mhTech));
D3DXMATRIX W;
D3DXMatrixIdentity(&W);
HR(gd3dDevice->SetTransform(D3DTS_WORLD, &W));
HR(gd3dDevice->SetTransform(D3DTS_VIEW, &mView));
HR(gd3dDevice->SetTransform(D3DTS_PROJECTION, &mProj));
D3DXMATRIX matTranslate;
D3DXMatrixTranslation(&matTranslate, xPos, yPos, 0.0f);
HR(gd3dDevice->SetTransform(D3DTS_WORLD, &matTranslate));
HR(gd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME));
HR(gd3dDevice->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12));
drawCylinders();
HR(gd3dDevice->EndScene());
HR(gd3dDevice->Present(0, 0, 0, 0));
}
void CubeDemo::buildGeoBuffers()
{
std::vector<D3DXVECTOR3> verts;
std::vector<DWORD> indices;
GenTriGrid(100, 100, 1.0f, 1.0f, D3DXVECTOR3(0.0f, 0.0f, 0.0f), verts, indices);
mNumGridVertices = 100*100;
mNumGridTriangles = 99*99*2;
HR(gd3dDevice->CreateVertexBuffer(mNumGridVertices * sizeof(VertexPos),
D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &mVB, 0));
VertexPos* v = 0;
HR(mVB->Lock(0, 0, (void**)&v, 0));
for(DWORD i = 0; i < mNumGridVertices; ++i)
v[i] = verts[i];
HR(mVB->Unlock());
HR(gd3dDevice->CreateIndexBuffer(mNumGridTriangles*3*sizeof(WORD), D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16, D3DPOOL_MANAGED, &mIB, 0));
WORD* k = 0;
HR(mIB->Lock(0, 0, (void**)&k, 0));
for(DWORD i = 0; i < mNumGridTriangles*3; ++i)
k[i] = (WORD)indices[i];
HR(mIB->Unlock());
}
modified 15-Jul-16 4:34am.
|
|
|
|
|
You're setting the world transform, then drawing the cube followed by the cylinder.
Either draw the cylinder before applying the world transform for the cube, or apply a new world transform before drawing the cylinder.
|
|
|
|
|
Thank you very much for your help.
|
|
|
|
|
|
|
I have recently read an article about Direct2D and GDI Interop from MSDN and I just wanted to make an attempt on that.
The problem with my code is that there is no (D2D) red rectangles at the output file but it does not produce any compile-time or runtime errors.
That really makes me frustrated as I have already spent my valuable weekend for that without any progress.
Any help is appreciated.
Ref. article: Direct2D and GDI Interoperability Overview (Windows)[^]
Code block:
#include<d2d1_2.h>
#include<gdiplus.h>
#include<iostream>
#include<wincodec.h>
#pragma comment(lib, "d2d1.lib")
#pragma comment(lib, "GdiPlus.lib")
#pragma comment(lib, "Windowscodecs.lib")
using namespace std;
void main()
{
HRESULT hr;
ID2D1Factory* factory;
ID2D1DCRenderTarget* target;
ID2D1SolidColorBrush* brush;
D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory);
ULONG_PTR token;
Gdiplus::GdiplusStartup(&token, new Gdiplus::GdiplusStartupInput(), nullptr);
auto image = new Gdiplus::Image(L"C:\\temp\\test.jpg");
auto g = Gdiplus::Graphics::FromImage(image);
auto prop = D2D1_RENDER_TARGET_PROPERTIES{
D2D1_RENDER_TARGET_TYPE_HARDWARE ,
D2D1_PIXEL_FORMAT{ DXGI_FORMAT_B8G8R8A8_UNORM , D2D1_ALPHA_MODE_PREMULTIPLIED },
144.0f,
144.0f,
D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE,
D2D1_FEATURE_LEVEL_DEFAULT
};
hr = factory->CreateDCRenderTarget(&prop, &target);
auto rect = RECT{ 0L,0L,800L, 600L };
cout << boolalpha << (image == nullptr) << boolalpha << (g == nullptr) << endl;
HDC deviceContext = g->GetHDC();
target->BindDC(deviceContext, &rect);
target->BeginDraw();
target->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Red, 1.0f), &brush);
target->DrawRectangle(D2D1_RECT_F{ 5.0f,5.0f,10.0f,10.0f }, brush);
target->DrawRectangle(D2D1_RECT_F{ 10.0f,10.0f,30.0f,30.0f }, brush);
hr = target->EndDraw();
cout << boolalpha << SUCCEEDED(hr) << endl;
CLSID pngEncoderClsId = { 0x557cf406, 0x1a04, 0x11d3,{ 0x9a,0x73,0x00,0x00,0xf8,0x1e,0xf3,0x2e } };
image->Save(L"C:\\temp\\output.png", &pngEncoderClsId);
Gdiplus::GdiplusShutdown(token);
}
|
|
|
|
|
You are trying to do this in a console application. I do not think that will work since you have no Window to draw on. You need to create a Windows app to do it.
|
|
|
|
|
Hi
I use the following link for starting an application with direct3d:
file:///D:/SoftwareProjects/Help/A%20Primer%20of%20DirectX%20Basics%20and%20the%20DirectX3D%20API%20-%20CodeProject.htm
I use this book too: Introduction to 3D Game Programming, written by Frank Luna
I use Microsoft Visual Studio 2012 C++ and Microsoft DirectX SDK (June 2010).
I have the following errors during debug of my application.
in the file DirectInput.cpp at the following lines:
HR(mKeyboard->Acquire());
HR(mMouse->Acquire());
The error is: one box appears with the following text:
Unexpected error encountered.
X Error
with buttons: YES/ NO
I don't know how to attach a screenshot of the error to the message.
Could you please help me to resolve the problem.
Also in DirectInput.h
I changed the declaration of the following:
extern DirectInput* gDInput;
in static DirectInput* gDInput;
Regards
|
|
|
|
|
Member 12268183 wrote: file:///D:/SoftwareProjects/Help/A%20Primer%20of%20DirectX%20Basics%20and%20the%20DirectX3D%20API%20-%20CodeProject.htm
You do realise we can't access your computer, right? A link to an HTML file stored on your computer is absolutely useless to us.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
|
You should ask your question on the forum at the end of the article. It's the best place to get help.
This space for rent
|
|
|
|
|
|
Changing a header file declaration usually ends in tears, unless you really understand the implications.
|
|
|
|
|
Member 12268183 wrote: I changed the declaration of the following:
extern DirectInput* gDInput;
in static DirectInput* gDInput; Do you think there might be a connection?
This space for rent
|
|
|
|
|
I don't know. If I put extern DirectInput* gDInput I receive the following error during the build process:
1> Generating Code...
1>CubeDemo.obj : error LNK2001: unresolved external symbol "class DirectInput * gDInput" (?gDInput@@3PAVDirectInput@@A)
1>SpriteDemo.obj : error LNK2001: unresolved external symbol "class DirectInput * gDInput" (?gDInput@@3PAVDirectInput@@A)
1>winmain.obj : error LNK2019: unresolved external symbol "class DirectInput * gDInput" (?gDInput@@3PAVDirectInput@@A) referenced in function "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::assign(char const *)" (?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@PBD@Z)
1>D:\SoftwareProjects\C++\book_ex1\Debug\book_ex1.exe : fatal error LNK1120: 1 unresolved externals
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
|
|
|
|
|
The linker is merely telling you that you forgot to provide a definition of the object that has been declared extern . You need to provide a line such as the following in one (and only one) of your source files:
DirectInput * gDInput =
|
|
|
|
|
Hi
I add extern DirectInput* gDInput; in DirectInput.h file. At the beginning of the file DirectInput.cpp I add DirectInput* gDInput = 0;
After the build process I received no errors. But during the debug process I still have the same error on the line in DirectInput.cpp:
HR(mKeyboard->Acquire());
One message box appears with the following message:
Unexpected error encountered: XFile with two buttons Yes/No
Regards
|
|
|
|
|
Then you need to use your debugger to find out why the error occurred. Randomly changing source code is not a very good way to try and resolve problems.
|
|
|
|
|
 I try to find the error using debug but till the moment it is not successful. The debuger is going in files as output.c, ullrem.asm, ulldiv.asm, vsprintf.c,
The debuger is passing through no source available point and continues till:
book_ex1.exe!DXTraceA(const char*strFile, unsigned long dwLine, HRESULT hr, const char*strMsg, int bPopMsgBox)Line 4828
Source file information:
Locating source for 'e:\temp\193462\obj.x86fre\misc\dxerr\objfre\i386\dxerra.cpp'. Checksum: Mo5 {62 b6 ef ba 67 f9 ac 6 4b 2 ec 8e 70 e7 46 a
The file 'e:\temp\193462\obj.x86fre\misc\dxerr\objfre\i386\dxerra.cpp' does not exist.
Looking in script documents for 'e:\temp\193462\obj.x86fre\misc\dxerr\objfre\i386\dxerra.cpp'...
Looking in the projects for 'e:\temp\193462\obj.x86fre\misc\dxerr\objfre\i386\dxerra.cpp'.
The file was not found in a project.
Looking in directory 'C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\'...
Looking in directory 'C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\vccorlib\'...
Looking in directory 'C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\atlmfc\src\mfc\'...
Looking in directory 'C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\atlmfc\src\atl\'... E}
Looking in directory 'C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\atlmfc\include'...
Looking in directory 'C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\atlmfc\src\mfc'...
Looking in directory 'C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\atlmfc\src\mfcm'...
Looking in directory 'C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\atlmfc\src\atl'...
|
|
|
|
|
You know where the exception occurs, add a breakpoint soemwhere before that point and run the program. When the breakpoint fires you can single step through the code and check all variables as you proceed, in order to find the offending value.
|
|
|
|
|
It is very difficult to find the error line because I look in Disassembly. I use step into and step out. Do you know better way to check errors in disassembly section.
|
|
|
|
|
Why are you looking in disassembly, when you have the source code?
|
|
|
|
|
Thank you very much for your help. Everythink is working well when I started the application without debuging.
|
|
|
|
|