⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gameswf_render_handler_d3d.cpp

📁 一个开源的Flash 播放器,可以在Windows/Linux 上运行
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    // 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 + -