标签: directx-9

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 dataRectangle = sprite.Texture.LockRectangle(0, LockFlags.None);
Format format = sprite.Texture.GetLevelDescription(0).Format;

byte[] buffer = new byte[4];
dataRectangle.Data.Read(buffer, ([y] * dataRectangle.Pitch) + ([x] * 4), buffer.Length);
texture.UnlockRectangle(0);
Run Code Online (Sandbox Code Playgroud)

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

我究竟做错了什么?有没有更好的方法呢?或者我的紫外线故事是错误的,它可以解决比平铺之前切割源矩形更简单吗?

感谢您的时间,

Lennard Fonteijn

更新#1

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

int pixel = (buffer[0] & 0xFF) | ((buffer[1] & 0xFF) << 8) | ((buffer[2] & 0xFF) << 16) | ((255 - buffer[3] & 0xFF) << 24);
Run Code Online (Sandbox Code Playgroud)

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

这是我目前的代码:

//Texture texture = 150x150
DataRectangle dataRectangle = texture.LockRectangle(0, LockFlags.None);
SurfaceDescription surface …
Run Code Online (Sandbox Code Playgroud)

directx slimdx directx-9

5
推荐指数
1
解决办法
5511
查看次数

将c ++应用程序从Directx9移植到Directx10之前的重要读取

我正处于在我们的软件中启动大型重构循环的边缘.目前,渲染组件仍然基于DX9.新版本将使用DX10.

在我开始之前,是否有关于将DX9移植到DX10的重要且写得很好的指南或概述?我找到了一些小信息,但找不到任何写得好的帖子,指南或概述.我想防止自己制造"经典"错误,我可以通过阅读来防止这种错误,然后再开始移植.

我的目的是阅读"通用"移植指南以及更具体的示例.该软件既可以渲染网格也可以渲染卷,因此非常感谢有关这些主题的信息.其他关键字 - 但不仅限于 - :缓冲区,内存管理和多GPU.

c++ porting directx-10 directx-9

5
推荐指数
1
解决办法
2012
查看次数

如何使用DirectX从后台缓冲区获取桌面的屏幕截图

我问如何在DirectX中拍摄屏幕截图并回答"使用GetFrontBufferData()".但是,MSDN中描述了"这个功能非常慢,按设计,不应该用于任何性能关键路径" .

当我向其他人询问测量时,"将后缓冲器的数据传输到系统存储器"得到了回答.但是,我无法找到具体的方法.

这是一个失败的例子.请让我知道正确的代码.

#include <stdio.h>
#include <Windows.h>
#include <d3d9.h>
#include <d3dx9tex.h>

void main()
{
    CoInitialize(NULL);

    HWND hwnd = GetDesktopWindow();

    LPDIRECT3D9 d3d9;
    D3DDISPLAYMODE ddm;

    d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
    d3d9->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&ddm);

    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS));
    d3dpp.Windowed = TRUE;
    d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
    d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
    d3dpp.BackBufferCount = 1;
    d3dpp.BackBufferWidth = ddm.Width;
    d3dpp.BackBufferHeight = ddm.Height;
    d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
    d3dpp.MultiSampleQuality = 0;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
    d3dpp.hDeviceWindow = hwnd;
    d3dpp.Flags = D3DPRESENTFLAG_VIDEO;
    d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;

    LPDIRECT3DDEVICE9 dev;
    d3d9->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, …
Run Code Online (Sandbox Code Playgroud)

directx desktop screenshot capture directx-9

5
推荐指数
1
解决办法
4619
查看次数

类型或名称空间名称“ directx”在名称空间“ microsoft”中不存在

我一直在尝试将DirectX包含在C Sharp项目(Visual Studio 2010)中。我安装了DirectX SDK,并将组件包括为:

using Microsoft.DirectX;
using Microsoft.DirextX.Direct3D;
Run Code Online (Sandbox Code Playgroud)

尝试编译时,出现错误:类型或名称空间名称“ directx”在名称空间“ microsoft”中不存在

一些博客提到我需要在“ .NET”选项卡下添加“引用”-Microsoft.DirectX。但我找不到那边。没有任何工具可以将其添加到选项卡。

任何建议将不胜感激。

c# directx visual-studio-2010 directx-9

5
推荐指数
1
解决办法
6433
查看次数

在Direct X中绘制一个矩形

在这里使用教程,我设法在屏幕上显示一个红色三角形:http://www.directxtutorial.com/Lesson.aspx?freeonid = 9-4-4

CUSTOMVERTEX OurVertices[] =
{
    { 0, 0, 0, 1.0f, D3DCOLOR_XRGB( 127, 0, 0 ) },
    { WIDTH, 0, 0, 1.0f, D3DCOLOR_XRGB( 127, 0, 0 ) },
    { 0, 300, 0, 1.0f, D3DCOLOR_XRGB( 127, 0, 0 ) },
    { WIDTH, 300, 0, 1.0f, D3DCOLOR_XRGB( 127, 0, 0 ) }
};

d3dDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),
    0,
    CUSTOMFVF,
    D3DPOOL_MANAGED,
    &vBuffer,
    NULL);

VOID* pVoid;    // the void* we were talking about

vBuffer->Lock(0, 0, (void**)&pVoid, 0);    // locks v_buffer, the buffer we …
Run Code Online (Sandbox Code Playgroud)

c++ vertex directx-9

5
推荐指数
1
解决办法
1万
查看次数

Windows 8上禁用了D​​irectX控制面板上的某些选项

我在Windows 8上使用DirectX 9.0,当我打开DirectX控制面板时,我发现一些选项被禁用,我作为管理员运行,所以这不是特权问题.为什么会这样?我无法打开调试版本运行时,因为它已被禁用.见下图.我使用的SDK是2010年6月

在此输入图像描述

directx directx-9 windows-8

5
推荐指数
1
解决办法
5998
查看次数

使用DirectX在Windows上捕获屏幕

我正在尝试在窗口上捕获屏幕的方法,从而决定最快的方法.最常见的是GDI方式.而且性能也不错.根据系统负载和静态/非静态屏幕内容,屏幕捕获率范围为27-47 fps(Windows 7,Intel i5 @2.6 GHz,8 GB RAM).

现在,使用DirectX前端缓冲区方法(使用GetFrontBufferData()API),性能相当,但稍微偏慢(我无法达到48 fps).

我仔细阅读了这篇文章:屏幕截图的最快方法,并尝试使用getRenderTarget()和getRenderTargetData()在接受的答案中建议,但正如评论中所建议的,我得到的只是一个黑色图像.这是我的完整代码,包括设备的初始配置:

    IDirect3DSurface9* pRenderTarget=NULL;
    IDirect3DSurface9* pDestTarget=NULL;
    // sanity checks.
    if (g_pd3dDevice == NULL){
      return;
    }
    HRESULT hr;
    // get the render target surface.
    hr = g_pd3dDevice->GetRenderTarget(0, &pRenderTarget);
    // get the current adapter display mode.
    //hr = pDirect3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&d3ddisplaymode);

    // create a destination surface.
    hr = g_pd3dDevice->CreateOffscreenPlainSurface(1600, 900, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pDestTarget, NULL);
   //copy the render target to the destination surface.
   hr = g_pd3dDevice->GetRenderTargetData(pRenderTarget, pDestTarget);

   D3DLOCKED_RECT lockedRect;
   hr =pDestTarget->LockRect(&lockedRect,NULL, D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY);

    for( int …
Run Code Online (Sandbox Code Playgroud)

c c++ windows directx directx-9

5
推荐指数
1
解决办法
9841
查看次数

d3d-&gt;CreateDevice 中的 D3DERR_INVALIDCALL 导致 Allegro 5 D3D 程序启动时窗口闪烁

我正在调试在创建启用多重采样的 Allegro 5 Direct3D 窗口时窗口创建闪烁问题。我已将问题范围缩小到 allegro 的 d3d_disp.cpp 源文件中的窗口创建问题。但是,我无法从 DirectX 获得任何调试输出。闪烁仅发生在 D3D 模式(而非 OpenGL)下并且仅在启用多重采样时发生。另请注意,这只发生在 NVIDIA GPU 上运行程序时,而不是在我的集成 Intel 上运行程序时。

我运行的是 Windows 10。

我已尝试在 Visual Studio 2017 中对此进行调试,但它无法捕获 DX 的调试输出。我从 2010 年 6 月开始安装 DirectX SDK 时安装了 DirectX 调试符号。

我已经尝试重建 allegro 并链接到 gcc 中的 libd3dx9d.a,但我仍然无法进入 directx 函数调用,并且符号未加载。从 2010 年 6 月开始,MinGW-W64 GCC 8.1 或 DirectX SDK 中没有可用的 libd3d9d.a(注意 d 表示调试)库。

我尝试通过 PIX 运行我的程序,但它给了我一个无法解决的不兼容错误。

这是可测试的 allegro 5 示例代码:

#include <allegro5/allegro.h>
#include <allegro5/allegro_color.h>
#include <allegro5/allegro_primitives.h> 
#include <allegro5/allegro_direct3d.h>

#include <cstdio>
#include <climits>

int main(int …
Run Code Online (Sandbox Code Playgroud)

c++ debugging allegro5 visual-studio-debugging directx-9

5
推荐指数
1
解决办法
1765
查看次数

从内存中创建纹理 directx

我有一个指向内存中包含像素信息的位置的指针。我想使用纹理或任何其他形式在屏幕上显示它。是否可以在 directx 9 中从内存创建纹理?谢谢

这是代码示例

D3DLOCKED_RECT r;
HRESULT hr;
DWORD c0=D3DCOLOR_ARGB(255,0,0,0), c1=D3DCOLOR_ARGB(255,255,255,255);
DWORD *pData, 
Image[64]={c0,c0,c0,c1,c0,c0,c0,c0,
   c0,c0,c0,c1,c0,c0,c0,c0,
   c0,c0,c0,c1,c0,c0,c0,c0,
       c1,c1,c1,c1,c1,c1,c1,c0,
       c0,c0,c0,c1,c0,c0,c0,c0,
   c0,c0,c0,c1,c0,c0,c0,c0,
   c0,c0,c0,c1,c0,c0,c0,c0,
   c0,c0,c0,c0,c0,c0,c0,c0};
if (m_pDevice->CreateTexture(8,8,1,D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT,   &m_pPointTexture,NULL)!=D3D_OK)
    return false;
if (m_pPointTexture->LockRect(0,&r,NULL, D3DLOCK_DISCARD |D3DLOCK_NOOVERWRITE)!=D3D_OK)
    return false;
for (int y=0; y<8; y++)
{
 pData=(DWORD*)((BYTE*)r.pBits + r.Pitch);
 for (int x=0; x<8; x++)
 pData[x]=Image[y*8+x];
}
m_pDevice->SetTexture(0,m_pPointTexture);
Run Code Online (Sandbox Code Playgroud)

然后,如果我通过 D3DXSaveTextureToFile() 将纹理保存到 BMP 文件,然后使用 D3DXCreateTextureFromFile() 创建纹理,那么在 setTexture 之前,我通过绘制矩形基元来渲染它。然后我得到预期的输出

directx directx-9

4
推荐指数
1
解决办法
8289
查看次数

如何在 C 中使用 DirectX 9 渲染多个窗口?

我已经在https://gamedev.stackexchange.com/questions/50374/how-can-i-render-multiple-windows-with-directx-9-in-c 上问过这个问题,但我还没有收到回答。

我正在尝试使用 DirectX 9 和交换链渲染多个窗口,但即使我创建了 2 个窗口,我也只能看到我创建的第一个窗口。我的 RendererDX9 标题是这样的:

#include <d3d9.h>
#include <Windows.h>
#include <vector>

#include "RAT_Renderer.h"

namespace RAT_ENGINE
{
    class RAT_RendererDX9 : public RAT_Renderer
    {
    public:
        RAT_RendererDX9();
        ~RAT_RendererDX9();

        void Init(RAT_WindowManager* argWMan);
        void CleanUp();

        void ShowWin();


    private:
        LPDIRECT3D9           renderInterface; // Used to create the D3DDevice
        LPDIRECT3DDEVICE9     renderDevice;    // Our rendering device
        LPDIRECT3DSWAPCHAIN9* swapChain;       // Swapchain to make multi-window rendering possible
        WNDCLASSEX wc;

        std::vector<HWND> hwindows;

        void Render(int argI);
    };
}
Run Code Online (Sandbox Code Playgroud)

我的 .cpp 文件是这样的:

#include "RAT_RendererDX9.h"


static LRESULT CALLBACK …
Run Code Online (Sandbox Code Playgroud)

c++ window directx-9

4
推荐指数
1
解决办法
3744
查看次数