我一直在关注一本关于 D3D11 游戏编程基础知识的书。我现在了解了 Direct3D 的绝对基础知识:)
但是...我有一个问题。在书中,我总是必须一次制作一个演示。现在,我正在尝试用它制作一个 2D 游戏。因为我不想养成坏习惯,所以我需要你的建议。
在书中,我总是必须定义一个(具有 texcoord 和位置成员的 struct VertexPos)或(仅具有 XMFLOAT3 位置成员的 struct VertexPos)。在我正在制作的游戏中,我希望能够绘制没有纹理的实体表面和有纹理的表面。我不知道如何做到这一点,更不用说有效地做到这一点了。
这是我的渲染函数:
void GameSpriteDemo::Render()
{
if (m_pD3DContext == 0)
{return;}
float ClearColor[4] = {0.0f, 0.0f, 0.25f, 1.0f};
m_pD3DContext->ClearRenderTargetView(m_pBackBufferTarget,ClearColor);
UINT stride = sizeof(VertexPos);
UINT offset = 0;
m_pD3DContext->IASetInputLayout(m_pInputLayout);
m_pD3DContext->IASetVertexBuffers(0,1,&m_pVertexBuffer, &stride, &offset);
m_pD3DContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
m_pD3DContext->VSSetShader(m_pSolidColorVS,0,0);
m_pD3DContext->PSSetShader(m_pSolidColorPS,0,0);
m_pD3DContext->PSSetShaderResources(0,1,&m_pColorMap);
m_pD3DContext->PSSetSamplers(0,1,&m_pColorMapSampler);
for(int i=0; i < 2; ++i)
{
XMMATRIX world = m_Sprites[i].GetWorldMatrix();
XMMATRIX mvp = XMMatrixMultiply( world, m_VpMatrix );
mvp = XMMatrixTranspose(mvp);
m_pD3DContext->UpdateSubresource(m_pMvpCB,0,0,&mvp,0,0);
m_pD3DContext->VSSetConstantBuffers(0,1,&m_pMvpCB);
m_pD3DContext->Draw(6,0);
}
m_pSwapChain->Present(0,0);
}
Run Code Online (Sandbox Code Playgroud)
那么,我应该如何使用多个顶点缓冲区、输入布局、着色器、混合器等有效地处理这个问题?
我是否应该创建这些版本的多个版本,然后在 …
我对用GDI渲染图形有点新意...
我做了一个绘画程序,它运行正常,只是它导致了很多烦人的屏幕闪烁.我承认我的油漆代码并没有真正优化(缺乏时间),但它也不应该超级低效,所以我很困惑.
我基本上做的是在init上创建兼容的DC,然后创建兼容的位图.然后我将其选择到兼容的DC中,并绘制到兼容的DC.然后我使用BitBlit()将其复制到窗口hDC ...
谁能告诉我这个屏幕撕裂的可能原因?编辑:顺便说一句,屏幕闪烁只发生在绘制路径期间(在路径被绘制到hMemDC之前,它被绘制到窗口的hDC)
代码示例:(编辑:如果您需要查看您认为相关的更多代码,请注释,我将编辑)
bool Path::DrawTo(HDC hDC)
{
if(hDC == NULL || m_PointVector.size() <= 0) {
return false;
}
switch (m_Tool) {
case Tool_Pen:
{
Point2D p = m_PointVector.at(0);
if(m_PointVector.size() > 1) {
HPEN oldPen = (HPEN)SelectObject(hDC,m_hPen);
MoveToEx(hDC, p.x, p.y, nullptr);
for(UINT i = 1; i < m_PointVector.size(); ++i) {
p = m_PointVector.at(i);
LineTo(hDC,p.x,p.y);
}
SelectObject(hDC,oldPen);
break;
} //else
SetPixel(hDC,p.x-1,p.y,m_Col);
SetPixel(hDC,p.x,p.y,m_Col);
SetPixel(hDC,p.x+1,p.y,m_Col);
SetPixel(hDC,p.x,p.y-1,m_Col);
SetPixel(hDC,p.x,p.y+1,m_Col);
break;
}
case Tool_Line:
{
if(m_PointVector.size() > 1) {
Point2D p = …Run Code Online (Sandbox Code Playgroud) 我想用我自己的结构'Point2'作为键来制作一个地图,但是我得到了错误,我不知道是什么导致了它,因为我为Point2结构声明了一个'operator <'.
码:
std::map<Point2, Prop*> m_Props_m;
std::map<Point2, Point2> m_Orders;
struct Point2
{
unsigned int Point2::x;
unsigned int Point2::y;
Point2& Point2::operator= (const Point2& b)
{
if (this != &b) {
x = b.x;
y = b.y;
}
return *this;
}
bool Point2::operator== (const Point2& b)
{
return ( x == b.x && y == b.y);
}
bool Point2::operator< (const Point2& b)
{
return ( x+y < b.x+b.y );
}
bool Point2::operator> (const Point2& b)
{
return ( x+y > b.x+b.y ); …Run Code Online (Sandbox Code Playgroud) 我将要编写的下几行来自"C++标准库 - 教程和参考"一书.
使用标准输入初始化:
//read all integer elements of the deque from standard input
std::deque<int> c((std::istream_iterator<int>(std::cin)),
(std::istream_iterator<int>()));
Run Code Online (Sandbox Code Playgroud)
不要忘记初始化程序参数周围的额外括号.否则,此表达式会执行一些非常不同的操作,您可能会在以下语句中收到一些奇怪的警告或错误.考虑在没有额外括号的情况下编写语句:
std::deque<int> c(std::istream_iterator<int>(std::cin),
std::istream_iterator<int>());
Run Code Online (Sandbox Code Playgroud)
在这种情况下,c声明一个返回类型为deque的函数.它的第一个参数是类型为istream_iterator,名称为cin,其第二个未命名参数的类型为"不带参数的函数返回istream_iterator".此构造在语法上作为声明或表达式有效.因此,根据语言规则,它被视为声明.额外的括号强制初始化程序不匹配声明的语法.
我可以看到为什么带有额外括号的那个不被认为是一个函数声明,但我看不出是什么会使一个没有成为函数声明呢?因为它有括号(std::cin),据我所知,变量可能没有带括号的名字?
我错过了什么吗?
这篇文章:http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf(第12页)似乎在锁和内存屏障之间有所不同
我想知道锁,内存屏障和信号量之间的区别是什么?
(虽然其他问题可能会提到锁和同步对象之间的区别,但我没有发现锁和内存屏障之间的区别)
我一直被告知我们不应该通过参考传递POD.但最近我发现一个引用实际上根本没有内存.
那么为什么我们选择写:
void DoSomething(int iNumber);
Run Code Online (Sandbox Code Playgroud)
代替:
void DoSomething(const int& riNumber);
Run Code Online (Sandbox Code Playgroud)
是不是更有效率?
我很确定这是一个愚蠢的新手问题,但我不知道,所以我不得不问...
为什么我们使用数据结构,如链接列表,二进制搜索树等?(当不需要动态分配时)
我的意思是:如果我们为单个对象保留一个变量,它会不会更快?这不会加快访问时间吗?例如:BST可能必须首先运行一些指针才能获得实际数据.
除了需要动态分配的时候,是否有理由使用它们?
例如:在可以使用简单(非动态)数组的情况下使用链表/ BST/std :: vector.
为了使这篇文章更有建设性,让它可能在将来帮助其他人:
问题是这样的:
std::map<Point2, Prop*> mm;
std::pair<Point2, Prop*> p;
if(Keydown(VK_LBUTTON)) {
p.first = pos; p.second = new Prop();
mm.insert(p))
}
Run Code Online (Sandbox Code Playgroud)
因此,即使迭代地迭代并最终释放所有Prop*指针,有时插入也会失败(因为具有相同键的一对可能已经存在于树中).这意味着创建的新Prop()将变为孤立.
解决方案:
1)要么总是使用std :: shared_ptr(可能是最好的解决方案)
2)或这样做:
std::map<Point2, Prop*> mm;
std::pair<Point2, Prop*> p;
if(Keydown(VK_LBUTTON)) {
p.first = pos; p.second = new Prop();
if(mm.insert(p).second == false) {
delete p.second;
}
}
Run Code Online (Sandbox Code Playgroud)
感谢SO用户parapura rajkumar
我的应用程序中有内存泄漏,我不知道是什么导致它们!我以为我要解除我所要做的一切.奇怪的是:每次我运行我的应用程序时都没有内存泄漏.
简而言之,这就是我的应用程序所做的:
在初始化时,它会创建numRows时间numColumns new Tile()内TileList.当鼠标悬停在屏幕上的某些位置,鼠标左键举行,它增加了一个std::pair<Point2, Prop*> p,用p.second = new Prop()一个std::map.
有时我可以添加一大堆道具并退出应用程序而不会有任何泄漏.有时我会像以前一样添加相同的道具,退出时会出现内存泄漏.
请帮忙.这是相关代码:
如果您需要查看我的代码的特定部分,只需对其进行评论,我将编辑该问题
PropList.h
class …Run Code Online (Sandbox Code Playgroud) 我想知道我是否可以在头文件中定义一些函数然后在同一个头文件中使用它们,同时将它们隐藏在其他任何东西中?
例如,我可以首先定义一些通用辅助函数(特定于数据结构),然后在使用这些函数的同一个头中定义一些数据结构吗?
例如:
template<class T>
void Swap(T &a, T &b)
{
T temp = a;
a = b;
b = temp;
}
Run Code Online (Sandbox Code Playgroud)
但我不想Swap()干涉其他具有相同名称的功能.
我可以把它变成一个私有方法,但是我必须为每个使用它的类提供相同的实现,或者让它们成为朋友类...
我正在学习哈希表,试图理解它们是如何工作的.我想用一个单独的链接(使用数组中的列表)制作一个相当简单的哈希表.我有几个问题:
假设密钥可以是任何类型,我会要求用户实现散列函数,对吧?这可以避免吗?
用户还需要在初始化时提供包含列表(用于冲突)的数组的长度,对吗?这可以避免吗?
如果您有任何其他提示,或者在C++的哈希表中有一些明确的代码示例,我将非常感激.
谢谢你的帮助.