📄 gameswf_render_handler_d3d.cpp
字号:
// No texgen; just pass through.
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU );
// Draw the quad.
//pk
CUSTOMVERTEX2 *pVertices;
HRESULT result;
if( FAILED( m_pVB2->Lock( 0, 0, (tLock**)&pVertices, D3DLOCK_DISCARD ) ) )
{
assert(0);
}
pVertices[0].x = a.m_x ;
pVertices[0].y = a.m_y ;
pVertices[0].z = Z_DEPTH;
pVertices[0].tu = uv_coords.m_x_min ;
pVertices[0].tv = uv_coords.m_y_min ;
pVertices[1].x = b.m_x ;
pVertices[1].y = b.m_y ;
pVertices[1].z = Z_DEPTH;
pVertices[1].tu = uv_coords.m_x_max ;
pVertices[1].tv = uv_coords.m_y_min ;
pVertices[2].x = c.m_x ;
pVertices[2].y = c.m_y ;
pVertices[2].z = Z_DEPTH;
pVertices[2].tu = uv_coords.m_x_min ;
pVertices[2].tv = uv_coords.m_y_max ;
pVertices[3].x = d.m_x ;
pVertices[3].y = d.m_y ;
pVertices[3].z = Z_DEPTH;
pVertices[3].tu = uv_coords.m_x_max ;
pVertices[3].tv = uv_coords.m_y_max ;
m_pVB2->Unlock();
// Render the vertex buffer contents
m_pd3dDevice->SetStreamSource( 0, m_pVB2,
#if DIRECT3D_VERSION >= 0x0900
0,
#endif
sizeof(CUSTOMVERTEX2) );
#if DIRECT3D_VERSION < 0x0900
m_pd3dDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX2);
#else
m_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX2);
#endif
result = m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
assert(result==S_OK);
}
void begin_submit_mask()
{
m_pd3dDevice->SetRenderState(
D3DRS_ZWRITEENABLE,
FALSE );
// Enable stencil testing
m_pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
//m_pd3dDevice->SetRenderState(
// D3DRS_ZWRITEENABLE,
// FALSE, false );
// Clear stencil buffer values to zero
m_pd3dDevice->Clear(0, NULL, D3DCLEAR_STENCIL, 0, 1.0f, 0);
// Specify the stencil comparison function
m_pd3dDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS );
// Set the comparison reference value
m_pd3dDevice->SetRenderState(D3DRS_STENCILREF, 1);
// Specify a stencil mask
m_pd3dDevice->SetRenderState(D3DRS_STENCILMASK, 0x1);
// A write mask controls what is written
m_pd3dDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0x1);
m_pd3dDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
m_pd3dDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
m_pd3dDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
#if 0
glEnable(GL_STENCIL_TEST);
glClearStencil(0);
glClear(GL_STENCIL_BUFFER_BIT);
glColorMask(0,0,0,0); // disable framebuffer writes
glEnable(GL_STENCIL_TEST); // enable stencil buffer for "marking" the mask
glStencilFunc(GL_ALWAYS, 1, 1); // always passes, 1 bit plane, 1 as mask
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); // we set the stencil buffer to 1 where we draw any polygon
// keep if test fails, keep if test passes but buffer test fails
// replace if test passes
#endif // 0
}
void end_submit_mask()
{
// Specify when to write stencil data
m_pd3dDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
m_pd3dDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
m_pd3dDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
// Specify the stencil comparison function
m_pd3dDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
m_pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE,TRUE);
#if 0
glColorMask(1,1,1,1); // enable framebuffer writes
glStencilFunc(GL_EQUAL, 1, 1); // we draw only where the stencil is 1 (where the mask was drawn)
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // don't change the stencil buffer
#endif // 0
}
void disable_mask()
{
m_pd3dDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
#if 0
glDisable(GL_STENCIL_TEST);
#endif // 0
}
}; // end struct render_handler_d3d
// bitmap_info_d3d implementation
bitmap_info_d3d::bitmap_info_d3d()
//bitmap_info_d3d::bitmap_info_d3d(create_empty e)
{
// A null texture. Needs to be initialized later.
m_texture_id = 0;
m_original_width = 0;
m_original_height = 0;
}
bitmap_info_d3d::bitmap_info_d3d(image::rgb* im)
// Image with no alpha.
{
assert(im);
// Rescale.
m_original_width = im->m_width;
m_original_height = im->m_height;
int w = 1; while (w < im->m_width) { w <<= 1; }
int h = 1; while (h < im->m_height) { h <<= 1; }
// Need to insert a dummy alpha byte in the image data, for
// D3DXLoadSurfaceFromMemory.
// @@ this sucks :(
Uint8* expanded_data = new Uint8[m_original_width * m_original_height * 4];
Uint8* pdata = expanded_data;
for (int y = 0; y < m_original_height; y++)
{
Uint8* scanline = image::scanline(im, y);
for (int x = 0; x < m_original_width; x++)
{
*pdata++ = scanline[x * 3 + 2]; // blue
*pdata++ = scanline[x * 3 + 1]; // green
*pdata++ = scanline[x * 3 + 0]; // red
*pdata++ = 255; // alpha
}
}
// Create the texture.
render_handler_d3d::m_d3d_textures.push_back(NULL);
m_texture_id = render_handler_d3d::m_d3d_textures.size() - 1;
IDirect3DTexture* tex;
HRESULT result = render_handler_d3d::m_pd3dDevice->CreateTexture(
w, h, 1, 0, // Usage
render_handler_d3d::m_FormatRGB, // Format
D3DPOOL_MANAGED, &tex
#if DIRECT3D_VERSION >= 0x0900
, NULL
#endif
);
if (render_handler_d3d::m_FormatRGB!=D3DFMT_A8R8G8B8 && result != S_OK)
{
result = render_handler_d3d::m_pd3dDevice->CreateTexture(
w, h, 1, 0, // Usage
D3DFMT_A8R8G8B8, // Format
D3DPOOL_MANAGED, &tex
#if DIRECT3D_VERSION >= 0x0900
, NULL
#endif
);
}
if (result != S_OK)
{
gameswf::log_error("error: can't create texture\n");
return;
}
assert(tex);
render_handler_d3d::m_d3d_textures.back() = tex;
IDirect3DSurface* surf = NULL;
result = tex->GetSurfaceLevel(0, &surf);
if (result != S_OK)
{
gameswf::log_error("error: can't get surface\n");
return;
}
assert(surf);
RECT source_rect;
source_rect.left = 0;
source_rect.top = 0;
source_rect.right = m_original_width;
source_rect.bottom = m_original_height;
result = D3DXLoadSurfaceFromMemory( surf, NULL, NULL, expanded_data,
D3DFMT_A8R8G8B8, m_original_width * 4, NULL, &source_rect, D3DX_DEFAULT, 0 );
// test
//D3DXSaveSurfaceToFile( "image.png", D3DXIFF_PNG, surf, NULL, NULL );
delete [] expanded_data;
if (result != S_OK)
gameswf::log_error("error: can't load surface from memory, result = %d\n", result);
surf->Release();
}
typedef struct
{
Uint8 r;
Uint8 g;
Uint8 b;
Uint8 a;
} RGBA;
void bitmap_info_d3d::convert_to_argb(image::rgba* im)
{
for (int h = 0; h < im->m_height; h++)
{
for (int w = 0; w < im->m_width; w++)
{
RGBA c;
c.r = im->m_data[((h * im->m_width) + w ) * 4];
c.g = im->m_data[(((h * im->m_width) + w ) * 4) + 1];
c.b = im->m_data[(((h * im->m_width) + w ) * 4) + 2];
c.a = im->m_data[(((h * im->m_width) + w ) * 4) + 3];
im->m_data[((h * im->m_width) + w ) * 4 + 3] = c.a;
im->m_data[(((h * im->m_width) + w ) * 4) + 2] = c.r;
im->m_data[(((h * im->m_width) + w ) * 4) + 1] = c.g;
im->m_data[(((h * im->m_width) + w ) * 4) + 0] = c.b;
}
}
}
bitmap_info_d3d::bitmap_info_d3d(image::rgba* im)
// Version of the constructor that takes an image with alpha.
{
assert(im);
#if DIRECT3D_VERSION < 0x0900
convert_to_argb(im);
#endif
m_original_width = im->m_width;
m_original_height = im->m_height;
int w = 1; while (w < im->m_width) { w <<= 1; }
int h = 1; while (h < im->m_height) { h <<= 1; }
// Create the texture.
render_handler_d3d::m_d3d_textures.push_back(NULL);
m_texture_id = render_handler_d3d::m_d3d_textures.size() - 1;
IDirect3DTexture* tex;
HRESULT result = render_handler_d3d::m_pd3dDevice->CreateTexture(
w, h, 1, 0, // Usage
render_handler_d3d::m_FormatRGBA, // Format
D3DPOOL_MANAGED, &tex
#if DIRECT3D_VERSION >= 0x0900
, NULL
#endif
);
if (render_handler_d3d::m_FormatRGBA!=D3DFMT_A8R8G8B8 && result != S_OK)
{
result = render_handler_d3d::m_pd3dDevice->CreateTexture(
w, h, 1, 0, // Usage
D3DFMT_A8R8G8B8, // Format
D3DPOOL_MANAGED, &tex
#if DIRECT3D_VERSION >= 0x0900
, NULL
#endif
);
}
if (result != S_OK)
{
gameswf::log_error("error: can't create texture\n");
return;
}
assert(tex);
render_handler_d3d::m_d3d_textures.back() = tex;
IDirect3DSurface* surf = NULL;
result = tex->GetSurfaceLevel(0, &surf);
if (result != S_OK)
{
gameswf::log_error("error: can't get surface\n");
return;
}
assert(surf);
RECT source_rect;
source_rect.left = 0;
source_rect.top = 0;
source_rect.right = m_original_width;
source_rect.bottom = m_original_height;
// Set the actual data.
result = D3DXLoadSurfaceFromMemory( surf, NULL, NULL, im->m_data,
#if DIRECT3D_VERSION < 0x0900
D3DFMT_A8R8G8B8,
#else
D3DFMT_A8B8G8R8,
#endif
im->m_pitch, NULL, &source_rect, D3DX_DEFAULT, 0);
if (result != S_OK)
gameswf::log_error("error: can't load surface from memory, result = %d\n", result);
surf->Release();
}
bitmap_info_d3d::bitmap_info_d3d(int width, int height, Uint8* data)
// Initialize this bitmap_info to an alpha image
// containing the specified data (1 byte per texel).
//
// !! Munges *data in order to create mipmaps !!
{
assert(data);
// Create the texture.
m_original_width = width;
m_original_height = height;
// You must use power-of-two dimensions!!
int w = 1; while (w < width) { w <<= 1; }
int h = 1; while (h < height) { h <<= 1; }
render_handler_d3d::m_d3d_textures.push_back(NULL);
m_texture_id = render_handler_d3d::m_d3d_textures.size() - 1;
IDirect3DTexture* tex;
HRESULT result = render_handler_d3d::m_pd3dDevice->CreateTexture(
w, h, 1, 0, // Usage
render_handler_d3d::m_FormatA, // Format
D3DPOOL_MANAGED, &tex
#if DIRECT3D_VERSION >= 0x0900
, NULL
#endif
);
if (result != S_OK)
{
gameswf::log_error("error: can't create texture\n");
return;
}
assert(tex);
render_handler_d3d::m_d3d_textures.back() = tex;
IDirect3DSurface* surf = NULL;
result = tex->GetSurfaceLevel(0, &surf);
if (result != S_OK)
{
gameswf::log_error("error: can't get surface\n");
return;
}
assert(surf);
RECT source_rect;
source_rect.left = 0;
source_rect.top = 0;
source_rect.right = width;
source_rect.bottom = height;
result = D3DXLoadSurfaceFromMemory( surf, NULL, NULL, data,
D3DFMT_A8, width, NULL, &source_rect, D3DX_DEFAULT, 0);
if (result != S_OK)
gameswf::log_error("error: can't load surface from memory, result = %d\n", result);
surf->Release();
// glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
// // Build mips.
// int level = 1;
// while (width > 1 || height > 1)
// {
// render_handler_d3d::make_next_miplevel(&width, &height, data);
// glTexImage2D(GL_TEXTURE_2D, level, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data);
// level++;
// }
}
IDirect3DDevice* render_handler_d3d::m_pd3dDevice;
D3DFORMAT render_handler_d3d::m_FormatRGB;
D3DFORMAT render_handler_d3d::m_FormatRGBA;
D3DFORMAT render_handler_d3d::m_FormatA;
D3DXMATRIX render_handler_d3d::m_ModelViewMatrix;
D3DXMATRIX render_handler_d3d::m_ProjMatrix;
array<IDirect3DBaseTexture*> render_handler_d3d::m_d3d_textures;
gameswf::render_handler* gameswf::create_render_handler_d3d(IDirect3DDevice* device)
// Factory.
{
render_handler_d3d *hndlr = new render_handler_d3d( device );
return hndlr;
}
// Local Variables:
// mode: C++
// c-basic-offset: 8
// tab-width: 8
// indent-tabs-mode: t
// End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -