我正在编程模拟,我想将我的应用程序从使用GDI移植到使用Direct2D.但我的Direct2D代码比我的GDI代码要慢得多.
我在屏幕上渲染了很多椭圆.在我的GDI应用程序中,我绘制到内存设备上下文,然后使用BitBlt在Windows设备上下文中绘制.使用Direct2D,我绘制到ID2D1HwndRenderTarget.
我的问题是,当使用GDI时,我可以轻松绘制400多个椭圆,并且仍然有400 FPS.当我使用Direct2D执行相同数量的省略号时,我的FPS下降到30FPS.
我已经关闭了antialiasing,但它并没有真正帮助.有趣的是,与GDI相比,在Direct2D中绘制几个省略号更快.我可以做些什么来提高Direct2D的性能,还是应该使用GDI保留我的应用程序?
这是我使用GDI的绘图代码:
VOID Begin() {
SelectObject(this->MemDeviceContext, this->MemoryBitmap);
this->BackgroundBrush = CreateSolidBrush(this->BackgroundColor);
HBRUSH OldBrush = (HBRUSH)SelectObject(this->MemDeviceContext, this->BackgroundBrush);
Rectangle(this->MemDeviceContext, -1, -1, 801, 601);
SelectObject(this->MemDeviceContext, OldBrush);
DeleteObject(this->BackgroundBrush);
SetViewportOrgEx(this->MemDeviceContext, 400, 300, &this->OldOrigin);
}
VOID End() {
SetViewportOrgEx(this->MemDeviceContext, this->OldOrigin.x, this->OldOrigin.y, 0);
BitBlt(this->DeviceContext, 0, 0, 800, 600, this->MemDeviceContext, 0, 0, SRCCOPY);
}
Run Code Online (Sandbox Code Playgroud)
在我的Begin和End函数之间,我使用标准的GDI方式绘制省略号.
以下是使用Direct2D的开始和结束函数:
VOID BeginDrawing() {
this->RenderTarget->BeginDraw();
RenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::CornflowerBlue));
RenderTarget->SetTransform(this->ScalingMatrix * this->TranslateMatrix);
}
VOID EndDrawing() {
this->RenderTarget->EndDraw();
}
Run Code Online (Sandbox Code Playgroud)
以下是我如何设置Direct2D接口.这一切都包括在课堂上; 这就是我无法发布完整代码的原因:
if(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &Direct2DFactory) != S_OK)
throw std::runtime_error("RENDERWINDOW::InitializeDirect2D: Failed to create a factory interface.");
RECT …Run Code Online (Sandbox Code Playgroud) 抱歉,这个问题的标题,但我不知道我的问题的正确标题。我有以下代码示例:
struct test {
test(int a) {
}
};
int main() {
test(1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的示例代码有效。现在,我(以我的理解)做了一点不同:
struct test {
test(int a) {
}
};
int main() {
int a = 0;
test(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译此文件时,出现以下错误:
error: redefinition of 'a' with a different type: 'test' vs 'int'
Run Code Online (Sandbox Code Playgroud)
但是我认为当我尝试这样做时,它真的很奇怪:
struct test {
test(int a) {
}
};
int main() {
int a = 0;
test((int)a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的示例再次起作用,并且因为我看不到区别(将int转换为int除外)而使我真正感到困惑。谁能解释这是怎么回事?先感谢您。
嗨我现在用C++写一个win32应用程序,我真的有问题要放大我窗口的内容.这是我开始完成缩放的伪代码:
// point One
int XPointOne = -200;
int YPointTwo = 0;
// point Two
int XPointTwo = 200;
int YPointTwo = 0;
// Draw point function.
DrawPoint(XCoordinate * ScalingFactor, YCoordinate * ScalingFactor) {
....
}
Run Code Online (Sandbox Code Playgroud)
我的坐标系设置为其原点位于窗口的中心.我想在使用鼠标滚轮时进行缩放.上述解决方案的问题在于,始终从窗口中心进行缩放.当你的鼠标不在窗口的中心时,这种看起来很丑陋.我想放大鼠标所在的区域,但我找不到合适的算法来计算x和y方向的偏移量.例如,如果鼠标具有坐标(-200,0)点,则应该具有坐标(-200,0),并且将坐标(600,0)指向两个,比例因子为2.我已经尝试了很多东西,但没有让它工作,特别是当鼠标移动到其他位置之间缩放一切都搞砸了.谁知道如何解决这个问题?
这是我的appliaciton的一些示例代码.第一个片段是我的回调函数,用于处理WM_MOUSEWHEEL消息.
VOID OnMouseWheel(WPARAM const& WParam, LPARAM const& LParam) {
if(GET_WHEEL_DELTA_WPARAM(WParam) > 0)
{
// Zoom in
Draw.ScaleFactor += 0.1;
}
else
{
// Zoom out
}
}
Run Code Online (Sandbox Code Playgroud)
Draw只是一个包装GDI函数的类.它有一个比例因子成员.下面的代码片段是Draw对象的DrawCircle成员函数,使用比例因子在屏幕上正确显示圆圈.
VOID DrawCircle(DOUBLE const& XCoordinate, DOUBLE const& YCoordinate, DOUBLE const& Radius, COLORREF const& Color) {
HBRUSH …Run Code Online (Sandbox Code Playgroud) 编辑:好的我写了一个小测试程序来显示在这里.这是源代码.
main.cpp中:
#include "core.h"
Core core;
int main()
{
core.coreFunction();
}
Run Code Online (Sandbox Code Playgroud)
core.h:
#ifndef CORE_H__
#define CORE_H__
#include "definitions.h"
#include "window.h"
class Core
{
public:
Window window;
void coreFunction()
{
window.windowFunction();
}
};
extern Core core;
#endif
Run Code Online (Sandbox Code Playgroud)
definitions.h
#ifndef DEFINITIONS_H__
#define DEFINITIONS_H__
class Core;
class Window;
#endif
Run Code Online (Sandbox Code Playgroud)
在window.h
#ifndef WINDOW_H__
#define WINDOW_H__
class Window
{
public:
void windowFunction()
{
core.coreFunction();
}
};
#endif
Run Code Online (Sandbox Code Playgroud)
使用此测试程序,我得到以下错误:window.h(10):错误C2065:'core':未声明的标识符.我希望这能澄清我的问题.请忽略这些函数对于显示我所做的事情没有任何意义,因为我的原始代码是在此处发布的方式.
我真的很难理解SetThreadAffinityMask函数.我试图用QueryPerformanceCounter函数实现一个计时器,但我不明白如何正确获得线程关联.msdn上的一个人发布了以下代码示例:
void HRTimer::StartTimer(void)
{
DWORD_PTR oldmask = ::SetThreadAffinityMask(::GetCurrentThread(), 0);
::QueryPerformanceCounter(&start);
::SetThreadAffinityMask(::GetCurrentThread(), oldmask);
}
Run Code Online (Sandbox Code Playgroud)
但是当我采用这个代码片段时,SetThreadAffinityMask返回的oldmask的值为零.在MSDN上,我看到返回值为零意味着发生了错误.我调用了GetLastError()并获得了ERROR_INVALID_PARAMETER的错误代码.现在我想知道上面的代码片段是否正确.有人可以解释一下如何正确使用SetThreadAffinityMask,以便例如只在系统上的第一个CPU上调用QueryPerformanceCounter吗?或者上面的例子是否正确,尽管SetThreadAffinityMask返回零?
先感谢您.