使用DirectX 9,我尝试创建然后以下列方式填充LPDIRECT3DTEXTURE9
纹理。
首先,我使用IDirect3DTexture9::CreateTexture
创建纹理:
LPDIRECT3DTEXTURE9 pTexture;
if ( FAILED( pd3dDevice->CreateTexture( MAX_IMAGE_WIDTH,
MAX_IMAGE_HEIGHT,
1,
0, // D3DUSAGE_DYNAMIC,
D3DFMT_A8R8G8B8,
D3DPOOL_MANAGED, // D3DPOOL_DEFAULT,
&pTexture,
NULL ) ) )
{
// Handle error case
}
然后,我尝试在纹理上锁定一个矩形,如下所示:
unsigned int uiSize = GetTextureSize();
D3DLOCKED_RECT rect;
ARGB BlackColor = { (char)0xFF, (char)0xFF, (char)0xFF, (char)0x00 };
::ZeroMemory( &rect, sizeof( D3DLOCKED_RECT ) );
// Lock outline texture to rect, and then cast rect to bits and use bits as outlineTexture access point
if ( pTexture == NULL )
{
return ERROR_NOT_INITIALIZED;
}
pTexture->LockRect( 0, &rect, NULL, D3DLOCK_NOSYSLOCK ); // Consider ?
ARGB* bits = (ARGB*)rect.pBits;
for ( unsigned int uiPixel = 0; uiPixel < uiSize; ++uiPixel )
{
// Copy all black pixels only
if ( compositeMask[uiPixel] == BlackColor )
{
bits[uiPixel] = compositeMask[uiPixel];
}
}
pTexture->UnlockRect( 0 );
return ERROR_SUCCESS;
ARGB
只是一个定义如下的结构:
struct ARGB
{
char b;
char g;
char r;
char a;
bool operator==( ARGB& comp )
{
if ( a == comp.a &&
r == comp.r &&
g == comp.g &&
b == comp.b )
return TRUE;
else
return FALSE;
}
bool operator!=( ARGB& comp )
{
return !( this->operator==( comp ) );
}
};
我想要做的是根据应用内算法预先计算一个像素数据阵列(黑色轮廓),然后只将该组像素数据中的纯黑色像素写入我的{{1}稍后再渲染。
应用程序当前在LockRect调用时抛出ACCESS_VIOLATION异常(0xC0000005)。任何人都可以解释原因吗?
这是确切的异常细节:
TestApp.exe中0x0132F261处的未处理异常:0xC0000005:访问冲突读取位置0x00000001。
位置在LPDIRECT3DTEXTURE9
和0x00000000
之间变化......是否暗示任何事情?
另外,如果有更好的方法来做我想做的事情,那么我会全力以赴:)
答案 0 :(得分:1)
就像你问题上的其他评论员一样,我原则上看不出你创建和锁定纹理的方式有什么问题。我自己做了同样的事情 - 在D3DPOOL_MANAGED
中创建纹理并使用LockRect
来更新内容。
然而,有三个方面与我有关。我发帖作为答案,因为评论太多了,所以请耐心等待......
D3DLOCK_NOSYSLOCK
标志。我发现在为多线程操作创建D3D设备时,这可能会导致冲突。struct
进行像素访问,并且不清楚struct
的实际大小可能是多少,因为我看不到您对该项目的打包选项。所以,我建议你做三件事来确定上述是否有任何问题:
首先,只需使用默认零标志进行锁定调用
pTexture->LockRect( 0, &rect, NULL, 0 );
其次,验证您的ARGB
结构确实是4个字节
ASSERT(sizeof(ARGB) == 4);
最后,除了锁定和解锁纹理之外什么也不做,看看你是否仍然遇到运行时错误,还要检查返回代码
HRESULT hr = pTexture->LockRect( 0, &rect, NULL, 0 );
ASSERT(SUCCEEDED(hr));
hr = pTexture->UnlockRect( 0 );
ASSERT(SUCCEEDED(hr));
在任何情况下,更新纹理位时,必须逐行进行,同时考虑到LockRect
调用中报告的步幅{ {1}}。
也许你可以用上面的结果更新你的问题,我可以根据需要修改这个答案。
答案 1 :(得分:0)
这令人愚蠢的愚蠢。对不起大家。
我一直跟着纹理指针通过代码; LPDIRECT3DTEXTURE9指针实际上存储在另一个自定义Texture类对象类型中,并附加了额外的上下文数据;这些包装器对象是另一个被复制并在整个地方使用的类的成员,但是没有为该类编写的赋值运算符或复制构造函数。在某些时候,在处理的巨大纹理列表中,从容器类发送的纹理之一被发现是无效的,因为它实际上是;它应该包含另一个纹理的副本,但只包含一个无效的指针。
对不幸的是每个人都有不幸的业余错误,但是谢谢大家的指示和保证