Direct2D - 没有任何内容被绘制到屏幕上,我在 C++ 中处理数组的方式出了问题。
大家好,感谢您的浏览。这是对发布的原始问题的后续 此处。
我有一个这样定义的基类:
class DrawableShape
{
public:
virtual HRESULT DrawShape(ID2D1HwndRenderTarget* m_pRenderTarget)
{
return S_OK;
}
};
我有两个扩展该类的类,两者都很相似,所以我列出一个:
class MyD2DEllipse : public DrawableShape
{
private:
D2D1_ELLIPSE data;
public:
MyD2DEllipse();
HRESULT DrawShape(ID2D1HwndRenderTarget* m_pRenderTarget);
};
DrawShape 函数的实现如下:
HRESULT MyD2DEllipse::DrawShape(ID2D1HwndRenderTarget* m_pRenderTarget)
{
HRESULT hr = E_FAIL;
ID2D1SolidColorBrush* m_pBrush;
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::OrangeRed),
&m_pBrush
);
m_pRenderTarget->DrawEllipse(&data, m_pBrush, 10.f);
return hr;
}
我想绘制随机数量的椭圆和矩形屏幕上,所以我首先找出这些随机数,创建一个具有该大小的 DrawableShape 数组(因为我无法在 C++ 中动态分配对象),用子对象替换父对象,然后调用绘图函数数组,再次随机。我的代码如下所示:
HRESULT Demo::OnRender()
{
HRESULT hr = S_OK;
hr = CreateDeviceResources();
if (SUCCEEDED(hr))
{
m_pRenderTarget->BeginDraw();
m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
// Decide on # of primitives
randEllipse = 1 + (rand() % 5);
randRectangle = 1 + (rand() % 5);
totalPrimitives = randEllipse + randRectangle;
DrawableShape *shapes;
shapes = new MyShape[totalPrimitives];
for (int i=0; i<randEllipse; i++)
{
MyEllipse ellipse1;
shapes[i] = ellipse1;
}
for (int i=randEllipse; i<(randEllipse + randRectangle); i++)
{
MyRectangle rect1;
shapes[i] = rect1;
}
for (int i=0; i<totalPrimitives; i++)
{
hr = shapes[i].DrawMyShape(m_pRenderTarget);
}
hr = m_pRenderTarget->EndDraw();
}
}
这应该有效,但事实并非如此。另外,写完后,我意识到最好在某种 init 函数中创建数组,并在 OnRender 函数中调用数组上的绘制。请帮忙!!
编辑:好的,我已经有了与指针一起使用的形状,问题是数组的构造。所以我有这样的想法:
MyD2DRectangle rect1;
MyD2DEllipse ell1;
DrawableShape *shape1 = &rect1;
DrawableShape *shape2 = &ell1;
shape1->DrawShape(m_pRenderTarget);
shape2->DrawShape(m_pRenderTarget);
这似乎本身就有效。如何在不切片的情况下创建 DrawableShape 数组?
Hello everyone and thank you for looking. This is a follow up to the original question posted here.
I have a base class that I define thusly:
class DrawableShape
{
public:
virtual HRESULT DrawShape(ID2D1HwndRenderTarget* m_pRenderTarget)
{
return S_OK;
}
};
I have two classes that extend this class, both are similar, so I'm listing one:
class MyD2DEllipse : public DrawableShape
{
private:
D2D1_ELLIPSE data;
public:
MyD2DEllipse();
HRESULT DrawShape(ID2D1HwndRenderTarget* m_pRenderTarget);
};
The DrawShape function is implemented like this:
HRESULT MyD2DEllipse::DrawShape(ID2D1HwndRenderTarget* m_pRenderTarget)
{
HRESULT hr = E_FAIL;
ID2D1SolidColorBrush* m_pBrush;
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::OrangeRed),
&m_pBrush
);
m_pRenderTarget->DrawEllipse(&data, m_pBrush, 10.f);
return hr;
}
I want to draw a random number of ellipses and rectangles to the screen, so I first find out those random numbers, create an array of DrawableShape with that size (since I can't allocate objects dynamically in C++), replace the parent objects with the child objects, and then call the draw function on the array, randomly again. Here's what my code looks like:
HRESULT Demo::OnRender()
{
HRESULT hr = S_OK;
hr = CreateDeviceResources();
if (SUCCEEDED(hr))
{
m_pRenderTarget->BeginDraw();
m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
// Decide on # of primitives
randEllipse = 1 + (rand() % 5);
randRectangle = 1 + (rand() % 5);
totalPrimitives = randEllipse + randRectangle;
DrawableShape *shapes;
shapes = new MyShape[totalPrimitives];
for (int i=0; i<randEllipse; i++)
{
MyEllipse ellipse1;
shapes[i] = ellipse1;
}
for (int i=randEllipse; i<(randEllipse + randRectangle); i++)
{
MyRectangle rect1;
shapes[i] = rect1;
}
for (int i=0; i<totalPrimitives; i++)
{
hr = shapes[i].DrawMyShape(m_pRenderTarget);
}
hr = m_pRenderTarget->EndDraw();
}
}
That should've worked, but it doesn't. Also, after writing this out, I realize that I'm better off creating the array in some sort of init function, and calling the draw on the array in the OnRender function. Please help!!
EDIT: Okay I've got the shapes working with pointers, the problem is the construction of the array. So I have something like this:
MyD2DRectangle rect1;
MyD2DEllipse ell1;
DrawableShape *shape1 = &rect1;
DrawableShape *shape2 = &ell1;
shape1->DrawShape(m_pRenderTarget);
shape2->DrawShape(m_pRenderTarget);
That seems to work by itself. How can I create the array of DrawableShape without slicing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
shapes
是MyShape
实例的数组。当您说shapes[i] = ellipse1;
或shapes[i] = rect1;
时,您将丢失子类数据作为此分配的一部分,这称为 < a href="https://stackoverflow.com/questions/274626/what-is-the-slicing-problem-in-c">C++ 中的切片。因此,每次调用
shapes[i].DrawMyShape(m_pRenderTarget);
都会返回S_OK
,如MyShape
中所定义。为了在 C++ 中正确使用多态性,您需要使用对 MyShape 实例的指针或引用(通常使用 new 进行分配)。如果不允许你这样做(作业?),那么你需要找到一种无需多态性的方法来做到这一点。
shapes
is an array ofMyShape
instances. When you sayshapes[i] = ellipse1;
orshapes[i] = rect1;
, you are losing the subclass data as part of this assignment, which is known as slicing in C++.As such, each call to
shapes[i].DrawMyShape(m_pRenderTarget);
is just returningS_OK
as defined inMyShape
.In order to properly use polymorphism in C++, you need to use pointers or references to
MyShape
instances (usually allocated usingnew
). If you are not allowed to do this (homework?), then you need to find a way to do this without polymorphism.