问题标签 [slimdx]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
1132 浏览

c# - 如何使图元在 DirectX (2D) 中正确覆盖精灵

我在 Direct3D9 中渲染精灵和图元时遇到了问题。我正在尝试使用精灵制作一个简单的 2D 游戏,但是我发现我还需要原语来绘制简单的正方形、线条等。问题在于叠加。

如果我只使用 绘制图元Device.DrawUserPrimitives(),一切都很好,图元被正确渲染。如果我只使用 绘制精灵Sprite.Draw(),也可以。但是,如果我想同时绘制精灵和图元,所有精灵都会自动覆盖图元或使它们变黑。

我试过禁用 Z 缓冲区,在渲染精灵时禁用 Z 缓冲区中的写入等,但它总是一样的。我设法通过改变它们的z位置使图元覆盖精灵,但是所有图元都是黑色的...... :(

请注意,我已经尝试在绘制精灵之前和之后渲染图元。它没有帮助。

我将在这里发布一些绘图精灵和原语的片段(变量名称已更改,因此即使您对 C# 和 SlimDX 一无所知,您也可以理解我在绘制什么):

...其中m_fan1是一个包含Vector4 position和的结构,int colorvertexDecl声明了这些顶点元素。

顺便一提:

  1. 如果我将填充模式更改为线框,则可以正确绘制图元的线框。
  2. 如果图元覆盖精灵,图元几乎是黑色的,我绘制的精灵越多,图元越暗。也许它与阿尔法有关?
  3. 在我绘制 sprite 之前,所有图元都被正确渲染。但即使我停止绘制精灵,在我重置应用程序之前,图元将保持暗/黑色。

如果您需要我的源代码的其他片段,请写在这里,我会更新它。

0 投票
1 回答
637 浏览

c# - SlimDX VertexDeclaration 内存泄漏?- 如何避免?

我的 SlimDX / DirectX 应用程序有问题。我有一个使用 SlimDX 制作的循环MessagePump,我的应用程序使用过多的内存时遇到了问题,内存量正在增加。我试图找到我的代码的哪一部分,我发现它可能是这样的:

这部分代码在一个恒定循环 ( MessagePump.Run())中运行,每秒它会多消耗大约 2 MB 的内存

如何避免内存泄漏VertexDeclaration?也许SlimDX 的 VertexDeclaration 的 C++ 源代码有问题?还是我必须定义VertexDeclaration循环的外部?为什么垃圾收集器不处理它?

还有一个与此相关的类似问题:如果我在循环中定义新变量是否有问题,而实际上我只使用它们一次?例如这段代码:

循环运行。这是一个问题,我应该在循环之外定义矩阵 T 和 S,还是垃圾收集器会处理这个问题?我一直在研究几个示例源代码,许多程序员都这样做——但是在循环中运行时它不会使用越来越多的内存吗?

0 投票
2 回答
873 浏览

scaling - 防止 Direct3D 视口图像缩放 (SlimDX)

我在一个窗口中的 SlimDX 中设置了 Direct3D11 场景。渲染在单独的线程中完成。

有没有办法让渲染器在绘制到调整大小的控件时不拉伸图像?我试过ModeDescription.Scaling = DisplayModeScaling.Centered了,好像没什么效果。有什么我想念的吗?

(我已经在更新渲染目标大小。我问这个的原因是,当我调整控件大小时,它会拉伸图像以在渲染目标更新为新大小之前填充控件一瞬间。结果是当我调整它的大小时,它会严重闪烁。如果我可以稍微快一点地重置渲染目标,它可能会消除闪烁。将图像保持在角落而不缩放它是非常好的,因为最终它根本不会缩放。 )

解决方法 1: 可以将渲染目标放在控件中。当窗口调整大小时,仅通过一种特殊方法调整控件的大小,该方法首先停止渲染,然后更新缓冲区并再次开始渲染。不过,这有点骇人听闻。我必须等待渲染周期完成,然后阻止它,然后调整大小,然后解除阻止。

解决方法 2:类似的解决方法是检查渲染循环中的调整大小标志,而不是中断它。渲染器应该能够直接绘制而无需缩放。这在性能方面更容易接受。但是,必须对 UI 线程进行阻塞调用才能执行实际的调整大小。

解决方法 3:与其完全调整控件的大小,不如将其设置为尽可能大,但会被裁剪(在窗口内)。无需调整大小,但必须以与上述解决方法类似的方式维护剪刀矩形,除非您不介意渲染大量屏幕外像素。渲染 20 左右额外的像素行和列确实具有在窗口重新变大时在边缘提供即时图像的有利效果。

理想情况下,调整大小应该直接从 UI 线程完成(不要鬼混延迟它并从渲染线程重新进入 UI 线程)。这不是渲染线程的责任,它会减慢它的速度。同样,缓冲区调整大小应该在渲染线程中完成以获得最佳性能(不要胡乱等待/阻塞/调整大小/解除阻塞)。这不起作用的唯一原因是如果在调整缓冲区大小之前完成调整大小,则渲染线程会缩放。

所以我的问题仍然存在:有没有一种方法可以在不缩放的情况下进行渲染?

0 投票
1 回答
3729 浏览

directx - 如何使用 SlimDX 设置 HLSL 统一变量的值?

我还没有找到这方面的文档,但这可能很简单。我有一个需要更新变量的像素着色器。我唯一接近的是ConstantTable,但它在Direct3D9下,而不是我正在使用的Direct3D11。

将 DirectX11 与 SlimDX 一起使用,我将如何设置着色器中的统一变量的值?

0 投票
1 回答
318 浏览

winforms - 使用 D3D10/11 和 MDI 窗口的性能

我正在开发一个 MDI 应用程序,它可能包含很多(>40)实时(30 fps)更新图;每个图形都必须潜在地在其中渲染 3D 几何图形。我已经尝试使用 SlimDX(在每个窗口上)对每个窗口使用 Direct2D,但是当添加超过 16 个窗口时性能下降非常糟糕。任何人都有这方面的经验,其反馈可能有用吗?

  • 我目前正在使用 D3D10/11 API,根据文档,每个窗口都有一个交换链。在 D3D9 文档中,您可以在演示之前切换窗口,这是推荐的用法。我应该尝试改用 D3D9 吗?会不会是交换链切换问题?
  • 如果这不是交换链问题,对我来说跳过 D2D 并只管理我自己的顶点缓冲区并使用 D3D 渲染会更好吗?

问候!

0 投票
1 回答
807 浏览

directx - 使用 Direct3D 绘制带有圆角末端的线条

有没有办法使用带有圆形结尾的 ID3DXLine 画一条线?我试图从线段数中绘制一条曲线,但得到线段连接的空白区域。这里的性能是必不可少的。

谢谢!


使用 D3D 绘制粗曲线的任何其他快速方法?

0 投票
1 回答
2742 浏览

directx - 多个渲染目标不保存数据

我正在使用 SlimDX,针对带有着色器模型 4 的 DirectX 11。我有一个像素着色器“preProc”,它处理我的顶点并保存三个数据纹理。一个用于每个像素的法线,一个用于每个像素的位置数据,一个用于颜色和深度(颜色占用 rgb,深度占用 alpha 通道)。

然后我稍后在后处理着色器中使用这些纹理以实现屏幕空间环境光遮蔽,但似乎没有数据保存在第一个着色器中。

这是我的像素着色器:

它输出以下结构:

并采用以下结构作为输入:

但是在我的后处理着色器中:

它只是输出一个浅蓝色屏幕(我将渲染目标重置为每帧开始时的颜色)。getCol 已经过测试,可以在仅处理一个渲染目标时从 renderTex 材质返回颜色。如果我将像素着色器更改为对 randomTex 纹理(我的代码之前从文件中加载并且不是渲染目标)进行采样,那么一切都会很好地渲染,所以我确信它不是我的后处理着色器。

如果我的 slimDX 代码失败了,我会这样做:

创建我的纹理、shaderresourvecviews 和 rendertargetviews:

渲染到我的多个渲染目标:

然后是我将 postProcessing 着色器渲染到屏幕时的函数:

编辑:我为当前运行的单帧添加了 PIX 函数调用输出:

EDIT2:我一直在阅读,也许我需要在 preProc 传递之后将纹理作为渲染目标解除分配,然后再将它们作为 ShaderResourceViews 传递给我的 postProcess 着色器。我假设调用 context.OutputMerger.SetTargets() 将释放所有当前分配的渲染目标,然后仅分配函数参数中指定的渲染目标。如果不是这种情况(我还不能确定它是否存在),那么我将如何在 SlimDX 中取消分配渲染目标?

EDIT3:啊,根据这个MSDN Page,调用 OutputMerger.SetRenderTargets() “覆盖所有有界渲染目标和深度模板目标,无论 ppRenderTargetViews 中的渲染目标数量如何。” 所以当我告诉 OutputMerger 渲染到屏幕时,我所有的渲染目标都会自动释放。这让我回到了第一方。

0 投票
2 回答
1662 浏览

directx - 在 IASetVertexBuffers() 上播放错误期间先前成功的 PIX 调用失败

我正在尝试在我编写了一段时间的 SlimDX DirectX11 游戏中调试着色器。代码运行良好并且执行顺利(尽管似乎忽略了我的纹理),当我运行实验以捕获 PIX 中的单个帧时,它执行得很好,但是如果我尝试访问 PIX 中的渲染或网格选项卡以获取我捕获的框架我收到以下错误:

EID 是在我捕获的帧之前发生的(我的帧从 EID 108 开始),所以我看不到它失败的地方。

我决定运行完整的帧流,看看是否会显示错误。这次我得到了一些有用的东西。

以及导致它的事件日志:

输出日志中也没有任何内容。有没有人遇到过这个?如果是这样,您是如何解决的?

0 投票
1 回答
897 浏览

c# - Accessing the data in a SlimDX Texture2D object

How do I access the data in a Texture2D object? Lots of XNA posts suggest using the function Texture2D.GetData but that appears to be missing in the SlimDX version of a Texture2D. I need to process my image to calculate overall luminance of the scene and don't want to be running 300 accesses in a pixel shader (i.e. 300 access * num_pixels per frame) when I could be doing it once per frame.

All I need to be able to do is access the colour (R32G32B32A32) of the texture.

Ah I reckon I've found it thanks to the SlimDX SDK. The Texture2D.ToStream() method sends the texture data to a memory stream, then I simply have to parse the bytes to get at my data. I'll submit this as an answer if it works for me.

0 投票
1 回答
5949 浏览

directx - SlimDX/DirectX9/C# - 如何访问纹理中的像素数据

这是我在 StackOverflow 上的第一个问题,万岁!老实说,我每天都使用 StackOverflow 来解决我的工作和个人编程之谜。99,9% 的时间我实际上也在这里找到了我需要的答案,这太棒了!

我目前的问题实际上让我有点难过,因为我似乎找不到任何真正有效的东西。我已经阅读了 GameDev.net 上的几篇文章,并在网上找到了其他资源,但无法整理出来。

我正在将我为 XNA 编写的小型 2D 引擎移植到 SlimDX(目前只是 DirectX9),这是一个很好的举措,因为我在短短几天内了解了更多关于 DirectX 内部工作的知识,而不是我在与 XNA 合作六个月。我完成了大部分基本渲染功能,并且实际上设法用大量附加功能重新创建了 XNA SpriteBatch(我在 XNA 中真的错过了这些功能)。

我试图开始工作的最后一件事是从给定纹理中提取源矩形并将其用于平铺。原因:不平铺时,您可以随意使用 UV 来获得要显示的源(例如:0.3;0.3 到 0.5;0.5),但是在平铺时,您需要 UV 来平铺(0;0 到 2;2意味着平铺图像两次),因此需要一个剪切纹理。

长话短说,我尝试使用以下内容:

我尝试了不同的像素,但似乎都给出了虚假数据。例如,我实际上尝试使用我当前的头像来查看我从 DataRectangle 获得的缓冲区是否与图像中的实际像素匹配,但没有运气(甚至检查了格式是否正确,它是正确的)。

我究竟做错了什么?有更好的方法吗?或者我的 UV 故事是错误的,它是否可以比在平铺之前切割源矩形更简单?

感谢您的时间,

伦纳德·方泰因

更新#1

我实际上设法使用以下字节数组的转换将像素数据导出到位图:

所以数据似乎并不像我想象的那么虚假。然而,我的下一个问题是抓取源矩形中指定的像素并将它们复制到新纹理中。我要剪切的图像是 150x150,但由于某种原因,它被拉伸为 256x256 图像(2 的幂),但是当实际尝试访问超过 150x150 的像素时,它会引发 OutOfBounds 异常。此外,当我实际尝试创建第二个大小为 256x256 的空白纹理时,无论我在其中放入什么,结果都是完全黑色的。

这是我当前的代码:

所以我的新(附加)问题是:如何将像素从一个纹理移动到另一个较小的纹理,包括 Alpha 通道?当我的原始纹理为 150x150 时,为什么 SurfaceDescription 会报告 256x256?