Direct3d9 Create a Const RECT for Present() - directx

Im just started programming with Direct3d9
so
i want just create a Rect
mydevice->->Present(NULL, NULL, NULL, NULL);
i dont want use NULL in Present fonction because a want create a rectangle for my surface Direct3d9.
i want create a window with botton and direct3d surface like 3Dsmax (4 surface and botton in left), so please how i can create this Rectangle ?
Rect r;
...
r.top;
r.left;
...
this rectangle return a LONG value and i need a Const RECT that i can set it in Present() fonction, so please how i can do that ?

Most of the time, you don't need to pass a rect to function present, unless your swap chain was created with D3DSWAPEFFECT_COPY.
If you want just want to draw subwindows like 3ds max, you should try multiple view or multiple windows in DirectX.
You won't specify any geometry in present, this function just present the content in backbuffer to the display, you should prepare everything you want to draw before calling this function.

Related

Draw dropshadow using Direct2D

I need to render a dropshadow of bitmap A onto bitmap B using Direct2D.
More specifically, A is 32-bit with alpha-transparency, i.e. some pixels can be transparent. B (also 32-bit) contains another image, i.e. it can't be assumed empty.
Can someone provide a working example of how to do that?
Preferably as a method that takes blur amount, distance, color and opacity of the dropshadow as parameters.
The C++ code I'm trying to convert is the below from MS. But I'm not sure about converting the C++ syntax and also the D2D2 libraries in Delphi XE2 seem to be incomplete.
ComPtr<ID2D1Effect> shadowEffect;
m_d2dContext->CreateEffect(CLSID_D2D1Shadow, &shadowEffect);
shadowEffect->SetInput(0, bitmap);
// Shadow is composited on top of a white surface to show opacity.
ComPtr<ID2D1Effect> floodEffect;
m_d2dContext->CreateEffect(CLSID_D2D1Flood, &floodEffect);
floodEffect->SetValue(D2D1_FLOOD_PROP_COLOR, D2D1::Vector4F(1.0f, 1.0f, 1.0f, 1.0f));
ComPtr<ID2D1Effect> affineTransformEffect;
m_d2dContext->CreateEffect(CLSID_D2D12DAffineTransform, &affineTransformEffect);
affineTransformEffect->SetInputEffect(0, shadowEffect.Get());
D2D1_MATRIX_3X2_F matrix = D2D1::Matrix3x2F::Translation(20, 20));
affineTransformEffect->SetValue(D2D1_2DAFFINETRANSFORM_PROP_TRANSFORM_MATRIX, matrix);
ComPtr<ID2D1Effect> compositeEffect;
m_d2dContext->CreateEffect(CLSID_D2D1Composite, &compositeEffect);
compositeEffect->SetInputEffect(0, floodEffect.Get());
compositeEffect->SetInputEffect(1, affineTransformEffect.Get());
compositeEffect->SetInput(2, bitmap);
m_d2dContext->BeginDraw();
m_d2dContext->DrawImage(compositeEffect.Get());
m_d2dContext->EndDraw();

FMX Change Coordinate System

I want to change Delphi FMX's coordinate system (for visual controls like TImage, TPaintBox, etc) to use Cartesian coordinate system (Bottom Left)
How can I do this?
This is very basic for GDI:
HDC hDC = this->Canvas->Handle;
SetMapMode(hDC, MM_LOENGLISH); //Change coordinate system
SetViewportOrgEx(hDC, 300, 200, NULL); //Change origin
Coordinate point change sample for Delphi FMX:
Image1.Position.Point := PointF(250, 250);
I've just noticed one can set a negative scale (at one or both axes) in FMX resulting in flipping things in the respective axes coordinates.
So to reverse the Y axis you need to do
SomeContainer.Scale.Point := TPointF.Create(0, -1);
after that you'd also need to offset though, but could do it by offseting a parent control by (-width/2, -height/2) I guess

Drawing rectangle with canvas

With this code I want to draw a rectangle:
procedure TForm1.Button1Click(Sender: TObject);
var rectangle:Trect;
begin
fx:=400;
fy:=400;
sc1:=base/fx;
sc2:=altezza/fy;
sc:=max(sc1, sc2);
lx:=fx*sc;
ly:=fy*sc;
xc:=base/2;
yc:=altezza/2;
x1:=xc-(lx/2); x2:=xc+(lx/2); y1:=yc-(ly/2); y2:=yc+(ly/2);
panel1.Repaint;
panel1.Canvas.Brush.color:= clblack;
panel1.Canvas.line((panel1.width div 2),0,(panel1.Width div 2), panel1.Height);
panel1.Canvas.line(0,(panel1.height div 2), panel1.Width,(panel1.Height div 2));
panel1.canvas.brush.style:=bsclear;
Rectangle:=rect(x1, y1, x2, y2);
end;
But there is a problem because I have to use only integer values.
Is it possible to use real values for drawing a rectangle with TCanvas?
The simple answer is no. Graphic devices as represented by TCanvas use a coordinate system with integral coordinates. If your coordinates are real values then you need to use some form of mapping between your coordinate system and the integral device coordinates.
However, in this instance it looks like it's not that complex. You don't need real valued coordinates per se. You only have real values because you used real division. Perhaps all you need to do is use integer division, div, rather than real division. Or perhaps you would prefer Round.
A bigger problem is that your code is in the wrong place. You cannot paint in a button handler. Windows will not remember what you painted. The next time the window is invalidated it will ask the panel to refresh itself, and your rectangle will be gone. Painting code needs to be inside an overriden Paint method or equivalent. Perhaps you need a paint box control.

Teechart Custom Lengend tool

I want to show a table for Box Plot containing Values such as mean Median , S.D , Range etc.
The Data Table tool shows only X, X2 data doesn't allow for customization data.I am trying too use Custom Legend Tool using which we can create Table specifying Grid Row and Column. Can anyone let me know how we can enter data into the table.
Thanks
Akshay
If I'm not wrong, you are using VC++. The CustomLegend tool is a quite new tool and I'm afraid there are some features missing in it for VC++.
I've added it to the wish list to be implemented in future releases (TA05015410/B395).
In the meanwhile, note TeeChart ActiveX supports custom drawing so you can manually draw your table if the other tools in the component don't allow you to draw what you exactly want to.
Custom drawing techniques basically consist on a set of methods and properties (set the Canvas Pen, Brush and Font, and draw lines, shapes or texts) to draw directly onto the canvas. These methods are commonly called at the OnAfterDraw event so the custom drawing can be redone after each repaint.
You can find examples written in VC++ under the \Examples\Visual C++\Version 6\ folder in your TeeChart ActiveX installation. Concretely, you can see a simple example of how to use custom drawing techniques in the Dragging Points project. In the DraggingDlg.cpp file you can see how some custom drawing techniques are used in the OnAfterDraw method:
void CDraggingDlg::OnAfterDrawTChart()
{
// Draw a white circle around the clicked pyramid...
if (-1 != m_ClickedBar)
{
CCanvas aCanvas = m_ctrlChart.GetCanvas();
CPen1 aPen = aCanvas.GetPen();
aPen.SetColor(RGB(255, 255, 255));
aPen.SetWidth(1);
aPen.SetStyle(psDot);
aCanvas.GetBrush().SetStyle(bsClear);
int x = m_ctrlChart.Series(0).CalcXPos(m_ClickedBar);
int y = m_ctrlChart.Series(0).CalcYPos(m_ClickedBar);
aCanvas.Ellipse(x, y, x + 40, y + 40);
}
}

Missing depth info after first mesh

I'm using SlimDX for a Direct3D 10 apps. In the apps I've loaded 2 to more mesh, with images loaded as texture and using a fx code for shader. The code was modified from SlimDX's sample "SimpleModel10"
I move the draw call, shader setup code into a class that manage 1 mesh, shader (effect) and draw call. Then I initialize 2 copy of this class, then call the draw function one after another.
The output, no matter how I change the Z position of the mesh, the one being draw later will always stay on top. Later, when I use PIX to debug the draw call, I found out that the 2nd mesh doesn't have depth while the first one does. I've tried with 3 meshes, 2nd and 3rd one will not have depth too. The funny thing is all of then are instantiated from the same class, using the same draw call.
What could have cause such problem?
Following is part of the code in the draw function of the class, I've omitted the rest as it's lengthy involved a few classes. I keep the existing OnRenderBegin() and OnRenderEnd() of the sample:
PanelEffect.GetVariableByName("world").AsMatrix().SetMatrix(world);
lock (this)
{
device.InputAssembler.SetInputLayout(layout);
device.InputAssembler.SetPrimitiveTopology(PrimitiveTopology.TriangleList);
device.InputAssembler.SetIndexBuffer(indices, Format.R32_UInt, 0);
device.InputAssembler.SetVertexBuffers(0, binding);
PanelEffect.GetTechniqueByIndex(0).GetPassByIndex(0).Apply();
device.DrawIndexed(indexCount, 0, 0);
device.InputAssembler.SetIndexBuffer(null, Format.Unknown, 0);
device.InputAssembler.SetVertexBuffers(0, nullBinding);
}
Edit: After much debugging and code isolation, I found out the culprit is Font.Draw() in my DrawString() function
internal void DrawString(string text)
{
sprite.Begin(SpriteFlags.None);
string[] texts = text.Split(new string[] {"\r\n"}, StringSplitOptions.None);
int y = PanelY;
foreach (string t in texts)
{
font.Draw(sprite, t, new System.Drawing.Rectangle(PanelX, y, PanelSize.Width, PanelSize.Height), FontDrawFlags.SingleLine, new Color4(Color.Red));
y += font.Description.Height;
}
sprite.End();
}
Comment out Font.Draw solve the problem. Maybe it automatically set some states which causes the next Mesh draw to discard depth. Looking into SlimDX's source code now.
After much debugging in PIX, this is the conclusion.
Calling Font.Draw() will automatically set DepthEnable to false and DepthFunction to D3D10_COMPARISON_NEVER, that's after comparing PIX's detail on the OutputMerger of before and after calling Font.Draw
Solution
Context10_1.Device.OutputMerger.DepthStencilState = depthStencilState;
Put that before the next Mesh draw call fixed the problem.
Previously I only set the DepthStencilState in the OnRenderBegin()

Resources