# New ReleaseD3D9Client Development

#### jarmonik

Beta Tester
I wanted to contibute a little bit to this GREAT client and decided to implement a small feature that is still missing: ShowGrapplePoints

Thanks, That's a really good news. I'll greatly appriciate that.

Can you give me a hint on how to render the Meshes?
Am I on the right track?
Or should I have used some other technique?

It looks good. But there is something odd about the arrow vertices. In a non-indexed mesh the vertices should come in a groups of three and there is no need to place the color in the vertices.

There are two possibilities.
1. Create an arrow using NTVERTEX declaration and existing shaders.
2. Create an arrow using D3DVECTOR declaration and write a new shader for it.

In this example I have selected the option 2 because the first one would need a normal and texture coordinates for the vertices and also a texture would need to be attached into the pipeline to allow existing shaders to work.

My computer is currently a bit broken so I haven't been able to test the code. So, It may contain some errors.

Here is a code example for a rendering routine:
Code:
[SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] D3D9Effect::RenderArrow(OBJHANDLE hObj, [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]const[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] VECTOR3 *ofs, [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]float[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] size, [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]const[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] D3DXCOLOR *pColor)
{
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]static[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] D3DVECTOR arrow[9] = {
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]{0.0, 0.0, 0.0},
{0.0,-1.0, 1.0},
{0.0, 1.0, 1.0},
[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// Body first triangle
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]{0.0,-0.5, 1.0},
{0.0,-0.5, 2.0},
{0.0, 0.5, 2.0},
[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// Body second triangle
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]{0.0,-0.5, 1.0},
{0.0, 0.5, 2.0},
{0.0, 0.5, 1.0}
};
MATRIX3 grot;
VECTOR3 camp, gpos;
oapiGetRotationMatrix(hObj, &grot);
oapiGetGlobalPos(hObj, &gpos);
oapiCameraGlobalPos(&camp);
VECTOR3 pos = gpos - camp;
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]if[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] (ofs) pos += mul (grot, *ofs);

D3DXMATRIX W;
D3DXVECTOR3 vPos([/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]float[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2](pos.x), [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]float[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2](pos.y), [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]float[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2](pos.z));
D3DXVECTOR3 vCam;
D3DXVec3Normalize(&vCam, &vPos);
D3DMAT_CreateX_Billboard(&vCam, &vPos, size, &W); [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// Create a billboard world matrix to face the X-axis towards camera
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]UINT numPasses = 0;
HR(pDev->SetVertexDeclaration(pPositionDecl)); [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// Position only vertex decleration
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]HR(FX->SetValue(eColor, pColor, [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]sizeof[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2](D3DXCOLOR))); [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// Setup arrow color
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]HR(FX->SetMatrix(eW, &W));
HR(FX->Begin(&numPasses, D3DXFX_DONOTSAVESTATE));
HR(FX->BeginPass(0));
HR(pDev->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 3, &arrow, [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]sizeof[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2](D3DVECTOR))); [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// Draw 3 triangles un-indexed
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]HR(FX->EndPass());
HR(FX->End());
gc->GetStats()->Draw++; [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// Increment rendering statistics counter
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]}
[/SIZE]

Here are a few other changes needed to create a new shader:
Code:
[SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// ==== These lines go into the D3D9Effect.cpp ====
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]D3DXHANDLE D3D9Effect::eArrowTech = 0;
eArrowTech = FX->GetTechniqueByName([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"ArrowTech"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]);
[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// ==== These lines go into the D3D9Effect.h ====
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]static[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] RenderArrow(OBJHANDLE hObj, [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]const[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] VECTOR3 *ofs, [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]float[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] size, [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]const[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] D3DXCOLOR *pColor);
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]static[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] D3DXHANDLE eArrowTech;
[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// ==== These lines go into the D3D9Client.fx ====
{
[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// Zero output.
float3 posW = mul(float4(posL, 1.0f), gW).xyz; [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// Apply world transformation matrix
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]outVS.posH = mul(float4(posW, 1.0f), gVP); [/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// Apply view projection matrix
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] outVS;
}
{
[/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] gColor;
}
[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// This is used for rendering beacons ------------------------------------------
//
[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]technique ArrowTech
{
pass P0
{

AlphaBlendEnable = [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]true[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2];
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha;
ZWriteEnable = [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]false[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2];
ZEnable = [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]true[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2];
}
}
[/SIZE]

To use the code you need to pass a vessel handle to the routine.
hVessel = vessel->GetHandle();
D3D9Effect::RenderArrow(hVessel, &pos, (float)size, &D3DCOLOR(0,0,1)
);

---------- Post added at 12:12 ---------- Previous post was at 11:58 ----------

Sorry, I supose the last line should be like this

D3D9Effect::RenderArrow(hVessel, &pos, (float)size, &D3DXCOLOR(0,0,1,1));

#### kuddel

##### Donator
Donator
Thanks a million jarmonik

My computer is currently a bit broken so I haven't been able to test the code. So, It may contain some errors.
I know. This makes your tips even more precious :thumbup: :tiphat:
I only needed to get on the right track. As soon as I'm back on my 'develop machine' I'll see what I can make of it!

Thanks again and hopefully the reconstruction of your setup is not too much pain in the

Regards,
Kuddel

---------- Post added at 22:00 ---------- Previous post was at 14:18 ----------

Hi again jarmonik,

your code works very well! :thumbup:

The only thing that is not 'perfect' is that the arrow(s) is always facing the camera (it's its most photogenic side maybe :lol: ) See Attachment

Here I face my two problems again:
a) beeing not good enough in VECTOR transformation
b) not having too much time

But maybe you can push me again onto the right track.

I think somewhere in the D3D9Effect::RenderArrow method I'll have to do some transformations to make them right...
PHP:
void D3D9Effect::RenderArrow(OBJHANDLE hObj, const VECTOR3 *ofs, const VECTOR3 *dir, const VECTOR3 *rot, float size, const D3DXCOLOR *pColor)
{
static D3DVECTOR arrow[9] = {
{0.0, 0.0, 0.0},
{0.0,-1.0, 1.0},
{0.0, 1.0, 1.0},
// Body first triangle
{0.0,-0.5, 1.0},
{0.0,-0.5, 2.0},
{0.0, 0.5, 2.0},
// Body second triangle
{0.0,-0.5, 1.0},
{0.0, 0.5, 2.0},
{0.0, 0.5, 1.0}
};
MATRIX3 grot;
VECTOR3 camp, gpos;

oapiGetRotationMatrix(hObj, &grot);
oapiGetGlobalPos(hObj, &gpos);
oapiCameraGlobalPos(&camp);

// SOMEWHERE HERE ?

VECTOR3 pos = gpos - camp;
if (ofs) pos += mul (grot, *ofs);

// ...OR  HERE ?

D3DXMATRIX W;
D3DXVECTOR3 vPos(float(pos.x), float(pos.y), float(pos.z));
D3DXVECTOR3 vCam;
D3DXVec3Normalize(&vCam, &vPos);
D3DMAT_CreateX_Billboard(&vCam, &vPos, size, &W); // Create a billboard world matrix to face the X-axis towards camera
UINT numPasses = 0;
HR(pDev->SetVertexDeclaration(pPositionDecl)); // Position only vertex decleration
HR(FX->SetValue(eColor, pColor, sizeof(D3DXCOLOR))); // Setup arrow color
HR(FX->SetMatrix(eW, &W));
HR(FX->Begin(&numPasses, D3DXFX_DONOTSAVESTATE));
HR(FX->BeginPass(0));
HR(pDev->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 3, &arrow, sizeof(D3DVECTOR))); // Draw 3 triangles un-indexed
HR(FX->EndPass());
HR(FX->End());
gc->GetStats()->Draw++; // Increment rendering statistics counter
}
As you see I've already prepared the parameter signature, but than my poor knowledge decelerates me :embarrassed:
The small amount of time is (of corse) just an excuse

Nevertheless, thank you very much for your (almost) perfect code-snippets!!!

Kuddel

P.S.: Shall I post -or PM you- my changes / the complete code ? (Based on RC39)

#### Attachments

• NoRotationYet.jpg
126 KB · Views: 50
Last edited:

#### blixel

##### Donator
Donator
When I start Orbiter NG there is no Fly-By-wire to choose from the extras tab in the launchpad.

In order to see Fly-By-Wire in the Extras tab, you have to enable the module in the Modules tab.

#### jarmonik

Beta Tester
You can add a new parameter in the function that will point the direction of the arrow:

void D3D9Effect::RenderArrow(OBJHANDLE hObj, const VECTOR3 *ofs, const VECTOR3 *direction, float size, const D3DXCOLOR *pColor)

Convert the VECTOR3 to D3DXVECTOR3 and use an other version of the D3DMAT_CreateX_Billboard function as shown below.

VECTOR3 dir = mul (grot, *direction);

D3DXVECTOR3 vDir(
float(dir.x), float(dir.y), float(dir.z));
D3DMAT_CreateX_Billboard(&vCam, &vPos, &vDir, size, size, &W);

---------- Post added at 06:40 ---------- Previous post was at 06:34 ----------

P.S.: Shall I post -or PM you- my changes / the complete code ? (Based on RC39)

The changes into the Vessel.cpp/.h would be enough. You can post them in here. No need to post the codes for D3D9Effect.cpp/.h we have already here unless you have made changes into them.

---------- Post added at 19:45 ---------- Previous post was at 06:40 ----------

I suppose if you need the rotation you can write the code like this. I haven't tested it.

PHP:
void D3D9Effect::RenderArrow(OBJHANDLE hObj, const VECTOR3 *ofs, const VECTOR3 *dir, const VECTOR3 *rot, float size, const D3DXCOLOR *pColor)
{
static D3DVECTOR arrow[9] = {
{0.0, 0.0, 0.0},
{0.0,-1.0, 1.0},
{0.0, 1.0, 1.0},
// Body first triangle
{0.0,-0.5, 1.0},
{0.0,-0.5, 2.0},
{0.0, 0.5, 2.0},
// Body second triangle
{0.0,-0.5, 1.0},
{0.0, 0.5, 2.0},
{0.0, 0.5, 1.0}
};

MATRIX3 grot;
D3DXMATRIX W;
VECTOR3 camp, gpos;

oapiGetRotationMatrix(hObj, &grot);
oapiGetGlobalPos(hObj, &gpos);
oapiCameraGlobalPos(&camp);

VECTOR3 pos = gpos - camp;
if (ofs) pos += mul (grot, *ofs);

VECTOR3 z = mul (grot, unit(*dir)) * size;
VECTOR3 y = mul (grot, unit(*rot)) * size;
VECTOR3 x = mul (grot, unit(crossp(*dir, *rot))) * size;

D3DXMatrixIdentity(&W);

W._11 = float(x.x);
W._12 = float(x.y);
W._13 = float(x.z);

W._21 = float(y.x);
W._22 = float(y.y);
W._23 = float(y.z);

W._31 = float(z.x);
W._32 = float(z.y);
W._33 = float(z.z);

W._41 = float(pos.x);
W._42 = float(pos.y);
W._43 = float(pos.z);

UINT numPasses = 0;
HR(pDev->SetVertexDeclaration(pPositionDecl)); // Position only vertex decleration
HR(FX->SetValue(eColor, pColor, sizeof(D3DXCOLOR))); // Setup arrow color
HR(FX->SetMatrix(eW, &W));
HR(FX->Begin(&numPasses, D3DXFX_DONOTSAVESTATE));
HR(FX->BeginPass(0));
HR(pDev->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 3, &arrow, sizeof(D3DVECTOR))); // Draw 3 triangles un-indexed
HR(FX->EndPass());
HR(FX->End());
gc->GetStats()->Draw++; // Increment rendering statistics counter
}

#### kuddel

##### Donator
Donator
...I suppose if you need the rotation you can write the code like this. I haven't tested it.
..and I suppose that's 100% correct although not tested :thumbup:
I'll try and report as soon as I'm at home
/Kuddel

---------- Post added at 23:02 ---------- Previous post was at 19:07 ----------

Hi jarmonik,

as expected your code works perfectly! I've done some minor tweaks to make is exactly like it is in the inline client (colors, alphas, size), but nothing really different.
And surely I first forgot to add the back-faced part of the arrow(s) :embarrassed: ...

For the record, here are all the changes:

=== Scene.cpp ===
PHP:
    // render grapple points
//
for (pv=vobjFirst; pv; pv=pv->next) {
if (!pv->vobj->IsActive()) continue;
pv->vobj->RenderGrapplePoints(pDevice);
}

=== vObject.h ===
PHP:
    /**
* \brief Render the vessel's grapple points when switched on (see oapiGetShowGrapplePoints)
* \param dev render device
* \default None.
*/
virtual void RenderGrapplePoints (LPDIRECT3DDEVICE9 dev) {}

=== VVessel.h ===
PHP:
    void RenderGrapplePoints (LPDIRECT3DDEVICE9 dev);

=== VVessel.cpp ===
PHP:
void vVessel::RenderGrapplePoints (LPDIRECT3DDEVICE9 dev)
{
if (!oapiGetShowGrapplePoints()) return; // nothing to do

DWORD i;
ATTACHMENTHANDLE hAtt;
VECTOR3 pos, dir, rot;
const float size = 0.25;
const float alpha = 0.5;

// Flash calculations
static double lastTime = 0;
static bool isOn = true;
double simt = oapiGetSysTime();
if (simt-lastTime > 0.5) // Flashing period (twice per second)
{
isOn = !isOn;
lastTime = simt;
}
if (!isOn) return; // nothing to do

const OBJHANDLE hVessel = vessel->GetHandle();

// attachment points to parent
for (i = 0; i < vessel->AttachmentCount(true); ++i)
{
hAtt = vessel->GetAttachmentHandle(true, i);
vessel->GetAttachmentParams(hAtt, pos, dir, rot);
D3D9Effect::RenderArrow(hVessel, &pos, &dir, &rot, size, &D3DXCOLOR(1,0,0,alpha));
}

// attachment points to children
for (i = 0; i < vessel->AttachmentCount(false); ++i)
{
hAtt = vessel->GetAttachmentHandle(false, i);
vessel->GetAttachmentParams(hAtt, pos, dir, rot);
D3D9Effect::RenderArrow(hVessel, &pos, &dir, &rot, size, &D3DXCOLOR(0,0.5,1,alpha));
}
}

=== D3D9Effect.h ===
PHP:
    static void RenderArrow(OBJHANDLE hObj, const VECTOR3 *ofs, const VECTOR3 *dir, const VECTOR3 *rot, float size, const D3DXCOLOR *pColor);

=== D3D9Effect.cpp ===
PHP:
D3DXHANDLE D3D9Effect::eArrowTech = 0; // (Grapple point) arrows
PHP:
    eArrowTech   = FX->GetTechniqueByName("ArrowTech");
PHP:
// ===========================================================================================
// This is a special rendering routine used to render (grapple point) arrows
//
void D3D9Effect::RenderArrow(OBJHANDLE hObj, const VECTOR3 *ofs, const VECTOR3 *dir, const VECTOR3 *rot, float size, const D3DXCOLOR *pColor)
{
static D3DVECTOR arrow[18] = {
{0.0, 0.0, 0.0},
{0.0,-1.0, 1.0},
{0.0, 1.0, 1.0},
{0.0, 0.0, 0.0},
{0.0, 1.0, 1.0},
{0.0,-1.0, 1.0},
// Body first triangle (front- & back-face)
{0.0,-0.5, 1.0},
{0.0,-0.5, 2.0},
{0.0, 0.5, 2.0},
{0.0,-0.5, 1.0},
{0.0, 0.5, 2.0},
{0.0,-0.5, 2.0},
// Body second triangle (front- & back-face)
{0.0,-0.5, 1.0},
{0.0, 0.5, 2.0},
{0.0, 0.5, 1.0},
{0.0,-0.5, 1.0},
{0.0, 0.5, 1.0},
{0.0, 0.5, 2.0}
};

MATRIX3 grot;
D3DXMATRIX W;
VECTOR3 camp, gpos;

oapiGetRotationMatrix(hObj, &grot);
oapiGetGlobalPos(hObj, &gpos);
oapiCameraGlobalPos(&camp);

VECTOR3 pos = gpos - camp;
if (ofs) pos += mul (grot, *ofs);

VECTOR3 z = mul (grot, unit(*dir)) * size;
VECTOR3 y = mul (grot, unit(*rot)) * size;
VECTOR3 x = mul (grot, unit(crossp(*dir, *rot))) * size;

D3DXMatrixIdentity(&W);

W._11 = float(x.x);
W._12 = float(x.y);
W._13 = float(x.z);

W._21 = float(y.x);
W._22 = float(y.y);
W._23 = float(y.z);

W._31 = float(z.x);
W._32 = float(z.y);
W._33 = float(z.z);

W._41 = float(pos.x);
W._42 = float(pos.y);
W._43 = float(pos.z);

UINT numPasses = 0;
HR(pDev->SetVertexDeclaration(pPositionDecl)); // Position only vertex decleration
HR(FX->SetValue(eColor, pColor, sizeof(D3DXCOLOR))); // Setup arrow color
HR(FX->SetMatrix(eW, &W));
HR(FX->Begin(&numPasses, D3DXFX_DONOTSAVESTATE));
HR(FX->BeginPass(0));
HR(pDev->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 6, &arrow, sizeof(D3DVECTOR))); // Draw 6 triangles un-indexed
HR(FX->EndPass());
HR(FX->End());
gc->GetStats()->Draw++; // Increment rendering statistics counter
}

See you in RC40 :lol:

Regards,
Kuddel

Last edited:

#### jarmonik

Beta Tester
Thanks, I'll add it in RC40.

I got the Windows and SDKs installed last night but there is still a lot of empty space on the harddrive but it's looking better already.

#### Donamy

Donator
Beta Tester
I get all jagged edges, how can I get the antialiasing working in D3D9 ? It works fine in the regular Orbiter.

---------- Post added at 10:24 PM ---------- Previous post was at 05:00 AM ----------

Downloading an earlier version of RC39, seems to have fixed the jagged edge problem, but not the thruster rendering.

#### jarmonik

Beta Tester
I get all jagged edges, how can I get the antialiasing working in D3D9 ? It works fine in the regular Orbiter.

---------- Post added at 10:24 PM ---------- Previous post was at 05:00 AM ----------

Downloading an earlier version of RC39, seems to have fixed the jagged edge problem, but not the thruster rendering.

In the RC39 the antialiasing settins are located in the Advanced setup panel in a video tab. The antialiasing settings will be disabled if GDI compatibility mode is enabled. But you can still enable the AA from the graphics driver control center even if the GDI compatibility mode is enabled.

Are you using GDI compatibility mode ?

#### Donamy

Donator
Beta Tester
I'm not using GDI mode.

#### jarmonik

Beta Tester
I'm not using GDI mode.
I suppose it could be a hardware auto-detection problem. What kind of options are there in the antialiasing selection menu ?

What kind of hardware you have ?

Last edited:

#### Donamy

Donator
Beta Tester
It is working now, when I downloaded an earlier version of RC39.

#### jarmonik

Beta Tester
Is anyone currently trying to implement the runway lights for the D3D9Client ?
If there is someone working with some new features for this client, then let me know about the project.

#### Felipi1205

##### Spaceflight enthusiast
Nice to see you back! Do you solved the problems with your hard drive?

#### Bibi Uncle

##### 50% Orbinaut, 50% Developer
I've just downloaded the latest code from Bitbucket, and I found some errors.

First, a #define _WIN32_WINNT 0x5001 is needed in D3D9Client.h, D3D9Client.cpp, D3D9Pad.h and D3D9Pad.cpp in order to define some Windows 2000/XP exclusive declarations (Cleartype definitions, TrackMouseEvent, and others). I use Visual Studio 2005, that may be the cause.

Next, in functions D3D9Client::CheckBltGroup, D3D9Client::clbkBlt, D3D9Client::clbkBlt (the second one) and D3D9Client::clbkScaleBlt, the line pBltGrpTgt = surfBltTgt = NULL; should be deleted due to the const-ness of the method. I can't even find how you compiled this...:shrug:

I'm currently working on the runway lights, but I can't garantee anything. I'm in an exam session, so I don't have a lot of time.

What I'm planning to do is to create a RunwayLights class. It will have a static method to load the parameters from the config file and create the RunwayLights (the constructor will be protected). I'll copy the RenderSpot function from vObject to render the beacons. The only problem I already see is how I will calculate which side of the runway the camera is. I need to know that in order to illuminate the right side (rotate the camera around a runway, you'll see what I mean).

Last edited:

#### Face

Beta Tester
I've just downloaded the latest code from Bitbucket, and I found some errors.

If you mean my OVP repository on Bitbucket, please be aware that it is not jarmonik's original work. While I've tried hard to stay true to his ZIP-archives, it is quite possible that I made some errors. Especially the last round of release was a bit unclear to me, as it did not contain changes to the source code, but instead had additional "beta" versions with code diffs. Thus there are two lines in the D3D9Client branch: one default with all the release tags, and one bookmarked "D3D9beta" for all the "beta" versions jarmonik released.

To help fix troubles there, please always quote the hash-code of the version you've checked out. If you downloaded a ZIP from BB, it should come with a .hg_archival.txt file. In this file, you'll find a line starting with "node:" showing the hash-code in question.

regards,
Face

#### jarmonik

Beta Tester
What I'm planning to do is to create a RunwayLights class. It will have a static method to load the parameters from the config file and create the RunwayLights (the constructor will be protected). I'll copy the RenderSpot function from vObject to render the beacons. The only problem I already see is how I will calculate which side of the runway the camera is. I need to know that in order to illuminate the right side (rotate the camera around a runway, you'll see what I mean).

Here is a source code for Orbiter 2010-P1. It's not the latest but should work fine.

That sounds great but using the RenderSpot is a bad idea because it's very slow. The runways are containing hundreds of beacons and we need more elegant way to render them. Also we may want to blur the beacons those are far away from the camera and make them relatively bigger.

I was thinking about creating a new rendering method for beacon arrays:

PHP:
typedef struct {
VECTOR3 pos;  // Position relative to origin of the base
DWORD color;   // 0xAARRGGBB
float size;        // in meters
} BeaconArrayEntry;

BeaconArrayEntry *entries = new BeaconArrayEntry[nbeacons];

// Fill the entries and create the array in base constructor

BeaconArray *array = new BeaconArray(entries, nbeacons);
delete entries[];

array->Render(DWORD start_index, DWORD end_index, float brightness);

Example:
array->Render(0, 100, 1.0f);
array->Render(101, 140, 1.5f);
array->Render(141, 200, 1.0f);
I suppose I could add GetDirection() method in the BeaconArray. It would make easier to enable and disable lights based on camera position.

PHP:
VECTOR3 dir = array->GetDirection();
if (dot(dir, runway_dir) > 0) array->Render(101, 140, 1.5f);
else                          array->Render(201, 240, 1.5f);

Last edited:

#### jarmonik

Beta Tester
Of course, an other and propably better option is to add a light direction and cone angle in the BeaconArrayEntry structure.

PHP:
typedef struct {
D3DXVECTOR3 pos;   // Position relative to origin of the base
D3DXVECTOR3 dir;   // Light direction
DWORD color;         // 0xAARRGGBB
float size;              // in meters
float coneangle;     // Light cone angle in degrees
} BeaconArrayEntry;

#### Bibi Uncle

##### 50% Orbinaut, 50% Developer
@Face: I was using the node 8b4a94a56e17c82f8b9ff49bb9c258721f543505, and I compiled with the 111105 build of Orbiter (some definitions used in the code needed the beta version).

@jarmonik: The BeaconArray::Render would render the beacons pretty much the same as vObject::RenderSpot or you have a faster way to render them? I do not have a lot of experience with Direct3D, so I'm not very good at stuffs like GPU instantiating.

My idea was to separate the base from the runway lights. The base would simply have references to runway lights (if there is two runways on the base, then there'll be two RunwayLights in the array of vBase) and it would call a render method during vBase::RenderStructures, specifing if it is day or night (using vBase::lights variable). So, the filling of the entries of the beacon arrays would be in the RunwayLights class, not in the vBase class.

Last edited:

#### jarmonik

Beta Tester
@jarmonik: The BeaconArray::Render would render the beacons pretty much the same as vObject::RenderSpot or you have a faster way to render them? I do not have a lot of experience with Direct3D, so I'm not very good at stuffs like GPU instantiating.
BeaconArray::Render() would use a static vertex buffer to draw multible beacons with a single draw call to a DirectX. This can be 100 times faster than drawing every beacon independently from a dynamic system memory buffer.

I'll take care of creating the BeaconArray class.

So, the filling of the entries of the beacon arrays would be in the RunwayLights class, not in the vBase class.
Yes, Of course. Sorry, my mistake.