Jelajahi Sumber

port dx8 to dx9

aignacio_sf 20 tahun lalu
induk
melakukan
0246695237
34 mengubah file dengan 3586 tambahan dan 4288 penghapusan
  1. 9 6
      panda/src/dxgsg8/dxIndexBufferContext8.cxx
  2. 14 11
      panda/src/dxgsg8/dxVertexBufferContext8.cxx
  3. 15 15
      panda/src/dxgsg9/Sources.pp
  4. 26 9
      panda/src/dxgsg9/config_dxgsg9.cxx
  5. 3 2
      panda/src/dxgsg9/config_dxgsg9.h
  6. 0 946
      panda/src/dxgsg9/d3dfont9.cxx
  7. 0 112
      panda/src/dxgsg9/d3dfont9.h
  8. 47 0
      panda/src/dxgsg9/dxGeomMunger9.I
  9. 189 0
      panda/src/dxgsg9/dxGeomMunger9.cxx
  10. 75 0
      panda/src/dxgsg9/dxGeomMunger9.h
  11. 4 5
      panda/src/dxgsg9/dxGraphicsDevice9.cxx
  12. 5 6
      panda/src/dxgsg9/dxGraphicsDevice9.h
  13. 68 498
      panda/src/dxgsg9/dxGraphicsStateGuardian9.I
  14. 416 453
      panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx
  15. 157 250
      panda/src/dxgsg9/dxGraphicsStateGuardian9.h
  16. 17 0
      panda/src/dxgsg9/dxIndexBufferContext9.I
  17. 132 0
      panda/src/dxgsg9/dxIndexBufferContext9.cxx
  18. 61 0
      panda/src/dxgsg9/dxIndexBufferContext9.h
  19. 5 7
      panda/src/dxgsg9/dxInput9.cxx
  20. 6 5
      panda/src/dxgsg9/dxInput9.h
  21. 73 0
      panda/src/dxgsg9/dxTextureContext9.I
  22. 1182 929
      panda/src/dxgsg9/dxTextureContext9.cxx
  23. 29 25
      panda/src/dxgsg9/dxTextureContext9.h
  24. 17 0
      panda/src/dxgsg9/dxVertexBufferContext9.I
  25. 254 0
      panda/src/dxgsg9/dxVertexBufferContext9.cxx
  26. 62 0
      panda/src/dxgsg9/dxVertexBufferContext9.h
  27. 3 1
      panda/src/dxgsg9/dxgsg9_composite1.cxx
  28. 39 42
      panda/src/dxgsg9/dxgsg9base.h
  29. 4 4
      panda/src/dxgsg9/wdxGraphicsPipe9.I
  30. 329 422
      panda/src/dxgsg9/wdxGraphicsPipe9.cxx
  31. 21 32
      panda/src/dxgsg9/wdxGraphicsPipe9.h
  32. 4 3
      panda/src/dxgsg9/wdxGraphicsWindow9.I
  33. 296 475
      panda/src/dxgsg9/wdxGraphicsWindow9.cxx
  34. 24 30
      panda/src/dxgsg9/wdxGraphicsWindow9.h

+ 9 - 6
panda/src/dxgsg8/dxIndexBufferContext8.cxx

@@ -70,12 +70,14 @@ create_ibuffer(DXScreenData &scrn) {
 
   PStatTimer timer(GraphicsStateGuardian::_create_index_buffer_pcollector);
 
-  D3DFORMAT index_type = 
+  D3DFORMAT index_type =
     DXGraphicsStateGuardian8::get_index_type(get_data()->get_index_type());
 
   HRESULT hr = scrn._d3d_device->CreateIndexBuffer
-    (get_data()->get_data_size_bytes(), D3DUSAGE_WRITEONLY,
-     index_type, D3DPOOL_MANAGED, &_ibuffer);
+//    (get_data()->get_data_size_bytes(), D3DUSAGE_WRITEONLY,
+//     index_type, D3DPOOL_MANAGED, &_ibuffer);
+    (get_data()->get_data_size_bytes(), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC,
+     index_type, D3DPOOL_DEFAULT, &_ibuffer);
   if (FAILED(hr)) {
     dxgsg8_cat.warning()
       << "CreateIndexBuffer failed" << D3DERRORSTRING(hr);
@@ -84,7 +86,7 @@ create_ibuffer(DXScreenData &scrn) {
     if (dxgsg8_cat.is_debug()) {
       dxgsg8_cat.debug()
         << "creating index buffer " << _ibuffer << ": "
-        << get_data()->get_num_vertices() << " indices (" 
+        << get_data()->get_num_vertices() << " indices ("
         << get_data()->get_vertices()->get_array_format()->get_column(0)->get_numeric_type()
         << ")\n";
     }
@@ -103,7 +105,7 @@ upload_data() {
   PStatTimer timer(GraphicsStateGuardian::_load_index_buffer_pcollector);
 
   int data_size = get_data()->get_data_size_bytes();
-  
+
   if (dxgsg8_cat.is_spam()) {
     dxgsg8_cat.spam()
       << "copying " << data_size
@@ -111,7 +113,8 @@ upload_data() {
   }
 
   BYTE *local_pointer;
-  HRESULT hr = _ibuffer->Lock(0, data_size, &local_pointer, 0);
+//  HRESULT hr = _ibuffer->Lock(0, data_size, &local_pointer, 0);
+  HRESULT hr = _ibuffer->Lock(0, data_size, &local_pointer, D3DLOCK_DISCARD);
   if (FAILED(hr)) {
     dxgsg8_cat.error()
       << "IndexBuffer::Lock failed" << D3DERRORSTRING(hr);

+ 14 - 11
panda/src/dxgsg8/dxVertexBufferContext8.cxx

@@ -46,8 +46,8 @@ DXVertexBufferContext8(GeomVertexArrayData *data) :
   int num_columns = array_format->get_num_columns();
 
   _fvf = 0;
-  
-  if (n < num_columns && 
+
+  if (n < num_columns &&
       array_format->get_column(n)->get_name() == InternalName::get_vertex()) {
     ++n;
 
@@ -59,7 +59,7 @@ DXVertexBufferContext8(GeomVertexArrayData *data) :
       num_blend_values = array_format->get_column(n)->get_num_values();
       ++n;
     }
-      
+
     if (n < num_columns &&
         array_format->get_column(n)->get_name() == InternalName::get_transform_index()) {
       // Furthermore, it's indexed vertex animation.
@@ -95,12 +95,12 @@ DXVertexBufferContext8(GeomVertexArrayData *data) :
     }
   }
 
-  if (n < num_columns && 
+  if (n < num_columns &&
       array_format->get_column(n)->get_name() == InternalName::get_normal()) {
     _fvf |= D3DFVF_NORMAL;
     ++n;
   }
-  if (n < num_columns && 
+  if (n < num_columns &&
       array_format->get_column(n)->get_name() == InternalName::get_color()) {
     _fvf |= D3DFVF_DIFFUSE;
     ++n;
@@ -109,7 +109,7 @@ DXVertexBufferContext8(GeomVertexArrayData *data) :
   // Now look for all of the texcoord names and enable them in the
   // same order they appear in the array.
   int texcoord_index = 0;
-  while (n < num_columns && 
+  while (n < num_columns &&
          array_format->get_column(n)->get_contents() == Geom::C_texcoord) {
     const GeomVertexColumn *column = array_format->get_column(n);
     switch (column->get_num_values()) {
@@ -197,8 +197,10 @@ create_vbuffer(DXScreenData &scrn) {
   PStatTimer timer(GraphicsStateGuardian::_create_vertex_buffer_pcollector);
 
   HRESULT hr = scrn._d3d_device->CreateVertexBuffer
-    (get_data()->get_data_size_bytes(), D3DUSAGE_WRITEONLY,
-     _fvf, D3DPOOL_MANAGED, &_vbuffer);
+//    (get_data()->get_data_size_bytes(), D3DUSAGE_WRITEONLY,
+//     _fvf, D3DPOOL_MANAGED, &_vbuffer);
+      (get_data()->get_data_size_bytes(), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC,
+     _fvf, D3DPOOL_DEFAULT, &_vbuffer);
   if (FAILED(hr)) {
     dxgsg8_cat.warning()
       << "CreateVertexBuffer failed" << D3DERRORSTRING(hr);
@@ -207,7 +209,7 @@ create_vbuffer(DXScreenData &scrn) {
     if (dxgsg8_cat.is_debug()) {
       dxgsg8_cat.debug()
         << "created vertex buffer " << _vbuffer << ": "
-        << get_data()->get_num_rows() << " vertices " 
+        << get_data()->get_num_rows() << " vertices "
         << *get_data()->get_array_format() << "\n";
     }
   }
@@ -225,7 +227,7 @@ upload_data() {
   PStatTimer timer(GraphicsStateGuardian::_load_vertex_buffer_pcollector);
 
   int data_size = get_data()->get_data_size_bytes();
-  
+
   if (dxgsg8_cat.is_spam()) {
     dxgsg8_cat.spam()
       << "copying " << data_size
@@ -233,7 +235,8 @@ upload_data() {
   }
 
   BYTE *local_pointer;
-  HRESULT hr = _vbuffer->Lock(0, data_size, &local_pointer, 0);
+//  HRESULT hr = _vbuffer->Lock(0, data_size, &local_pointer, 0);
+  HRESULT hr = _vbuffer->Lock(0, data_size, &local_pointer, D3DLOCK_DISCARD);
   if (FAILED(hr)) {
     dxgsg8_cat.error()
       << "VertexBuffer::Lock failed" << D3DERRORSTRING(hr);

+ 15 - 15
panda/src/dxgsg9/Sources.pp

@@ -1,14 +1,13 @@
-// DX9 build is temporarily disabled until we bring it up-to-date with
-// the new Geom rewrite.
-#define BUILD_DIRECTORY
-//#define BUILD_DIRECTORY $[HAVE_DX]
+#define BUILD_DIRECTORY $[HAVE_DX]
 
-#define OTHER_LIBS interrogatedb:c dconfig:c dtoolconfig:m \
-                   dtoolutil:c dtoolbase:c dtool:m
-#define USE_PACKAGES dx
+#define OTHER_LIBS \
+   interrogatedb:c dconfig:c dtoolconfig:m \
+   dtoolutil:c dtoolbase:c dtool:m
 
 #define WIN_SYS_LIBS \
    d3d9.lib d3dx9.lib dxerr9.lib
+   
+#define USE_PACKAGES dx
 
 #begin lib_target
   #define TARGET dxgsg9
@@ -18,12 +17,6 @@
     
   #define COMBINED_SOURCES $[TARGET]_composite1.cxx     
 
-  // need to install these due to external projects that link directly with libpandadx (bartop)  
-  #define INSTALL_HEADERS \
-    dxgsg9base.h config_dxgsg9.h dxGraphicsStateGuardian9.I dxGraphicsStateGuardian9.h \
-    dxTextureContext9.h d3dfont9.h \
-    dxGraphicsDevice9.h
-
   // build dxGraphicsStateGuardian separately since its so big
   
   #define SOURCES \
@@ -31,12 +24,19 @@
     dxGraphicsDevice9.h \
     wdxGraphicsPipe9.I wdxGraphicsPipe9.h \
     wdxGraphicsWindow9.I wdxGraphicsWindow9.h \
-    $[INSTALL_HEADERS]
+    dxgsg9base.h config_dxgsg9.h dxGraphicsStateGuardian9.I dxGraphicsStateGuardian9.h \
+    dxVertexBufferContext9.h dxVertexbufferContext9.I \
+    dxIndexBufferContext9.h dxIndexBufferContext9.I \
+    dxTextureContext9.h dxTextureContext9.I \
+    dxGeomMunger9.h dxGeomMunger9.I \
+    dxGraphicsDevice9.h
     
   #define INCLUDED_SOURCES \
     config_dxgsg9.cxx \
+    dxVertexBufferContext9.cxx \
+    dxIndexBufferContext9.cxx \
     dxTextureContext9.cxx \
-    d3dfont9.cxx \
+    dxGeomMunger9.cxx \
     dxGraphicsDevice9.cxx \
     wdxGraphicsPipe9.cxx wdxGraphicsWindow9.cxx
 

+ 26 - 9
panda/src/dxgsg9/config_dxgsg9.cxx

@@ -1,10 +1,10 @@
-// Filename: config_dxgsg8.cxx
-// Created by:   masad (02Jan04)
+// Filename: config_dxgsg9.cxx
+// Created by:  drose (06Oct99)
 //
 ////////////////////////////////////////////////////////////////////
 //
 // PANDA 3D SOFTWARE
-// Copyright (c) 2004, Disney Enterprises, Inc.  All rights reserved
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
 //
 // All use of this software is subject to the terms of the Panda 3d
 // Software license.  You should have received a copy of this license
@@ -19,6 +19,9 @@
 #include "config_dxgsg9.h"
 #include "dxGraphicsStateGuardian9.h"
 #include "dxTextureContext9.h"
+#include "dxVertexBufferContext9.h"
+#include "dxIndexBufferContext9.h"
+#include "dxGeomMunger9.h"
 #include "graphicsPipeSelection.h"
 #include "wdxGraphicsWindow9.h"
 #include "wdxGraphicsPipe9.h"
@@ -27,9 +30,8 @@
 #include "dconfig.h"
 
 Configure(config_dxgsg9);
-//NotifyCategoryDef(dxgsg9, ":display:gsg");  dont want to merge this with the regular parent class dbg output
-NotifyCategoryDef(dxgsg9, "dxgsg");
-NotifyCategoryDef(wdxdisplay9, "windisplay");
+NotifyCategoryDef(dxgsg9, ":display:gsg");
+NotifyCategoryDef(wdxdisplay9, "display");
 
 // Configure this variable true to cause the DXGSG to show each
 // transform space it renders by drawing a little unit axis.  This
@@ -45,9 +47,9 @@ ConfigVariableInt dx_multisample_antialiasing_level
 ConfigVariableBool dx_no_vertex_fog
 ("dx-no-vertex-fog", false);
 
-// if true, overwrite cursor bitmap tip with "D3D" to distinguish it from GDI cursor 
+// if true, overwrite cursor bitmap tip with "D3D" to distinguish it from GDI cursor
 ConfigVariableBool dx_show_cursor_watermark
-("dx-show-cursor-watermark", 
+("dx-show-cursor-watermark",
 #ifdef _DEBUG
     true
 #else
@@ -59,6 +61,18 @@ ConfigVariableBool dx_show_cursor_watermark
 ConfigVariableBool dx_use_triangle_mipgen_filter
 ("dx-use-triangle-mipgen-filter", false);
 
+ConfigVariableBool dx_broken_max_index
+("dx-broken-max-index", false,
+ PRC_DESC("Configure this true if you have a buggy graphics driver that "
+          "doesn't correctly implement the third parameter, NumVertices, "
+          "of DrawIndexedPrimitive().  In particular, the NVIDIA Quadro "
+          "driver version 6.14.10.7184 seems to treat this as a maximum "
+          "vertex index, rather than a delta between the maximum and "
+          "minimum vertex index.  Turn this on if you are seeing stray "
+          "triangles, or you are not seeing all of your triangles.  Enabling "
+          "this should work around this bug, at the cost of some additional "
+          "rendering overhead on the GPU."));
+
 #ifndef NDEBUG
 // debugging flag
 // values are same as D3DCULL enumtype, 0 - no force, 1 - force none, 2 - force CW, 3 - force CCW
@@ -110,7 +124,7 @@ ConfigVariableBool dx_debug_view_mipmaps
 ConfigVariableBool dx_force_anisotropic_filtering
 ("dx-force-anisotropic-filtering", false);
 
-// set 'retained-mode #t' and this to have prepare_geom concatenate all tristrips within a geom 
+// set 'retained-mode #t' and this to have prepare_geom concatenate all tristrips within a geom
 // together using degenerate tris
 ConfigVariableBool link_tristrips
 ("link-tristrips", false);
@@ -137,6 +151,9 @@ init_libdxgsg9() {
 
   DXGraphicsStateGuardian9::init_type();
   DXTextureContext9::init_type();
+  DXVertexBufferContext9::init_type();
+  DXIndexBufferContext9::init_type();
+  DXGeomMunger9::init_type();
 
   wdxGraphicsPipe9::init_type();
   wdxGraphicsWindow9::init_type();

+ 3 - 2
panda/src/dxgsg9/config_dxgsg9.h

@@ -1,10 +1,10 @@
 // Filename: config_dxgsg.h
-// Created by:  masad (02Jan04)
+// Created by:  drose (06Oct99)
 //
 ////////////////////////////////////////////////////////////////////
 //
 // PANDA 3D SOFTWARE
-// Copyright (c) 2004, Disney Enterprises, Inc.  All rights reserved
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
 //
 // All use of this software is subject to the terms of the Panda 3d
 // Software license.  You should have received a copy of this license
@@ -36,6 +36,7 @@ extern ConfigVariableBool dx_use_rangebased_fog;
 extern ConfigVariableBool link_tristrips;
 extern ConfigVariableInt dx_multisample_antialiasing_level;
 extern ConfigVariableBool dx_use_triangle_mipgen_filter;
+extern ConfigVariableBool dx_broken_max_index;
 
 
 // debug flags we might want to use in full optimized build

+ 0 - 946
panda/src/dxgsg9/d3dfont9.cxx

@@ -1,946 +0,0 @@
-//-----------------------------------------------------------------------------
-// File: D3DFont.cpp
-//
-// Desc: Texture-based font class
-//       modified from a modified version of DXSDK CD3DFont from http://www.lafaqmfc.com/directx.htm
-//       Note that this is faster than ID3DXFont, which calls GDI in Draw()
-//-----------------------------------------------------------------------------
-#ifndef STRICT
-#define STRICT
-#endif
-
-#include "dxgsg9base.h"
-#include <stdio.h>
-#include <tchar.h>
-#include <d3dx9.h>
-#include "d3dfont9.h"
-
-//-----------------------------------------------------------------------------
-// Custom vertex types for rendering text
-//-----------------------------------------------------------------------------
-
-struct FONT2DVERTEX {
-    D3DXVECTOR4 p;   DWORD color;     FLOAT tu, tv;
-};
-struct FONT3DVERTEX {
-    D3DXVECTOR3 p;   D3DXVECTOR3 n;   FLOAT tu, tv;
-};
-
-inline FONT2DVERTEX InitFont2DVertex( const D3DXVECTOR4& p, D3DCOLOR color,
-                                      FLOAT tu, FLOAT tv ) {
-    FONT2DVERTEX v;   v.p = p;   v.color = color;   v.tu = tu;   v.tv = tv;
-    return v;
-}
-
-inline FONT3DVERTEX InitFont3DVertex( const D3DXVECTOR3& p, const D3DXVECTOR3& n,
-                                      FLOAT tu, FLOAT tv ) {
-    FONT3DVERTEX v;   v.p = p;   v.n = n;   v.tu = tu;   v.tv = tv;
-    return v;
-}
-
-//-----------------------------------------------------------------------------
-// Name: CD3DFont()
-// Desc: Font class constructor
-//-----------------------------------------------------------------------------
-CD3DFont::CD3DFont( TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags ) {
-    _tcscpy( m_strFontName, strFontName );
-    m_dwFontHeight         = dwHeight;
-    m_dwFontFlags          = dwFlags;
-
-    m_pd3dDevice           = NULL;
-    m_pTexture             = NULL;
-    m_pVB                  = NULL;
-
-    m_pSBSavedStateBlock    = NULL;
-    m_pSBDrawTextStateBlock = NULL;
-
-    ClearBeginEndData ( ) ; 
-    m_bBeginText = false ; 
-}
-
-//-----------------------------------------------------------------------------
-// Name: ~CD3DFont()
-// Desc: Font class destructor
-//-----------------------------------------------------------------------------
-CD3DFont::~CD3DFont() {
-    DeleteDeviceObjects();
-}
-
-//-----------------------------------------------------------------------------
-// Name: InitDeviceObjects()
-// Desc: Initializes device-dependent objects, including the vertex buffer used
-//       for rendering text and the texture map which stores the font image.
-//-----------------------------------------------------------------------------
-HRESULT CD3DFont::InitDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice ) {
-    HRESULT hr;
-
-    // Keep a local copy of the device
-    m_pd3dDevice = pd3dDevice;
-
-    // Establish the font and texture size
-    m_fTextScale  = 1.0f; // Draw fonts into texture without scaling
-
-    // Large fonts need larger textures 
-    // We can be generous at this step, this is an estimate
-    if(m_dwFontHeight > 40)
-        m_dwTexWidth = m_dwTexHeight = 2048;
-    else if(m_dwFontHeight > 32)
-        m_dwTexWidth = m_dwTexHeight = 1024;
-    else if(m_dwFontHeight > 16)
-        m_dwTexWidth = m_dwTexHeight = 512;
-    else
-        m_dwTexWidth = m_dwTexHeight = 256;
-
-    // Prepare to create a bitmap
-    DWORD*      pBitmapBits;
-    BITMAPINFO bmi;
-    ZeroMemory( &bmi.bmiHeader,  sizeof(BITMAPINFOHEADER) );
-    bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
-    bmi.bmiHeader.biWidth       =  (int)m_dwTexWidth;
-    bmi.bmiHeader.biHeight      = -(int)m_dwTexHeight;
-    bmi.bmiHeader.biPlanes      = 1;
-    bmi.bmiHeader.biCompression = BI_RGB;
-    bmi.bmiHeader.biBitCount    = 32;
-
-    // Create a DC and a bitmap for the font
-    HDC     hDC       = CreateCompatibleDC( NULL );
-    HBITMAP hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS,
-                                          (VOID**)&pBitmapBits, NULL, 0 );
-    SetMapMode( hDC, MM_TEXT );
-
-    // Create a font.  By specifying ANTIALIASED_QUALITY, we might get an
-    // antialiased font, but this is not guaranteed.
-    INT nHeight    = -MulDiv( m_dwFontHeight, 
-                              (INT)(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72 );
-    DWORD dwBold   = (m_dwFontFlags&D3DFONT_BOLD)   ? FW_BOLD : FW_NORMAL;
-    DWORD dwItalic = (m_dwFontFlags&D3DFONT_ITALIC) ? TRUE    : FALSE;
-    HFONT hFont    = CreateFont( nHeight, 0, 0, 0, dwBold, 
-
-                                 FALSE ,   // dwItalic, // NO! We should not do that...
-                                    // See below comment about GetTextExtentPoint32
-
-                                 FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
-                                 CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
-                                 VARIABLE_PITCH, m_strFontName );
-    if(NULL==hFont) {
-        dxgsg9_cat.error() << "CD3DFont InitDeviceObjects(): initial CreateFont failed!  GetLastError=" << GetLastError() << endl;
-        return E_FAIL;
-    }
-
-    HBITMAP hbmOld = ( HBITMAP ) SelectObject ( hDC, hbmBitmap );
-    HFONT   hfOld  = ( HFONT ) SelectObject ( hDC, hFont );
-
-    // Set text properties
-    SetTextColor( hDC, RGB(255,255,255) );
-    SetBkColor(   hDC, 0x00000000 );
-    SetTextAlign( hDC, TA_TOP );
-
-    // First Loop through all printable characters 
-    // in order to determine the smallest necessary texture
-    DWORD x = 0;
-    DWORD y = 0;
-    TCHAR str[2] = _T("x");
-    SIZE size;
-    SIZE sizes [ 127 - 32 ] ;
-
-    TCHAR c;
-    for(c=32; c<127; c++) {
-        str[0] = c;
-        // GetTextExtentPoint32 does not care that the font is Italic or not, it will 
-        // return the same value. However, if we specify an Italic font, the output 
-        // on the bitmap will use more pixels. 
-        // If the font is Italic we have to output the standard character 
-        // and bend our vertices.
-        GetTextExtentPoint32 ( hDC, str, 1, & sizes [ c - 32 ] );
-    } ; 
-
-    static DWORD TexturesSizes [ 5 ] = { 128 , 256 , 512 , 1024 , 2048} ; 
-    DWORD dwTexSize = 0 ;  
-    for(DWORD iTex = 0 ; iTex < 5 ; ++ iTex) {
-        // fake the tex coord loop calculation 
-        x = 0 ; 
-        y = 0 ; 
-        for(TCHAR c=32; c<127; c++) {
-            if((DWORD)( x + sizes[ c - 32 ].cx+1) > TexturesSizes [ iTex ]) {
-                x  = 0;
-                y += sizes[ c - 32 ].cy+1;
-                // new y size 
-                if((DWORD) ( y + sizes[ 0 ].cy + 1 ) >= TexturesSizes [ iTex ]) {
-                    // does not fit, let's try a larger one 
-                    break ; 
-                }; 
-            }; 
-            x += sizes[ c - 32 ].cx + 2 ;
-        } ; 
-
-        if((DWORD) ( y + sizes[ 0 ].cy + 1 ) < TexturesSizes [ iTex ]) {
-            // Yahoo! it fits! 
-            dwTexSize = TexturesSizes [ iTex ] ; 
-            break ; 
-        }; 
-    } ; 
-
-    m_dwTexWidth = m_dwTexHeight = dwTexSize ;
-
-    // Select old objects ( added ) 
-    // Is this needed for compatible DCs? 
-    // The old handles are not not NULL, so it is done "by the book"
-    SelectObject ( hDC, hbmOld );
-    SelectObject ( hDC, hfOld );
-
-    // delete our gdi objects
-    DeleteObject( hbmBitmap );
-    DeleteObject( hFont );
-    DeleteDC( hDC );
-
-    // moved here to allow deletion of GDI objects 
-    if(dwTexSize == 0) {
-        dxgsg9_cat.error() << "CD3DFont InitDeviceObjects() error: Texture didnt fit, creation failed!\n";
-        return E_FAIL;
-    }
-
-    // Re-Create new GDI stuff with the optimal size 
-    // 
-    // Prepare to create a bitmap
-    ZeroMemory( &bmi.bmiHeader,  sizeof(BITMAPINFOHEADER) );
-    bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
-    bmi.bmiHeader.biWidth       =  (int)m_dwTexWidth;
-    bmi.bmiHeader.biHeight      = -(int)m_dwTexHeight;
-    bmi.bmiHeader.biPlanes      = 1;
-    bmi.bmiHeader.biCompression = BI_RGB;
-    bmi.bmiHeader.biBitCount    = 32;
-
-    // Create a DC and a bitmap for the font
-    hDC       = CreateCompatibleDC( NULL );
-    hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS,
-                                  (VOID**)&pBitmapBits, NULL, 0 );
-    SetMapMode( hDC, MM_TEXT );
-
-    // Create a font.  By specifying ANTIALIASED_QUALITY, we might get an
-    // antialiased font, but this is not guaranteed.
-    nHeight  = -MulDiv( m_dwFontHeight, 
-                        (INT)(GetDeviceCaps(hDC, LOGPIXELSY) * m_fTextScale), 72 );
-    dwBold   = (m_dwFontFlags&D3DFONT_BOLD)   ? FW_BOLD : FW_NORMAL;
-    dwItalic = (m_dwFontFlags&D3DFONT_ITALIC) ? TRUE    : FALSE;
-    hFont    = CreateFont( nHeight, 0, 0, 0, dwBold, 
-                           FALSE , // was dwItalic, // see above 
-                           FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
-                           CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
-                           VARIABLE_PITCH, m_strFontName );
-
-    if(NULL==hFont) {
-        dxgsg9_cat.error() << "CD3DFont InitDeviceObjects(): optimal CreateFont failed!  GetLastError=" << GetLastError() << endl;
-        return E_FAIL;
-    }
-
-    hbmOld = ( HBITMAP ) SelectObject ( hDC, hbmBitmap );
-    hfOld  = ( HFONT ) SelectObject ( hDC, hFont );
-
-    // Set text properties
-    SetTextColor( hDC, RGB(255,255,255) );
-    SetBkColor(   hDC, 0x00000000 );
-    SetTextAlign( hDC, TA_TOP );
-
-    // If requested texture is too big, use a smaller texture and smaller font,
-    // and scale up when rendering.
-    D3DCAPS9 d3dCaps;
-    m_pd3dDevice->GetDeviceCaps( &d3dCaps );
-
-    if(m_dwTexWidth > d3dCaps.MaxTextureWidth) {
-        m_fTextScale = (FLOAT)d3dCaps.MaxTextureWidth / (FLOAT)m_dwTexWidth;
-        m_dwTexWidth = m_dwTexHeight = d3dCaps.MaxTextureWidth;
-    }; 
-
-    // Create a new texture for the font
-    hr = m_pd3dDevice->CreateTexture( m_dwTexWidth, m_dwTexHeight, 1,
-                                      0, D3DFMT_A4R4G4B4,
-                                      D3DPOOL_MANAGED, &m_pTexture, NULL);
-
-    if(FAILED(hr)) {
-        SelectObject ( hDC, hbmOld );
-        SelectObject ( hDC, hfOld );
-
-        DeleteObject( hbmBitmap );
-        DeleteObject( hFont );
-        DeleteDC( hDC );
-
-        dxgsg9_cat.error() << "CD3DFont InitDeviceObjs CreateTexture failed!" << D3DERRORSTRING(hr);
-        return hr;
-    }; 
-
-    // Loop through all printable character and output them to the bitmap..
-    // Meanwhile, keep track of the corresponding tex coords for each character.
-    x = 0 ; 
-    y = 0 ; 
-
-    for(c=32; c<127; c++) {
-        str[0] = c;
-        GetTextExtentPoint32( hDC, str, 1, &size );
-        if((DWORD)(x+size.cx+1) > m_dwTexWidth) {
-            x  = 0;
-            y += size.cy+1;
-        }
-
-        // We need one pixel on both sides 
-
-        // plus one here for one pixel on the left
-        ExtTextOut( hDC, x + 1, y, ETO_OPAQUE, NULL, str, 1, NULL );
-
-        m_fTexCoords[c-32][0] = ( (FLOAT) x + 0.5f ) / m_dwTexWidth ;
-        m_fTexCoords[c-32][1] = ( (FLOAT) y + 0.5f ) / m_dwTexHeight ;
-        m_fTexCoords[c-32][2] = ( (FLOAT) x + 0.5f + size.cx ) / m_dwTexWidth;
-        m_fTexCoords[c-32][3] = ( (FLOAT) y + 0.5f + size.cy ) / m_dwTexHeight;
-
-        // plus two here because we also need one more pixel on the right side
-        x += size.cx + 2 ;
-    }
-
-    // Lock the surface and write the alpha values for the set pixels
-    D3DLOCKED_RECT d3dlr;
-    m_pTexture->LockRect( 0, &d3dlr, 0, 0 );
-    BYTE* pDstRow = (BYTE*)d3dlr.pBits;
-    WORD* pDst16;
-    BYTE bAlpha; // 4-bit measure of pixel intensity
-
-    for(y=0; y < m_dwTexHeight; y++) {
-        pDst16 = (WORD*)pDstRow;
-        for(x=0; x < m_dwTexWidth; x++) {
-            bAlpha = (BYTE)((pBitmapBits[m_dwTexWidth*y + x] & 0xff) >> 4);
-            if(bAlpha > 0) {
-                *pDst16++ = (bAlpha << 12) | 0x0fff;
-            } else {
-                *pDst16++ = 0x0000;
-            }
-        }
-        pDstRow += d3dlr.Pitch;
-    }
-
-    // Done updating texture, so clean up used objects
-    m_pTexture->UnlockRect(0);
-
-    SelectObject ( hDC, hbmOld );
-    SelectObject ( hDC, hfOld );
-
-    DeleteObject( hbmBitmap );
-    DeleteObject( hFont );
-    DeleteDC( hDC );
-
-    return RestoreDeviceObjects();
-}
-
-//-----------------------------------------------------------------------------
-// Name: RestoreDeviceObjects()
-// Desc:
-//-----------------------------------------------------------------------------
-HRESULT CD3DFont::RestoreDeviceObjects() {
-    HRESULT hr;
-
-    // Create vertex buffer for the letters
-    if(FAILED( hr = m_pd3dDevice->CreateVertexBuffer(
-            // can be rendered 3d 
-                                                    MAX_NUM_VERTICES*sizeof(FONT3DVERTEX /*FONT2DVERTEX */ ),
-                                                    D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0,
-                                                    D3DPOOL_DEFAULT,  // D3DUSAGE_DYNAMIC makes D3DPOOL_MANAGED impossible
-                                                    &m_pVB, NULL ) )) {
-        dxgsg9_cat.error() << "CD3DFont CreateVB failed!" << D3DERRORSTRING(hr);
-        return hr;
-    }
-
-    PRINT_REFCNT(dxgsg9,m_pd3dDevice);
-
-    // Create the state blocks for rendering text
-    for(UINT which=0; which<2; which++) {
-        m_pd3dDevice->BeginStateBlock();
-        m_pd3dDevice->SetTexture( 0, m_pTexture );
-
-        if(D3DFONT_ZENABLE & m_dwFontFlags)
-            m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
-        else
-            m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
-
-        m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
-        m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND,   D3DBLEND_SRCALPHA );
-        m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND,  D3DBLEND_INVSRCALPHA );
-        m_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE,  TRUE );
-        m_pd3dDevice->SetRenderState( D3DRS_ALPHAREF,         0x08 );
-        m_pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC,  D3DCMP_GREATEREQUAL );
-        m_pd3dDevice->SetRenderState( D3DRS_FILLMODE,   D3DFILL_SOLID );
-        m_pd3dDevice->SetRenderState( D3DRS_CULLMODE,   D3DCULL_CCW );
-        m_pd3dDevice->SetRenderState( D3DRS_STENCILENABLE,    FALSE );
-        m_pd3dDevice->SetRenderState( D3DRS_CLIPPING,         TRUE );
-        m_pd3dDevice->SetRenderState( D3DRS_ANTIALIASEDLINEENABLE,    FALSE );
-        m_pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE,  FALSE );
-        m_pd3dDevice->SetRenderState( D3DRS_VERTEXBLEND,      FALSE );
-        m_pd3dDevice->SetRenderState( D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE );
-        m_pd3dDevice->SetRenderState( D3DRS_FOGENABLE,        FALSE );
-        m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_POINT );
-        m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
-        m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE );
-        m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
-        m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
-        m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
-        m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
-        m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
-        m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
-        m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
-        m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
-        m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_DISABLE );
-        m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );
-
-        if(which==0)
-            m_pd3dDevice->EndStateBlock( &m_pSBSavedStateBlock );
-        else
-            m_pd3dDevice->EndStateBlock( &m_pSBDrawTextStateBlock );
-    }
-
-    return S_OK;
-}
-
-
-//-----------------------------------------------------------------------------
-// Name: InvalidateDeviceObjects()
-// Desc: Destroys all device-dependent objects
-//-----------------------------------------------------------------------------
-HRESULT CD3DFont::InvalidateDeviceObjects() {
-    HRESULT hr;
-
-    PRINT_REFCNT(dxgsg9,m_pd3dDevice);
-
-    if(IS_VALID_PTR(m_pd3dDevice)) {
-        // undo SetStreamSource before releasing VB
-
-        IDirect3DVertexBuffer9 *pStreamData=NULL;
-        UINT StreamStride;
-        hr = m_pd3dDevice->GetStreamSource(0,&pStreamData,NULL,&StreamStride);
-        SAFE_RELEASE(pStreamData);  // undo GetStreamSource AddRef
-        if(pStreamData==m_pVB)
-            hr = m_pd3dDevice->SetStreamSource(0,NULL,0,0);
-    }
-
-    PRINT_REFCNT(dxgsg9,m_pVB);
-
-    RELEASE(m_pVB,dxgsg9,"d3dfont VB",RELEASE_ONCE);
-
-    PRINT_REFCNT(dxgsg9,m_pd3dDevice);
-
-    /* not necessary in DX9
-    // Delete the state blocks
-    if(m_pd3dDevice) {
-        assert(IS_VALID_PTR(m_pd3dDevice));
-        if(m_pSBSavedStateBlock)
-            m_pd3dDevice->DeleteStateBlock( m_pSBSavedStateBlock );
-        if(m_pSBDrawTextStateBlock)
-            m_pd3dDevice->DeleteStateBlock( m_pSBDrawTextStateBlock );
-    }
-    */
-
-    PRINT_REFCNT(dxgsg9,m_pd3dDevice);
-
-    m_pSBSavedStateBlock    = NULL;
-    m_pSBDrawTextStateBlock = NULL;
-
-    return S_OK;
-}
-
-
-//-----------------------------------------------------------------------------
-// Name: DeleteDeviceObjects()
-// Desc: Destroys all device-dependent objects
-//-----------------------------------------------------------------------------
-HRESULT CD3DFont::DeleteDeviceObjects() {
-    PRINT_REFCNT(dxgsg9,m_pd3dDevice);
-
-    InvalidateDeviceObjects();
-
-    SAFE_RELEASE( m_pTexture );
-
-    PRINT_REFCNT(dxgsg9,m_pd3dDevice);
-
-    m_pd3dDevice = NULL;
-
-    return S_OK;
-}
-
-
-//-----------------------------------------------------------------------------
-// Name: GetTextExtent()
-// Desc: Get the dimensions of a text string
-//-----------------------------------------------------------------------------
-HRESULT CD3DFont::GetTextExtent( TCHAR* strText, SIZE* pSize ) {
-    if(NULL==strText || NULL==pSize)
-        return E_FAIL;
-
-    FLOAT fRowWidth  = 0.0f;
-    FLOAT fRowHeight = (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight;
-    FLOAT fWidth     = 0.0f;
-    FLOAT fHeight    = fRowHeight;
-
-    while(*strText) {
-        TCHAR c = *strText++;
-
-        if(c == _T('\n')) {
-            fRowWidth = 0.0f;
-            fHeight  += fRowHeight;
-        }
-        if(c < _T(' '))
-            continue;
-
-        FLOAT tx1 = m_fTexCoords[c-32][0];
-        FLOAT tx2 = m_fTexCoords[c-32][2];
-
-        fRowWidth += (tx2-tx1)*m_dwTexWidth;
-
-        if(fRowWidth > fWidth)
-            fWidth = fRowWidth;
-    }
-
-    pSize->cx = (int)fWidth;
-    pSize->cy = (int)fHeight;
-
-    return S_OK;
-}
-
-//-----------------------------------------------------------------------------
-// Name: DrawTextScaled()
-// Desc: Draws scaled 2D text.  Note that x and y are in viewport coordinates
-//       (ranging from -1 to +1).  fXScale and fYScale are the size fraction 
-//       relative to the entire viewport.  For example, a fXScale of 0.25 is
-//       1/8th of the screen width.  This allows you to output text at a fixed
-//       fraction of the viewport, even if the screen or window size changes.
-//-----------------------------------------------------------------------------
-HRESULT CD3DFont::DrawTextScaled( FLOAT x, FLOAT y, FLOAT z,
-                                  FLOAT fXScale, FLOAT fYScale, DWORD dwColor,
-                                  TCHAR* strText, DWORD dwFlags ) {
-    if(m_pd3dDevice == NULL)
-        return E_FAIL;
-
-    HRESULT hr ; 
-    if(m_bBeginText) {
-        hr = DeferedDrawTextScaled ( x, y, z, fXScale, fYScale, dwColor, strText, dwFlags ) ; 
-    } else {
-        BeginText ( ) ; 
-        hr = DeferedDrawTextScaled ( x, y, z, fXScale, fYScale, dwColor, strText, dwFlags ) ; 
-        if(! FAILED ( hr ))
-            EndText ( ) ;
-    } ; 
-
-    return hr ;
-}
-
-//-----------------------------------------------------------------------------
-// Name: DrawText()
-// Desc: Draws 2D text
-//-----------------------------------------------------------------------------
-HRESULT CD3DFont::DrawText( FLOAT sx, FLOAT sy, DWORD dwColor,
-                            TCHAR* strText, DWORD dwFlags ) {
-    if(m_pd3dDevice == NULL)
-        return E_FAIL;
-
-    HRESULT hr ; 
-    if(m_bBeginText) {
-        hr = DeferedDrawText ( sx, sy, dwColor, strText, dwFlags ) ; 
-    } else {
-        BeginText(); 
-        hr = DeferedDrawText ( sx, sy, dwColor, strText, dwFlags ) ; 
-        if(! FAILED ( hr ))
-            EndText ( ) ;
-    } ; 
-
-    return hr ;
-}
-
-
-void CD3DFont::ClearBeginEndData ( void ) {
-    m_nDeferedCalls = 0 ; 
-    m_TextBuffer [ 0 ] = 0 ; 
-    m_pTextBuffer = & m_TextBuffer [ 0 ] ; 
-} 
-
-HRESULT CD3DFont::BeginText ( void ) {
-    m_bBeginText = true ; 
-    ClearBeginEndData() ; 
-
-    return S_OK ; 
-} 
-
-HRESULT CD3DFont::DeferedDrawTextScaled
-( FLOAT x, FLOAT y, FLOAT z, 
-  FLOAT fXScale, FLOAT fYScale, DWORD dwColor, 
-  TCHAR* strText, DWORD dwFlags ) {
-    return 
-    DeferedDraw ( true , x, y, z, fXScale, fYScale, dwColor, strText, dwFlags ) ; 
-} 
-
-HRESULT CD3DFont::DeferedDrawText
-( FLOAT x, FLOAT y, DWORD dwColor, 
-  TCHAR* strText, DWORD dwFlags ) {
-    return 
-    DeferedDraw ( false , x, y, 0.0f , 0.0f , 0.0f , dwColor, strText, dwFlags ) ; 
-} 
-
-HRESULT CD3DFont::DeferedDraw
-( bool bScaled , 
-  FLOAT x, FLOAT y, FLOAT z, 
-  FLOAT fXScale, FLOAT fYScale, DWORD dwColor, 
-  TCHAR* strText, DWORD dwFlags ) {
-    if(m_nDeferedCalls >= MaxCalls) {
-        dxgsg9_cat.error() << "CD3DFont DeferedDraw() error, MaxCalls exceeded!\n";
-        return E_FAIL ;
-    }
-
-    // we need to make a deep copy of the string 
-    // the user object might have fallen out of scope
-    // when it will be time to render 
-    int nStrLen = strlen ( strText ) + 1 ; 
-    int nUsed = m_pTextBuffer - & m_pTextBuffer [ 0 ] ; 
-    if(nUsed + nStrLen > TextBufferLength) {
-        dxgsg9_cat.error() << "CD3DFont DeferedDraw() error, TextBufferLength exceeded!\n";
-        return E_FAIL ;
-    }
-
-    strcpy ( m_pTextBuffer , strText ) ; 
-    m_DTArgs [ m_nDeferedCalls ].m_strText = m_pTextBuffer ; 
-    m_pTextBuffer += nStrLen ; 
-
-    m_DTArgs [ m_nDeferedCalls ].m_bScaled = bScaled ; 
-    m_DTArgs [ m_nDeferedCalls ].m_x = x ; 
-    m_DTArgs [ m_nDeferedCalls ].m_y = y ; 
-    m_DTArgs [ m_nDeferedCalls ].m_z = z ; 
-    m_DTArgs [ m_nDeferedCalls ].m_fXScale = fXScale ; 
-    m_DTArgs [ m_nDeferedCalls ].m_fYScale = fYScale ; 
-    m_DTArgs [ m_nDeferedCalls ].m_dwColor = dwColor ; 
-    m_DTArgs [ m_nDeferedCalls ].m_dwFlags = dwFlags ; 
-
-    m_nDeferedCalls ++ ; 
-
-    return S_OK ; 
-} 
-
-HRESULT CD3DFont::EndText ( void ) {
-    if(m_pd3dDevice == NULL)
-        return E_FAIL;
-    HRESULT hr;
-
-    assert(IS_VALID_PTR(m_pVB));
-
-    UINT SavedStreamStride;
-    IDirect3DVertexBuffer9 *pSavedStreamData=NULL;
-    IDirect3DVertexShader9 *pSavedVertexShader=NULL;
-    IDirect3DPixelShader9 *pSavedPixelShader=NULL;
-
-    hr = m_pd3dDevice->GetVertexShader(&pSavedVertexShader);
-    hr = m_pd3dDevice->GetPixelShader(&pSavedPixelShader);
-
-    // Set up renderstate
-    hr = m_pSBSavedStateBlock->Capture();
-    hr = m_pSBDrawTextStateBlock->Apply();
-    /*
-    if(pSavedVertexShader!=D3DFVF_FONT2DVERTEX)
-        hr = m_pd3dDevice->SetVertexShader(D3DFVF_FONT2DVERTEX);
-    if(pSavedPixelShader!=NULL)
-        hr = m_pd3dDevice->SetPixelShader(NULL);
-    */
-    hr = m_pd3dDevice->SetVertexShader(NULL);
-    hr = m_pd3dDevice->SetPixelShader(NULL);
-
-    hr = m_pd3dDevice->GetStreamSource(0,&pSavedStreamData,NULL,&SavedStreamStride);
-    if(FAILED(hr)) {
-        dxgsg9_cat.error() << "CD3DFont EndText GetStreamSource() failed!" << D3DERRORSTRING(hr);
-        return E_FAIL;
-    }
-
-    // undo GetStreamSource AddRef
-    SAFE_RELEASE(pSavedStreamData);
-
-    if((pSavedStreamData!=m_pVB)||(SavedStreamStride!=sizeof(FONT2DVERTEX))) {
-        hr = m_pd3dDevice->SetStreamSource(0,m_pVB,0,sizeof(FONT2DVERTEX));
-        if(FAILED(hr)) {
-            dxgsg9_cat.error() << "CD3DFont EndText initial SetStreamSource() failed!" << D3DERRORSTRING(hr);
-            return E_FAIL;
-        }
-    }
-
-    // Set filter states
-    //
-    // filter if any in our list is specified filtered 
-    //
-    // This functionality is different from the original D3DFont 
-    // but is a significant speed increase
-    //
-    // User will make another batch if necessary
-    //  
-    bool bFiltered = false ; 
-    UINT i;
-    for(i = 0 ; i < m_nDeferedCalls ; ++ i) {
-        DWORD   dwFlags = m_DTArgs [ i ].m_dwFlags ; 
-        if(dwFlags & D3DFONT_FILTERED) {
-            bFiltered = true ; 
-            break ; 
-        }
-    } ; 
-    if(bFiltered) {
-        m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
-        m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
-    }; 
-
-    // useless if nothing is scaled but should be fast enough 
-    D3DVIEWPORT9 vp;
-    m_pd3dDevice->GetViewport( &vp );
-    FLOAT fLineHeight = ( m_fTexCoords[0][3] - m_fTexCoords[0][1] ) * m_dwTexHeight;
-
-    // Fill vertex buffer
-    FONT2DVERTEX* pVertices;
-    DWORD         dwNumTriangles = 0L;
-    m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
-
-    bool bItalic = 0 != ( m_dwFontFlags & D3DFONT_ITALIC ) ; 
-    // loop on our batched sets of arguments 
-    for(i = 0 ; i < m_nDeferedCalls ; ++ i) {
-        bool    bScaled = m_DTArgs [ i ].m_bScaled ; 
-        FLOAT   x       = m_DTArgs [ i ].m_x       ; 
-        FLOAT   y       = m_DTArgs [ i ].m_y       ; 
-        FLOAT   z       = m_DTArgs [ i ].m_z       ; 
-        FLOAT   fXScale = m_DTArgs [ i ].m_fXScale ; 
-        FLOAT   fYScale = m_DTArgs [ i ].m_fYScale ; 
-        DWORD   dwColor = m_DTArgs [ i ].m_dwColor ; 
-        TCHAR * strText = m_DTArgs [ i ].m_strText ; 
-
-        if(bScaled) {
-
-            FLOAT sx  = (x+1.0f)*vp.Width/2;
-            FLOAT sy  = (y-1.0f)*vp.Height/2;
-            FLOAT sz  = z;
-            FLOAT rhw = 1.0f;
-            FLOAT fStartX = sx;
-
-            FLOAT fBend = 0.0f ; 
-            if(bItalic)
-                fBend = fYScale*vp.Height / 4.0f ;
-
-            while(*strText) {
-                TCHAR c = *strText++;
-
-                if(c == _T('\n')) {
-                    sx  = fStartX;
-                    sy += fYScale*vp.Height;
-                }
-                if(c < _T(' '))
-                    continue;
-
-                FLOAT tx1 = m_fTexCoords[c-32][0];
-                FLOAT ty1 = m_fTexCoords[c-32][1];
-                FLOAT tx2 = m_fTexCoords[c-32][2];
-                FLOAT ty2 = m_fTexCoords[c-32][3];
-
-                FLOAT w = (tx2-tx1)*m_dwTexWidth;
-                FLOAT h = (ty2-ty1)*m_dwTexHeight;
-
-                w *= (fXScale*vp.Height)/fLineHeight;
-                h *= (fYScale*vp.Height)/fLineHeight;
-
-                if(c != _T(' ')) {
-                    *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+h-0.5f,sz,rhw), dwColor, tx1, ty2 );
-                    *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f + fBend,sy+0-0.5f,sz,rhw), dwColor, tx1, ty1 );
-                    *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,sz,rhw), dwColor, tx2, ty2 );
-                    *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f + fBend,sy+0-0.5f,sz,rhw), dwColor, tx2, ty1 );
-                    *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,sz,rhw), dwColor, tx2, ty2 );
-                    *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f + fBend,sy+0-0.5f,sz,rhw), dwColor, tx1, ty1 );
-                    dwNumTriangles += 2;
-
-                    if(dwNumTriangles*3 > (MAX_NUM_VERTICES-6)) {
-                        // Unlock, render, and relock the vertex buffer
-                        m_pVB->Unlock();
-                        m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
-                        m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
-                        dwNumTriangles = 0L;
-                    }
-                }
-
-                sx += w;
-            } ; 
-        } else {  // not scaled 
-            FLOAT fBend = 0.0f ; 
-            if(bItalic)
-                fBend = fLineHeight / 4.0f ;
-
-            // Lazy guy...
-            FLOAT sx = x ; 
-            FLOAT sy = y ; 
-
-            FLOAT fStartX = sx;
-            while(*strText) {
-                TCHAR c = *strText++;
-
-                if(c == _T('\n')) {
-                    sx = fStartX ;
-                    sy += fLineHeight ;
-                }
-                if(c < _T(' '))
-                    continue;
-
-                FLOAT tx1 = m_fTexCoords[c-32][0];
-                FLOAT ty1 = m_fTexCoords[c-32][1];
-                FLOAT tx2 = m_fTexCoords[c-32][2];
-                FLOAT ty2 = m_fTexCoords[c-32][3];
-
-                FLOAT w = (tx2-tx1) *  m_dwTexWidth / m_fTextScale;
-                FLOAT h = (ty2-ty1) * m_dwTexHeight / m_fTextScale;
-
-                if(c != _T(' ')) {
-                    *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx1, ty2 );
-                    *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f + fBend,sy+0-0.5f,0.9f,1.0f), dwColor, tx1, ty1 );
-                    *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx2, ty2 );
-                    *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f + fBend,sy+0-0.5f,0.9f,1.0f), dwColor, tx2, ty1 );
-                    *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx2, ty2 );
-                    *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f + fBend,sy+0-0.5f,0.9f,1.0f), dwColor, tx1, ty1 );
-                    dwNumTriangles += 2;
-
-                    if(dwNumTriangles*3 > (MAX_NUM_VERTICES-6)) {
-                        // Unlock, render, and relock the vertex buffer
-                        m_pVB->Unlock();
-                        m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
-                        pVertices = NULL;
-                        m_pVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_DISCARD );
-                        dwNumTriangles = 0L;
-                    }
-                };  // endif not blank 
-
-                sx += w;
-            } ; // end while 
-
-        } ; // end if else scaled 
-
-    } ; // end for 
-
-    m_bBeginText = false ; 
-    ClearBeginEndData ( ) ; 
-
-    // Unlock and render the vertex buffer
-    m_pVB->Unlock();
-    if(dwNumTriangles > 0)
-        m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
-
-    // Restore the modified renderstates
-    m_pSBSavedStateBlock->Apply();
-    /*
-    if((hSavedVertexShader!=NULL) && (hSavedVertexShader!=D3DFVF_FONT2DVERTEX))
-        m_pd3dDevice->SetVertexShader(hSavedVertexShader);
-    if(hSavedPixelShader!=NULL)
-        m_pd3dDevice->SetPixelShader(hSavedPixelShader);
-    */
-    m_pd3dDevice->SetVertexShader(pSavedVertexShader);
-    m_pd3dDevice->SetPixelShader(pSavedPixelShader);
-
-    if(IS_VALID_PTR(pSavedStreamData) && ((pSavedStreamData!=m_pVB)||(SavedStreamStride!=sizeof(FONT2DVERTEX)))) {
-        hr = m_pd3dDevice->SetStreamSource(0,pSavedStreamData,0,SavedStreamStride);
-        if(FAILED(hr)) {
-            dxgsg9_cat.error() << "CD3DFont EndText restore SetStreamSource() failed!" << D3DERRORSTRING(hr);
-            return E_FAIL;
-        }
-        pSavedStreamData->Release();
-    }
-
-    return S_OK;
-} 
-
-#if 0
-// dont need this now
-//-----------------------------------------------------------------------------
-// Name: Render3DText()
-// Desc: Renders 3D text
-//-----------------------------------------------------------------------------
-HRESULT CD3DFont::Render3DText( TCHAR* strText, DWORD dwFlags ) {
-    if(m_pd3dDevice == NULL)
-        return E_FAIL;
-
-    // Setup renderstate
-    m_pd3dDevice->CaptureStateBlock( m_pSBSavedStateBlock );
-    m_pd3dDevice->ApplyStateBlock( m_pSBDrawTextStateBlock );
-    m_pd3dDevice->SetVertexShader( D3DFVF_FONT3DVERTEX );
-    m_pd3dDevice->SetPixelShader( NULL );
-    m_pd3dDevice->SetStreamSource( 0, m_pVB, sizeof(FONT3DVERTEX) );
-
-    // Set filter states
-    if(dwFlags & D3DFONT_FILTERED) {
-        m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
-        m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
-    }
-
-    // Position for each text element
-    FLOAT x = 0.0f;
-    FLOAT y = 0.0f;
-
-    // Center the text block at the origin
-    if(dwFlags & D3DFONT_CENTERED) {
-        SIZE sz;
-        GetTextExtent( strText, &sz );
-        x = -(((FLOAT)sz.cx)/10.0f)/2.0f;
-        y = -(((FLOAT)sz.cy)/10.0f)/2.0f;
-    }
-
-    // Turn off culling for two-sided text
-    if(dwFlags & D3DFONT_TWOSIDED)
-        m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
-
-    FLOAT fStartX = x;
-    TCHAR c;
-
-    // Fill vertex buffer
-    FONT3DVERTEX* pVertices;
-    // DWORD         dwVertex       = 0L; // not ref'ed
-    DWORD         dwNumTriangles = 0L;
-    m_pVB->Lock( 0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD );
-
-    bool bItalic = 0 != ( m_dwFontFlags & D3DFONT_ITALIC ) ; 
-    FLOAT fBend = 0.0f ; 
-    if(bItalic)
-        fBend = ( ( m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight/10.0f ) / 4.0f ;
-
-    while(c = *strText++) {
-        if(c == '\n') {
-            x = fStartX;
-            y -= (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight/10.0f;
-        }
-        if(c < 32)
-            continue;
-
-        FLOAT tx1 = m_fTexCoords[c-32][0];
-        FLOAT ty1 = m_fTexCoords[c-32][1];
-        FLOAT tx2 = m_fTexCoords[c-32][2];
-        FLOAT ty2 = m_fTexCoords[c-32][3];
-
-        FLOAT w = (tx2-tx1) * m_dwTexWidth  / ( 10.0f * m_fTextScale );
-        FLOAT h = (ty2-ty1) * m_dwTexHeight / ( 10.0f * m_fTextScale );
-
-        if(c != _T(' ')) {
-            *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+0,y+0,0), D3DXVECTOR3(0,0,-1), tx1, ty2 );
-            *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+0 + fBend ,y+h,0), D3DXVECTOR3(0,0,-1), tx1, ty1 );
-            *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+w,y+0,0), D3DXVECTOR3(0,0,-1), tx2, ty2 );
-            *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+w + fBend ,y+h,0), D3DXVECTOR3(0,0,-1), tx2, ty1 );
-            *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+w,y+0,0), D3DXVECTOR3(0,0,-1), tx2, ty2 );
-            *pVertices++ = InitFont3DVertex( D3DXVECTOR3(x+0 + fBend ,y+h,0), D3DXVECTOR3(0,0,-1), tx1, ty1 );
-            dwNumTriangles += 2;
-
-            if(dwNumTriangles*3 > (MAX_NUM_VERTICES-6)) {
-                // Unlock, render, and relock the vertex buffer
-                m_pVB->Unlock();
-                m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
-                m_pVB->Lock( 0, 0, (BYTE**)&pVertices, D3DLOCK_DISCARD );
-                dwNumTriangles = 0L;
-            }
-        }
-
-        x += w;
-    }
-
-    // Unlock and render the vertex buffer
-    m_pVB->Unlock();
-    if(dwNumTriangles > 0)
-        m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, dwNumTriangles );
-
-    // Restore the modified renderstates
-    m_pd3dDevice->ApplyStateBlock( m_pSBSavedStateBlock );
-
-    return S_OK;
-}
-#endif

+ 0 - 112
panda/src/dxgsg9/d3dfont9.h

@@ -1,112 +0,0 @@
-//--------------------------------------------------------------------------------------------
-// File: D3DFont.h
-//
-// Desc: Texture-based font class
-//       based on a modified version of DXSDK CD3DFont from http://www.lafaqmfc.com/directx.htm
-//       Note that this is faster than ID3DXFont, which calls GDI in Draw()
-//---------------------------------------------------------------------------------------------
-#ifndef D3DFONT_H
-#define D3DFONT_H
-#include <tchar.h>
-#include <d3d9.h>
-
-// Font creation flags
-#define D3DFONT_BOLD        0x0001
-#define D3DFONT_ITALIC      0x0002
-#define D3DFONT_ZENABLE     0x0004
-
-// Font rendering flags
-#define D3DFONT_CENTERED    0x0001
-#define D3DFONT_TWOSIDED    0x0002
-#define D3DFONT_FILTERED    0x0004
-
-//-----------------------------------------------------------------------------
-// Name: class CD3DFont
-// Desc: Texture-based font class for doing text in a 3D scene.
-//-----------------------------------------------------------------------------
-class CD3DFont
-{
-    enum 
-    { 
-        D3DFVF_FONT2DVERTEX = (D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1) , 
-        D3DFVF_FONT3DVERTEX = (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1) , 
-        TextBufferLength = 1024 , 
-        MAX_NUM_VERTICES = TextBufferLength * 6 , 
-        MaxCalls = 30 
-    } ; 
-
-    TCHAR   m_strFontName[80];            // Font properties
-    DWORD   m_dwFontHeight;
-    DWORD   m_dwFontFlags;
-
-    LPDIRECT3DDEVICE9       m_pd3dDevice; // A D3DDevice used for rendering
-    LPDIRECT3DTEXTURE9      m_pTexture;   // The d3d texture for this font
-    LPDIRECT3DVERTEXBUFFER9 m_pVB;        // VertexBuffer for rendering text
-    DWORD   m_dwTexWidth;                 // Texture dimensions
-    DWORD   m_dwTexHeight;
-    FLOAT   m_fTextScale;
-    FLOAT   m_fTexCoords[128-32][4];
-
-    // Stateblocks for setting and restoring render states
-    IDirect3DStateBlock9* m_pSBSavedStateBlock;
-    IDirect3DStateBlock9* m_pSBDrawTextStateBlock;
-
-    struct DrawTextArgs 
-    {
-        bool  m_bScaled ; 
-        FLOAT m_x ;  FLOAT m_y ;  FLOAT m_z ; 
-        FLOAT m_fXScale ; FLOAT m_fYScale ; 
-        DWORD m_dwColor ;  
-        TCHAR *m_strText ; 
-        DWORD m_dwFlags ; 
-    } ; 
-
-    DrawTextArgs m_DTArgs [ MaxCalls ] ; 
-    char    m_TextBuffer  [ TextBufferLength ] ; 
-    char   *m_pTextBuffer ; 
-    UINT    m_nDeferedCalls ;
-    bool    m_bBeginText ; 
-    inline  HRESULT DeferedDrawText( FLOAT x, FLOAT y, DWORD dwColor, 
-                      TCHAR* strText, DWORD dwFlags=0L );
-    inline  HRESULT DeferedDrawTextScaled ( FLOAT x, FLOAT y, FLOAT z, 
-                            FLOAT fXScale, FLOAT fYScale, DWORD dwColor, 
-                            TCHAR* strText, DWORD dwFlags=0L ) ; 
-    inline  HRESULT DeferedDraw
-            ( bool bScaled , 
-              FLOAT x, FLOAT y, FLOAT z, 
-              FLOAT fXScale, FLOAT fYScale, DWORD dwColor, 
-              TCHAR* strText, DWORD dwFlags ) ; 
-
-    inline  void ClearBeginEndData (void ) ; 
-
-
-public:
-    // 2D and 3D text drawing functions
-    HRESULT BeginText ( void ) ;
-    HRESULT EndText ( void ) ;
-
-    HRESULT DrawText( FLOAT x, FLOAT y, DWORD dwColor, 
-                      TCHAR* strText, DWORD dwFlags=0L );
-    HRESULT DrawTextScaled ( FLOAT x, FLOAT y, FLOAT z, 
-                            FLOAT fXScale, FLOAT fYScale, DWORD dwColor, 
-                            TCHAR* strText, DWORD dwFlags=0L ) ; 
-
-   // HRESULT Render3DText( TCHAR* strText, DWORD dwFlags=0L );
-    
-    // Function to get extent of text
-    HRESULT GetTextExtent( TCHAR* strText, SIZE* pSize );
-
-    // Initializing and destroying device-dependent objects
-    HRESULT InitDeviceObjects(LPDIRECT3DDEVICE9 pd3dDevice);
-    HRESULT RestoreDeviceObjects();
-    HRESULT InvalidateDeviceObjects();
-    HRESULT DeleteDeviceObjects();
-
-    // Constructor / destructor
-    CD3DFont( TCHAR* strFontName, DWORD dwHeight, DWORD dwFlags=0L );
-    ~CD3DFont();
-};
-
-#endif
-
-

+ 47 - 0
panda/src/dxgsg9/dxGeomMunger9.I

@@ -0,0 +1,47 @@
+// Filename: dxGeomMunger9.I
+// Created by:  drose (11Mar05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXGeomMunger9::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+INLINE DXGeomMunger9::
+DXGeomMunger9(GraphicsStateGuardian *gsg, const RenderState *state) :
+  StandardMunger(gsg, state, 1, NT_packed_dabc, C_color),
+  _texture(state->get_texture()),
+  _tex_gen(state->get_tex_gen())
+{
+  if (_texture != (TextureAttrib *)NULL) {
+    _texture = _texture->filter_to_max(gsg->get_max_texture_stages());
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXGeomMunger9::operator new
+//       Access: Public
+//  Description: Calls up to do_operator_new() to implement the
+//               low-overhead allocation/deallocation for this type of
+//               GeomMunger.
+////////////////////////////////////////////////////////////////////
+INLINE void *DXGeomMunger9::
+operator new(size_t size) {
+  return do_operator_new(size, &_deleted_chain);
+}
+

+ 189 - 0
panda/src/dxgsg9/dxGeomMunger9.cxx

@@ -0,0 +1,189 @@
+// Filename: dxGeomMunger9.cxx
+// Created by:  drose (11Mar05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dxGeomMunger9.h"
+#include "geomVertexReader.h"
+#include "geomVertexWriter.h"
+#include "config_dxgsg9.h"
+
+GeomMunger *DXGeomMunger9::_deleted_chain = NULL;
+TypeHandle DXGeomMunger9::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXGeomMunger9::munge_format_impl
+//       Access: Protected, Virtual
+//  Description: Given a source GeomVertexFormat, converts it if
+//               necessary to the appropriate format for rendering.
+////////////////////////////////////////////////////////////////////
+CPT(GeomVertexFormat) DXGeomMunger9::
+munge_format_impl(const GeomVertexFormat *orig,
+                  const GeomVertexAnimationSpec &animation) {
+  if (dxgsg9_cat.is_debug()) {
+    if (animation.get_animation_type() != AT_none) {
+      dxgsg9_cat.debug()
+        << "preparing animation type " << animation << " for " << *orig
+  << "\n";
+    }
+  }
+  // We have to build a completely new format that includes only the
+  // appropriate components, in the appropriate order, in just one
+  // array.
+  PT(GeomVertexFormat) new_format = new GeomVertexFormat(*orig);
+  new_format->set_animation(animation);
+  PT(GeomVertexArrayFormat) new_array_format = new GeomVertexArrayFormat;
+
+  const GeomVertexColumn *vertex_type = orig->get_vertex_column();
+  const GeomVertexColumn *normal_type = orig->get_normal_column();
+  const GeomVertexColumn *color_type = orig->get_color_column();
+
+  if (vertex_type != (const GeomVertexColumn *)NULL) {
+    new_array_format->add_column
+      (InternalName::get_vertex(), 3, NT_float32,
+       vertex_type->get_contents());
+    new_format->remove_column(vertex_type->get_name());
+
+  } else {
+    // If we don't have a vertex type, not much we can do.
+    return orig;
+  }
+
+  if (animation.get_animation_type() == AT_hardware &&
+      animation.get_num_transforms() > 0) {
+    if (animation.get_num_transforms() > 1) {
+      // If we want hardware animation, we need to reserve space for the
+      // blend weights.
+      new_array_format->add_column
+        (InternalName::get_transform_weight(), animation.get_num_transforms() - 1,
+         NT_float32, C_other);
+    }
+
+    if (animation.get_indexed_transforms()) {
+      // Also, if we'll be indexing into the transform table, reserve
+      // space for the index.
+      new_array_format->add_column
+        (InternalName::get_transform_index(), 1,
+         NT_packed_dcba, C_index);
+    }
+
+    // Make sure the old weights and indices are removed, just in
+    // case.
+    new_format->remove_column(InternalName::get_transform_weight());
+    new_format->remove_column(InternalName::get_transform_index());
+
+    // And we don't need the transform_blend table any more.
+    new_format->remove_column(InternalName::get_transform_blend());
+  }
+
+  if (normal_type != (const GeomVertexColumn *)NULL) {
+    new_array_format->add_column
+      (InternalName::get_normal(), 3, NT_float32, C_vector);
+    new_format->remove_column(normal_type->get_name());
+  }
+
+  if (color_type != (const GeomVertexColumn *)NULL) {
+    new_array_format->add_column
+      (InternalName::get_color(), 1, NT_packed_dabc, C_color);
+    new_format->remove_column(color_type->get_name());
+  }
+
+  // To support multitexture, we will need to add all of the relevant
+  // texcoord types, and in the correct order.
+
+  // Now set up each of the active texture coordinate stages--or at
+  // least those for which we're not generating texture coordinates
+  // automatically.
+
+  // Now copy all of the texture coordinates in, in order by stage
+  // index.  But we have to reuse previous columns.
+  if (_texture != (TextureAttrib *)NULL) {
+    typedef pset<const InternalName *> UsedStages;
+    UsedStages used_stages;
+
+    int num_stages = _texture->get_num_on_stages();
+    for (int i = 0; i < num_stages; ++i) {
+      TextureStage *stage = _texture->get_on_stage(i);
+
+      const InternalName *name = stage->get_texcoord_name();
+      if (used_stages.insert(name).second) {
+        // This is the first time we've encountered this texcoord name.
+        const GeomVertexColumn *texcoord_type = orig->get_column(name);
+
+        if (texcoord_type != (const GeomVertexColumn *)NULL) {
+          new_array_format->add_column
+            (name, texcoord_type->get_num_values(), NT_float32, C_texcoord);
+        } else {
+          // We have to add something as a placeholder, even if the
+          // texture coordinates aren't defined.
+          new_array_format->add_column(name, 2, NT_float32, C_texcoord);
+        }
+        new_format->remove_column(name);
+      }
+    }
+  }
+
+  // Make sure the FVF-style array we just built up is first in the
+  // list.
+  new_format->insert_array(0, new_array_format);
+
+  return GeomVertexFormat::register_format(new_format);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXGeomMunger9::compare_to_impl
+//       Access: Protected, Virtual
+//  Description: Called to compare two GeomMungers who are known to be
+//               of the same type, for an apples-to-apples comparison.
+//               This will never be called on two pointers of a
+//               different type.
+////////////////////////////////////////////////////////////////////
+int DXGeomMunger9::
+compare_to_impl(const GeomMunger *other) const {
+  const DXGeomMunger9 *om = DCAST(DXGeomMunger9, other);
+  if (_texture != om->_texture) {
+    return _texture < om->_texture ? -1 : 1;
+  }
+  if (_tex_gen != om->_tex_gen) {
+    return _tex_gen < om->_tex_gen ? -1 : 1;
+  }
+
+  return StandardMunger::compare_to_impl(other);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXGeomMunger9::geom_compare_to_impl
+//       Access: Protected, Virtual
+//  Description: Called to compare two GeomMungers who are known to be
+//               of the same type, for an apples-to-apples comparison.
+//               This will never be called on two pointers of a
+//               different type.
+////////////////////////////////////////////////////////////////////
+int DXGeomMunger9::
+geom_compare_to_impl(const GeomMunger *other) const {
+  // Unlike GLGeomMunger, we do consider _texture and _tex_gen
+  // important for this purpose, since they control the number and
+  // order of texture coordinates we might put into the FVF.
+  const DXGeomMunger9 *om = DCAST(DXGeomMunger9, other);
+  if (_texture != om->_texture) {
+    return _texture < om->_texture ? -1 : 1;
+  }
+  if (_tex_gen != om->_tex_gen) {
+    return _tex_gen < om->_tex_gen ? -1 : 1;
+  }
+
+  return StandardMunger::geom_compare_to_impl(other);
+}

+ 75 - 0
panda/src/dxgsg9/dxGeomMunger9.h

@@ -0,0 +1,75 @@
+// Filename: dxGeomMunger9.h
+// Created by:  drose (11Mar05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DXGEOMMUNGER9_H
+#define DXGEOMMUNGER9_H
+
+#include "pandabase.h"
+#include "standardMunger.h"
+#include "graphicsStateGuardian.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : DXGeomMunger9
+// Description : This specialization on GeomMunger finesses vertices
+//               for DirectX rendering.  In particular, it makes sure
+//               colors are stored in DirectX's packed_argb format,
+//               and that all relevant components are packed into a
+//               single array, in the correct order.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDADX DXGeomMunger9 : public StandardMunger {
+public:
+  INLINE DXGeomMunger9(GraphicsStateGuardian *gsg, const RenderState *state);
+
+protected:
+  virtual CPT(GeomVertexFormat) munge_format_impl(const GeomVertexFormat *orig,
+                                                    const GeomVertexAnimationSpec &animation);
+
+  virtual int compare_to_impl(const GeomMunger *other) const;
+  virtual int geom_compare_to_impl(const GeomMunger *other) const;
+
+public:
+  INLINE void *operator new(size_t size);
+
+private:
+  CPT(TextureAttrib) _texture;
+  CPT(TexGenAttrib) _tex_gen;
+
+  static GeomMunger *_deleted_chain;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    StandardMunger::init_type();
+    register_type(_type_handle, "DXGeomMunger9",
+                  StandardMunger::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "dxGeomMunger9.I"
+
+#endif
+

+ 4 - 5
panda/src/dxgsg9/dxGraphicsDevice9.cxx

@@ -1,10 +1,10 @@
 // Filename: dxGraphicsDevice.cxx
-// Created by:   masad (02Jan04)
+// Created by:  masad (22Jul03)
 //
 ////////////////////////////////////////////////////////////////////
 //
 // PANDA 3D SOFTWARE
-// Copyright (c) 2004, Disney Enterprises, Inc.  All rights reserved
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
 //
 // All use of this software is subject to the terms of the Panda 3d
 // Software license.  You should have received a copy of this license
@@ -30,8 +30,8 @@ DXGraphicsDevice9(wdxGraphicsPipe9 *pipe) :
   GraphicsDevice(pipe) {
 
   ZeroMemory(&_Scrn,sizeof(_Scrn));
-  _pD3DDevice = NULL;
-  _pSwapChain = NULL;
+  _d3d_device = NULL;
+  _swap_chain = NULL;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -43,4 +43,3 @@ DXGraphicsDevice9::
 ~DXGraphicsDevice9() {
 
 }
-

+ 5 - 6
panda/src/dxgsg9/dxGraphicsDevice9.h

@@ -1,10 +1,10 @@
 // Filename: dxGraphicsDevice.h
-// Created by:  masad (02Jan04)
+// Created by:  masad (22Jul03)
 //
 ////////////////////////////////////////////////////////////////////
 //
 // PANDA 3D SOFTWARE
-// Copyright (c) 2004, Disney Enterprises, Inc.  All rights reserved
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
 //
 // All use of this software is subject to the terms of the Panda 3d
 // Software license.  You should have received a copy of this license
@@ -29,7 +29,7 @@
 ////////////////////////////////////////////////////////////////////
 //   Class : DXGraphicsDevice9
 // Description : A GraphicsDevice necessary for multi-window rendering
-//               in DX. 
+//               in DX.
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDADX DXGraphicsDevice9 : public GraphicsDevice {
   friend class wdxGraphicsPipe9;
@@ -39,8 +39,8 @@ public:
   ~DXGraphicsDevice9();
 
   DXScreenData _Scrn;
-  LPDIRECT3DDEVICE9 _pD3DDevice;  // same as pScrn->_pD3DDevice, cached for spd
-  IDirect3DSwapChain9 *_pSwapChain;
+  LPDIRECT3DDEVICE9 _d3d_device;  // same as Scrn._d3d_device, cached for spd
+  IDirect3DSwapChain9 *_swap_chain;
 
 #if 0
 protected:
@@ -52,4 +52,3 @@ protected:
 };
 
 #endif
-

+ 68 - 498
panda/src/dxgsg9/dxGraphicsStateGuardian9.I

@@ -1,10 +1,10 @@
-// Filename: dxGraphicsStateGuardian8.I
-// Created by:   masad (02Jan04)
+// Filename: dxGraphicsStateGuardian9.I
+// Created by:  mike (02Feb99)
 //
 ////////////////////////////////////////////////////////////////////
 //
 // PANDA 3D SOFTWARE
-// Copyright (c) 2004, Disney Enterprises, Inc.  All rights reserved
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
 //
 // All use of this software is subject to the terms of the Panda 3d
 // Software license.  You should have received a copy of this license
@@ -16,481 +16,97 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-INLINE DWORD
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXGraphicsStateGuardian9::Colorf_to_D3DCOLOR
+//       Access: Public, Static
+//  Description: Converts Panda's floating-point Colorf structure to
+//               DirectX's D3DCOLOR packed structure.
+////////////////////////////////////////////////////////////////////
+INLINE DWORD DXGraphicsStateGuardian9::
 Colorf_to_D3DCOLOR(const Colorf &cColorf) {
 // MS VC defines _M_IX86 for x86.  gcc should define _X86_
 #if defined(_M_IX86) || defined(_X86_)
-    DWORD d3dcolor,tempcolorval=255;
-
-    // note the default FPU rounding mode will give 255*0.5f=0x80, not 0x7F as VC would force it to by resetting rounding mode
-    // dont think this makes much difference
+  DWORD d3dcolor, tempcolorval=255;
 
-    __asm {
+  // note the default FPU rounding mode will give 255*0.5f=0x80, not 0x7F as VC would force it to by resetting rounding mode
+  // dont think this makes much difference
+  
+  __asm {
         push ebx   ; want to save this in case this fn is inlined
         push ecx
         mov ecx, cColorf
         fild tempcolorval
         fld DWORD PTR [ecx]
-        fmul ST(0),ST(1)
+        fmul ST(0), ST(1)
         fistp tempcolorval  ; no way to store directly to int register
         mov eax, tempcolorval
         shl eax, 16
 
         fld DWORD PTR [ecx+4]  ;grn
-        fmul ST(0),ST(1)
+        fmul ST(0), ST(1)
         fistp tempcolorval
-        mov ebx,tempcolorval
+        mov ebx, tempcolorval
         shl ebx, 8
-        or eax,ebx
+        or eax, ebx
 
         fld DWORD PTR [ecx+8]  ;blue
-        fmul ST(0),ST(1)
+        fmul ST(0), ST(1)
         fistp tempcolorval
-        or eax,tempcolorval
+        or eax, tempcolorval
 
         fld DWORD PTR [ecx+12] ;alpha
-        fmul ST(0),ST(1)
+        fmul ST(0), ST(1)
         fistp tempcolorval
         ; simulate pop 255.0 off FP stack w/o store, mark top as empty and increment stk ptr
         ffree ST(0)
         fincstp
-        mov ebx,tempcolorval
+        mov ebx, tempcolorval
         shl ebx, 24
-        or eax,ebx
-        mov d3dcolor,eax
+        or eax, ebx
+        mov d3dcolor, eax
         pop ecx
         pop ebx
-    }
+  }
 
-   //   dxgsg9_cat.debug() << (void*)d3dcolor << endl;
-   return d3dcolor;
+  //   dxgsg9_cat.debug() << (void*)d3dcolor << endl;
+  return d3dcolor;
 #else //!_X86_
-   return MY_D3DRGBA(cColorf[0], cColorf[1], cColorf[2], cColorf[3]);
+  return MY_D3DRGBA(cColorf[0], cColorf[1], cColorf[2], cColorf[3]);
 #endif //!_X86_
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::enable_line_smooth
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-enable_line_smooth(bool val) {
-  if(_line_smooth_enabled != val) {
-    _line_smooth_enabled = val;
-  #ifndef NDEBUG
-    {
-        if(val && (_pScrn->d3dcaps.LineCaps & D3DLINECAPS_ANTIALIAS))
-           dxgsg9_cat.error() << "no HW support for line smoothing!!\n";
-    }
-  #endif
-
-    _pD3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, (DWORD)val);
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::enable_dither
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-enable_dither(bool val) {
-  if (_dither_enabled != val) {
-    _dither_enabled = val;
-
-  #ifndef NDEBUG
-    {
-        if(val && !(_pScrn->d3dcaps.RasterCaps & D3DPRASTERCAPS_DITHER))
-           dxgsg9_cat.error() << "no HW support for color dithering!!\n";
-    }
-  #endif
-
-    _pD3DDevice->SetRenderState(D3DRS_DITHERENABLE, (DWORD)val);
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::enable_stencil_test
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-enable_stencil_test(bool val) {
-  if (_stencil_test_enabled != val) {
-    _stencil_test_enabled = val;
-    _pD3DDevice->SetRenderState(D3DRS_STENCILENABLE, (DWORD)val);
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::enable_color_material
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-enable_color_material(bool val) {
-  if (_color_material_enabled != val) {
-    _color_material_enabled = val;
-  }
-}
-
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::enable_blend
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-enable_blend(bool val) {
-  if (_blend_enabled != val) {
-    _blend_enabled = val;
-    _pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, (DWORD)val);
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::set_color_writemask
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-set_color_writemask(UINT color_writemask) {
-  if (_color_writemask != color_writemask) {
-    _color_writemask = color_writemask;
-    if(_pScrn->bCanDirectDisableColorWrites) {
-        // only newer HW supports this rstate
-        _pD3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, (DWORD)color_writemask);
-    } else {
-        // blending can only handle on/off
-        assert((color_writemask==0x0)||(color_writemask==0xFFFFFFFF));
-        set_blend_mode();
-    }
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::enable_blend
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-enable_gouraud_shading(bool val) {
-  if (_bGouraudShadingOn != val) {
-    _bGouraudShadingOn = val;
-    _pD3DDevice->SetRenderState(D3DRS_SHADEMODE, (val ? D3DSHADE_GOURAUD : D3DSHADE_FLAT));
-  }
-}
-
-INLINE void DXGraphicsStateGuardian9::
-enable_primitive_clipping(bool val) {
-  if (_clipping_enabled != val) {
-    _clipping_enabled = val;
-    _pD3DDevice->SetRenderState(D3DRS_CLIPPING, (DWORD)val);
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::enable_fog
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-enable_fog(bool val) {
-  if ((_fog_enabled != val) && (_doFogType!=None)) {
-    _fog_enabled = val;
-    _pD3DDevice->SetRenderState(D3DRS_FOGENABLE, (DWORD)val);
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::set_vertex_format
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-set_vertex_format(DWORD NewFvfType) {
-#ifdef USE_VERTEX_SHADERS
-  if(_CurVertexShader!=NULL) {
-    // this needs optimization
-    HRESULT hr = _pD3DDevice->SetVertexShader(_CurVertexShader);
-    #ifndef NDEBUG
-    if(FAILED(hr)) {
-           dxgsg9_cat.error() << "SetVertexShader for custom vtx shader failed" << D3DERRORSTRING(hr);
-           exit(1);
-    }
-    #endif
-    _CurFVFType = NewFvfType;    
-    return;
-  }
-#endif
-
-  if (_CurFVFType != NewFvfType) {
-    _CurFVFType = NewFvfType;
-
- HRESULT hr = _pD3DDevice->SetVertexShader(NULL);
- hr = _pD3DDevice->SetFVF(NewFvfType);
-
- //    HRESULT hr = _pD3DDevice->SetVertexShader((IDirect3DVertexShader9*)NewFvfType);
- #ifndef NDEBUG
-    if(FAILED(hr)) {
-           dxgsg9_cat.error() << "SetVertexShader(0x" << (void*)NewFvfType<<") failed" << D3DERRORSTRING(hr);
-           exit(1);
-    }
- #endif
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::enable_alpha_test
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-enable_alpha_test(bool val )
-{
-  if (_alpha_test_enabled != val) {
-    _alpha_test_enabled = val;
-    _pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, (DWORD)val);
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::call_dxLightModelAmbient
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-call_dxLightModelAmbient( const Colorf& color)
-{
-  if (_lmodel_ambient != color) {
-    _lmodel_ambient = color;
-#ifdef GSG_VERBOSE
-    dxgsg9_cat.debug() << "dxLightModel(LIGHT_MODEL_AMBIENT, " << color << ")" << endl;
-#endif
-    _pD3DDevice->SetRenderState( D3DRS_AMBIENT,
-                D3DCOLOR_COLORVALUE(color[0], color[1], color[2], color[3]));
-  }
-}
-
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::call_dxAlphaFunc
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-call_dxAlphaFunc(D3DCMPFUNC func, float reference_alpha) {
-  if (_alpha_func != func) {
-    _alpha_func = func;
-#ifdef GSG_VERBOSE
-    dxgsg9_cat.debug() << "dxAlphaFunc(";
-    switch (func) {
-    case D3DCMP_NEVER:
-      dxgsg9_cat.debug(false) << "D3DCMP_NEVER";
-      break;
-    case D3DCMP_LESS:
-      dxgsg9_cat.debug(false) << "D3DCMP_LESS";
-      break;
-    case D3DCMP_EQUAL:
-      dxgsg9_cat.debug(false) << "D3DCMP_EQUAL";
-      break;
-#ifdef D3DCMP_LEQUAL
-    case D3DCMP_LEQUAL:
-      dxgsg9_cat.debug(false) << "D3DCMP_LEQUAL";
-      break;
-#endif
-    case D3DCMP_GREATER:
-      dxgsg9_cat.debug(false) << "D3DCMP_GREATER";
-      break;
-    case D3DCMP_NOTEQUAL:
-      dxgsg9_cat.debug(false) << "D3DCMP_NOTEQUAL";
-      break;
-#ifdef D3DCMP_GEQUAL
-    case D3DCMP_GEQUAL:
-      dxgsg9_cat.debug(false) << "D3DCMP_GEQUAL";
-      break;
-#endif
-    case D3DCMP_ALWAYS:
-      dxgsg9_cat.debug(false) << "D3DCMP_ALWAYS";
-      break;
-    }
-    dxgsg9_cat.debug() << " , " << reference_alpha << ")" << endl;
-#endif
-    _pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC, func);
-  }
-
-  if(_alpha_func_refval != reference_alpha) {
-      _alpha_func_refval = reference_alpha;
-      _pD3DDevice->SetRenderState(D3DRS_ALPHAREF, (UINT) (reference_alpha*255.0f));  //d3d uses 0x0-0xFF, not a float
-  }
-}
-
-
-INLINE void DXGraphicsStateGuardian9::
-call_dxBlendFunc(D3DBLEND sfunc, D3DBLEND dfunc )
-{
-  if (_blend_source_func != sfunc)
-    {
-    _blend_source_func = sfunc;
-    _pD3DDevice->SetRenderState(D3DRS_SRCBLEND, sfunc);
-#ifdef GSG_VERBOSE
-    dxgsg9_cat.debug() << "dxSrcBlendFunc(";
-    switch (sfunc)
-        {
-        case D3DBLEND_ZERO:
-          dxgsg9_cat.debug(false) << "ZERO, ";
-          break;
-        case D3DBLEND_ONE:
-          dxgsg9_cat.debug(false) << "ONE, ";
-          break;
-        case D3DBLEND_DESTCOLOR:
-          dxgsg9_cat.debug(false) << "DESTCOLOR, ";
-          break;
-        case D3DBLEND_INVDESTCOLOR:
-          dxgsg9_cat.debug(false) << "INVDESTCOLOR, ";
-          break;
-        case D3DBLEND_SRCALPHA:
-          dxgsg9_cat.debug(false) << "SRCALPHA, ";
-          break;
-        case D3DBLEND_INVSRCALPHA:
-          dxgsg9_cat.debug(false) << "INVSRCALPHA, ";
-          break;
-        case D3DBLEND_DESTALPHA:
-          dxgsg9_cat.debug(false) << "DESTALPHA, ";
-          break;
-        case D3DBLEND_INVDESTALPHA:
-          dxgsg9_cat.debug(false) << "INVDESTALPHA, ";
-          break;
-        case D3DBLEND_SRCALPHASAT:
-          dxgsg9_cat.debug(false) << "SRCALPHASAT, ";
-          break;
-        default:
-          dxgsg9_cat.debug(false) << "unknown, ";
-          break;
-        }
-    dxgsg9_cat.debug(false) << endl;
-#endif
-    }
-  if ( _blend_dest_func != dfunc)
-    {
-    _blend_dest_func = dfunc;
-    _pD3DDevice->SetRenderState(D3DRS_DESTBLEND, dfunc);
-#ifdef GSG_VERBOSE
-    dxgsg9_cat.debug() << "dxDstBlendFunc(";
-    switch (dfunc)
-        {
-        case D3DBLEND_ZERO:
-          dxgsg9_cat.debug(false) << "ZERO, ";
-          break;
-        case D3DBLEND_ONE:
-          dxgsg9_cat.debug(false) << "ONE, ";
-          break;
-        case D3DBLEND_DESTCOLOR:
-          dxgsg9_cat.debug(false) << "DESTCOLOR, ";
-          break;
-        case D3DBLEND_INVDESTCOLOR:
-          dxgsg9_cat.debug(false) << "INVDESTCOLOR, ";
-          break;
-        case D3DBLEND_SRCALPHA:
-          dxgsg9_cat.debug(false) << "SRCALPHA, ";
-          break;
-        case D3DBLEND_INVSRCALPHA:
-          dxgsg9_cat.debug(false) << "INVSRCALPHA, ";
-          break;
-        case D3DBLEND_DESTALPHA:
-          dxgsg9_cat.debug(false) << "DESTALPHA, ";
-          break;
-        case D3DBLEND_INVDESTALPHA:
-          dxgsg9_cat.debug(false) << "INVDESTALPHA, ";
-          break;
-        case D3DBLEND_SRCALPHASAT:
-          dxgsg9_cat.debug(false) << "SRCALPHASAT, ";
-          break;
-        }
-    dxgsg9_cat.debug(false) << endl;
-#endif
-    }
-}
-
-INLINE void DXGraphicsStateGuardian9::
-enable_zwritemask(bool val) {
-    if (_depth_write_enabled != val) {
-        _depth_write_enabled = val;
-        _pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, val);
-    }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::add_to_FVFBuf
-//       Access: Private
-//  Description: This adds data to the flexible vertex format
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-add_to_FVFBuf(void *data,  size_t bytes) {
-    memcpy(_pCurFvfBufPtr, data, bytes);
-    _pCurFvfBufPtr += bytes;
-}
-
-INLINE void DXGraphicsStateGuardian9::
-transform_color(Colorf &InColor,D3DCOLOR &OutRGBAColor) {
-  Colorf transformed
-    (InColor[0] * _current_color_scale[0],
-     InColor[1] * _current_color_scale[1],
-     InColor[2] * _current_color_scale[2],
-     InColor[3] * _current_color_scale[3]);
-  OutRGBAColor = Colorf_to_D3DCOLOR(transformed);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::enable_texturing
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-enable_texturing(bool val) {
-  _texturing_enabled = val;
-  
-  if (!val) {
-    _pD3DDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_DISABLE);
-
-  } else {
-    nassertv(_pCurTexContext!=NULL);
-    SetTextureBlendMode(_CurTexBlendMode,true);
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::wants_texcoords
-//       Access: Public, Virtual
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE bool DXGraphicsStateGuardian9::
-wants_texcoords() const {
-    return _texturing_enabled;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian9::get_texture_wrap_mode
-//       Access: Protected
+//       Access: Protected, Static
 //  Description: Maps from the Texture's internal wrap mode symbols to
 //               GL's.
 ////////////////////////////////////////////////////////////////////
 INLINE D3DTEXTUREADDRESS DXGraphicsStateGuardian9::
-get_texture_wrap_mode(Texture::WrapMode wm) const {
-  static D3DTEXTUREADDRESS PandaTexWrapMode_to_D3DTexWrapMode[Texture::WM_invalid] = {
-    D3DTADDRESS_CLAMP,D3DTADDRESS_WRAP,D3DTADDRESS_MIRROR,D3DTADDRESS_MIRRORONCE,D3DTADDRESS_BORDER};
-
-    return PandaTexWrapMode_to_D3DTexWrapMode[wm];
+get_texture_wrap_mode(Texture::WrapMode wm) {
+  switch (wm) {
+  case Texture::WM_clamp:
+    return D3DTADDRESS_CLAMP;
+  case Texture::WM_repeat:
+    return D3DTADDRESS_WRAP;
+  case Texture::WM_mirror:
+    return D3DTADDRESS_MIRROR;
+  case Texture::WM_mirror_once:
+    return D3DTADDRESS_MIRRORONCE;
+  case Texture::WM_border_color:
+    return D3DTADDRESS_BORDER;
+  }
+  dxgsg9_cat.error() << "Invalid Texture::Mode value" << endl;
+  return D3DTADDRESS_WRAP;
 }
 
 ////////////////////////////////////////////////////////////////////
 //     Function: DXGraphicsStateGuardian9::get_fog_mode_type
-//       Access: Protected
+//       Access: Protected, Static
 //  Description: Maps from the fog types to gl version
 ////////////////////////////////////////////////////////////////////
 INLINE D3DFOGMODE DXGraphicsStateGuardian9::
-get_fog_mode_type(Fog::Mode m) const {
+get_fog_mode_type(Fog::Mode m) {
   switch (m) {
   case Fog::M_linear:
     return D3DFOG_LINEAR;
@@ -504,78 +120,32 @@ get_fog_mode_type(Fog::Mode m) const {
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::enable_clip_plane
-//       Access: Protected, Virtual
-//  Description: Intended to be overridden by a derived class to
-//               enable the indicated clip_plane id.  A specific
-//               PlaneNode will already have been bound to this id via
-//               bind_clip_plane().
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-enable_clip_plane(int plane_id, bool enable) {
-  assert(plane_id < D3DMAXUSERCLIPPLANES);
-
-  DWORD bitflag = ((DWORD)1 << plane_id);
-  if (enable) {
-    _clip_plane_bits |= bitflag;
-  } else {
-    _clip_plane_bits &= ~bitflag;
-  }
-
-  _pD3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, _clip_plane_bits);
-}
-
-/**  unimplemented
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::enable_multisample
-//       Access:
-//  Description:
+//     Function: DXGraphicsStateGuardian9::get_tex_mat_sym
+//       Access: Protected, Static
+//  Description: Returns the nth D3DTS_TEXTURE(n) constant.
 ////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-enable_multisample(bool val) {
-  _multisample_enabled = val;
-  #ifdef NDEBUG
-    dxgsg9_cat.error() << "dx multisample unimplemented!!\n";
-  #endif
+INLINE D3DTRANSFORMSTATETYPE DXGraphicsStateGuardian9::
+get_tex_mat_sym(int stage_index) {
+  return (D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0 + stage_index);
 }
 
 ////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::enable_multisample_alpha_one
-//       Access:
-//  Description:
+//     Function: DXGraphicsStateGuardian9::get_safe_buffer_start
+//       Access: Protected, Static
+//  Description: Returns the address of a 64K buffer that is allocated
+//               at the beginning of a 64K block.
 ////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-enable_multisample_alpha_one(bool val) {
-  if (_multisample_alpha_one_enabled != val) {
-    _multisample_alpha_one_enabled = val;
+INLINE unsigned char *DXGraphicsStateGuardian9::
+get_safe_buffer_start() {
+  if (_temp_buffer == NULL) {
+    // Guarantee we get a buffer of size 0x10000 bytes that begins
+    // on an even multiple of 0x10000.  We do this by allocating
+    // double the required buffer, and then pointing to the first
+    // multiple of 0x10000 within that buffer.
+    _temp_buffer = new unsigned char[0x1ffff];
+    _safe_buffer_start = (unsigned char *)(((long)_temp_buffer + 0xffff) & ~0xffff);
   }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::enable_multisample_alpha_mask
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-enable_multisample_alpha_mask(bool val) {
-  if (_multisample_alpha_mask_enabled != val) {
-    _multisample_alpha_mask_enabled = val;
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: DXGraphicsStateGuardian9::enable_point_smooth
-//       Access:
-//  Description:
-////////////////////////////////////////////////////////////////////
-INLINE void DXGraphicsStateGuardian9::
-enable_point_smooth(bool val) {
-  // _point_smooth_enabled = val;
 
-  #ifdef NDEBUG
-    dxgsg9_cat.error() << "dx point smoothing unimplemented!!\n";
-  #endif
+  return _safe_buffer_start;
 }
-*/
 

File diff ditekan karena terlalu besar
+ 416 - 453
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx


+ 157 - 250
panda/src/dxgsg9/dxGraphicsStateGuardian9.h

@@ -1,10 +1,10 @@
-// Filename: dxGraphicsStateGuardian.h
-// Created by:   masad (02Jan04)
+// Filename: dxGraphicsStateGuardian9.h
+// Created by:  mike (02Feb99)
 //
 ////////////////////////////////////////////////////////////////////
 //
 // PANDA 3D SOFTWARE
-// Copyright (c) 2004, Disney Enterprises, Inc.  All rights reserved
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
 //
 // All use of this software is subject to the terms of the Panda 3d
 // Software license.  You should have received a copy of this license
@@ -16,343 +16,250 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#ifndef DXGRAPHICSSTATEGUARDIAN_H
-#define DXGRAPHICSSTATEGUARDIAN_H
-
-//#define GSG_VERBOSE 1
+#ifndef DXGRAPHICSSTATEGUARDIAN9_H
+#define DXGRAPHICSSTATEGUARDIAN9_H
 
 #include "dxgsg9base.h"
 #include "dxTextureContext9.h"
-#include "d3dfont9.h"
 #include "config_dxgsg9.h"
 
 #include "graphicsStateGuardian.h"
-#include "geomprimitives.h"
 #include "texture.h"
-#include "texGenAttrib.h"
 #include "displayRegion.h"
 #include "material.h"
 #include "depthTestAttrib.h"
+#include "cullFaceAttrib.h"
 #include "renderModeAttrib.h"
 #include "fog.h"
 #include "pointerToArray.h"
 
 class Light;
 
-//#if defined(NOTIFY_DEBUG) || defined(DO_PSTATS)
-//#ifdef _DEBUG
-// is there something in DX9 to replace this?
-#if 0
-// This function now serves both to print a debug message to the
-// console, as well as to notify PStats about the change in texture
-// memory.  Thus, we compile it in if we are building with support for
-// either notify debug messages or PStats; otherwise, we compile it
-// out.
-extern void dbgPrintVidMem(LPDIRECTDRAW7 pDD, LPDDSCAPS2 lpddsCaps,const char *pMsg);
-#define PRINTVIDMEM(pDD,pCaps,pMsg) dbgPrintVidMem(pDD,pCaps,pMsg)
-#else
-#define PRINTVIDMEM(pDD,pCaps,pMsg)
-#endif
+class DXVertexBufferContext9;
+class DXIndexBufferContext9;
 
 ////////////////////////////////////////////////////////////////////
-//   Class : DXGraphicsStateGuardian9
-// Description : A GraphicsStateGuardian specialized for rendering
-//               into DX.  There should be no DX calls
-//               outside of this object.
+//       Class : DXGraphicsStateGuardian9
+// Description : A GraphicsStateGuardian for rendering into DirectX9
+//               contexts.
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDADX DXGraphicsStateGuardian9 : public GraphicsStateGuardian {
-  friend class wdxGraphicsWindow9;
-  friend class wdxGraphicsPipe9;
-  friend class wdxGraphicsWindowGroup9;
-  friend class DXTextureContext9;
-
 public:
   DXGraphicsStateGuardian9(const FrameBufferProperties &properties);
   ~DXGraphicsStateGuardian9();
 
-  virtual void reset();
+  virtual TextureContext *prepare_texture(Texture *tex);
+  void apply_texture(int i, TextureContext *tc);
+  virtual void release_texture(TextureContext *tc);
+
+  virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data);
+  void apply_vertex_buffer(VertexBufferContext *vbc);
+  virtual void release_vertex_buffer(VertexBufferContext *vbc);
+
+  virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data);
+  void apply_index_buffer(IndexBufferContext *ibc);
+  virtual void release_index_buffer(IndexBufferContext *ibc);
+
+  virtual PT(GeomMunger) make_geom_munger(const RenderState *state);
+
+  virtual void set_color_clear_value(const Colorf &value);
 
   virtual void do_clear(const RenderBuffer &buffer);
 
   virtual void prepare_display_region();
   virtual bool prepare_lens();
 
-  virtual void draw_point(GeomPoint *geom, GeomContext *gc);
-  virtual void draw_line(GeomLine *geom, GeomContext *gc);
-  virtual void draw_linestrip(GeomLinestrip *geom, GeomContext *gc);
-  void draw_linestrip_base(Geom *geom, GeomContext *gc, bool bConnectEnds);
-  virtual void draw_sprite(GeomSprite *geom, GeomContext *gc);
-  virtual void draw_polygon(GeomPolygon *geom, GeomContext *gc);
-  virtual void draw_quad(GeomQuad *geom, GeomContext *gc);
-  virtual void draw_tri(GeomTri *geom, GeomContext *gc);
-  virtual void draw_tristrip(GeomTristrip *geom, GeomContext *gc);
-  virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc);
-  virtual void draw_sphere(GeomSphere *geom, GeomContext *gc);
+  virtual bool begin_frame();
+  virtual bool begin_scene();
+  virtual void end_scene();
+  virtual void end_frame();
 
-  virtual TextureContext *prepare_texture(Texture *tex);
-  void apply_texture(TextureContext *tc, int index);
-  virtual void release_texture(TextureContext *tc);
+  virtual bool begin_draw_primitives(const Geom *geom,
+                                     const GeomMunger *munger,
+                                     const GeomVertexData *vertex_data);
+  virtual void draw_triangles(const GeomTriangles *primitive);
+  virtual void draw_tristrips(const GeomTristrips *primitive);
+  virtual void draw_trifans(const GeomTrifans *primitive);
+  virtual void draw_lines(const GeomLines *primitive);
+  virtual void draw_linestrips(const GeomLinestrips *primitive);
+  virtual void draw_points(const GeomPoints *primitive);
+  virtual void end_draw_primitives();
 
   virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
                                            const RenderBuffer &rb);
   virtual bool framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
                                        const RenderBuffer &rb);
 
-  virtual void apply_material(const Material *material);
+  virtual void reset();
+
   virtual void apply_fog(Fog *fog);
 
-  virtual void issue_transform(const TransformState *transform);
-  virtual void issue_tex_matrix(const TexMatrixAttrib *attrib);
-  virtual void issue_tex_gen(const TexGenAttrib *attrib);
-  virtual void issue_texture(const TextureAttrib *attrib);
-  virtual void issue_material(const MaterialAttrib *attrib);
-  virtual void issue_render_mode(const RenderModeAttrib *attrib);
-  virtual void issue_rescale_normal(const RescaleNormalAttrib *attrib);
-  virtual void issue_alpha_test(const AlphaTestAttrib *attrib);
-  virtual void issue_depth_test(const DepthTestAttrib *attrib);
-  virtual void issue_depth_write(const DepthWriteAttrib *attrib);
-  virtual void issue_color_write(const ColorWriteAttrib *attrib);
-  virtual void issue_cull_face(const CullFaceAttrib *attrib);
-  virtual void issue_fog(const FogAttrib *attrib);
-  virtual void issue_depth_offset(const DepthOffsetAttrib *attrib);
-
-  virtual void bind_light(PointLight *light_obj, const NodePath &light, 
+  virtual void bind_light(PointLight *light_obj, const NodePath &light,
                           int light_id);
-  virtual void bind_light(DirectionalLight *light_obj, const NodePath &light, 
+  virtual void bind_light(DirectionalLight *light_obj, const NodePath &light,
                           int light_id);
-  virtual void bind_light(Spotlight *light_obj, const NodePath &light, 
+  virtual void bind_light(Spotlight *light_obj, const NodePath &light,
                           int light_id);
 
-  virtual bool begin_frame();
-  virtual bool begin_scene();
-  virtual void end_scene();
-  virtual void end_frame();
-
-  virtual bool wants_texcoords() const;
-
-  virtual void set_color_clear_value(const Colorf& value);
+  static D3DFORMAT get_index_type(Geom::NumericType numeric_type);
+  INLINE static DWORD Colorf_to_D3DCOLOR(const Colorf &cColorf);
 
-public:
-  // recreate_tex_callback needs these to be public
-  DXScreenData *_pScrn;
-  LPDIRECT3DDEVICE9 _pD3DDevice;  // same as pScrn->_pD3DDevice, cached for spd
-  IDirect3DSwapChain9 *_pSwapChain;
-  D3DPRESENT_PARAMETERS _PresReset;  // This is built during reset device
+  virtual void set_state_and_transform(const RenderState *state,
+                                       const TransformState *transform);
 
 protected:
+  void do_issue_transform();
+  void do_issue_alpha_test();
+  void do_issue_render_mode();
+  void do_issue_rescale_normal();
+  void do_issue_color_write();
+  void do_issue_depth_test();
+  void do_issue_depth_write();
+  void do_issue_cull_face();
+  void do_issue_fog();
+  void do_issue_depth_offset();
+  void do_issue_tex_gen();
+  void do_issue_shade_model();
+  void do_issue_material();
+  void do_issue_texture();
+  void do_issue_blending();
+
   virtual void enable_lighting(bool enable);
   virtual void set_ambient_light(const Colorf &color);
   virtual void enable_light(int light_id, bool enable);
 
-  virtual bool slot_new_clip_plane(int plane_id);
   virtual void enable_clip_plane(int plane_id, bool enable);
   virtual void bind_clip_plane(const NodePath &plane, int plane_id);
 
-  virtual void set_blend_mode();
-
-  void free_nondx_resources();            // free local internal buffers
+  void free_nondx_resources();
   void free_d3d_device();
 
   void set_draw_buffer(const RenderBuffer &rb);
   void set_read_buffer(const RenderBuffer &rb);
 
-  INLINE void add_to_FVFBuf(void *data,  size_t bytes) ;
-
   void do_auto_rescale_normal();
 
-  bool                  _bDXisReady;
-  HRESULT               _last_testcooplevel_result;
-  DXTextureContext9  *_pCurTexContext;
-
-  bool              _bTransformIssued;  // decaling needs to tell when a transform has been issued
-  D3DMATRIX         _SavedTransform;
-
-  RenderBuffer::Type _cur_read_pixel_buffer;  // source for copy_pixel_buffer operation
-  bool _auto_rescale_normal;
+protected:
+  INLINE static D3DTEXTUREADDRESS get_texture_wrap_mode(Texture::WrapMode wm);
+  INLINE static D3DFOGMODE get_fog_mode_type(Fog::Mode m);
+  const D3DCOLORVALUE &get_light_color(Light *light) const;
+  INLINE static D3DTRANSFORMSTATETYPE get_tex_mat_sym(int stage_index);
 
-  void GenerateSphere(void *pVertexSpace,DWORD dwVertSpaceByteSize,
-                    void *pIndexSpace,DWORD dwIndexSpaceByteSize,
-                    D3DXVECTOR3 *pCenter, float fRadius,
-                    DWORD wNumRings, DWORD wNumSections, float sx, float sy, float sz,
-                    DWORD *pNumVertices,DWORD *pNumTris,DWORD fvfFlags,DWORD dwVertSize);
-  HRESULT ReleaseAllDeviceObjects();
-  HRESULT RecreateAllDeviceObjects();
-  HRESULT DeleteAllDeviceObjects();
-
-/*
-  INLINE void enable_multisample_alpha_one(bool val);
-  INLINE void enable_multisample_alpha_mask(bool val);
-  INLINE void enable_multisample(bool val);
-*/
-
-  INLINE void enable_color_material(bool val);
-  INLINE void enable_fog(bool val);
-  INLINE void enable_zwritemask(bool val);
-  INLINE void set_color_writemask(UINT color_writemask);
-  INLINE void enable_gouraud_shading(bool val);
-  INLINE void set_vertex_format(DWORD NewFvfType);
-
-  INLINE D3DTEXTUREADDRESS get_texture_wrap_mode(Texture::WrapMode wm) const;
-  INLINE D3DFOGMODE get_fog_mode_type(Fog::Mode m) const;
-
-  INLINE void enable_primitive_clipping(bool val);
-  INLINE void enable_alpha_test(bool val);
-  INLINE void enable_line_smooth(bool val);
-  INLINE void enable_blend(bool val);
-  INLINE void enable_point_smooth(bool val);
-  INLINE void enable_texturing(bool val);
-  INLINE void call_dxLightModelAmbient(const Colorf& color);
-  INLINE void call_dxAlphaFunc(D3DCMPFUNC func, float refval);
-  INLINE void call_dxBlendFunc(D3DBLEND sfunc, D3DBLEND dfunc);
   static D3DBLEND get_blend_func(ColorBlendAttrib::Operand operand);
-  INLINE void enable_dither(bool val);
-  INLINE void enable_stencil_test(bool val);
   void report_texmgr_stats();
-  void draw_multitri(Geom *geom, D3DPRIMITIVETYPE tri_id);
-
-  void draw_prim_inner_loop(int nVerts, const Geom *geom, ushort perFlags);
-  void draw_prim_inner_loop_coordtexonly(int nVerts, const Geom *geom);
-  size_t draw_prim_setup(const Geom *geom) ;
-
-  //   for drawing primitives
-  Normalf   p_normal;  // still used to hold G_OVERALL, G_PER_PRIM values
-  TexCoordf p_texcoord;
-  D3DCOLOR  _curD3Dcolor;
-  DWORD     _perPrim,_perVertex,_perComp;   //  these hold DrawLoopFlags bitmask values
-  DWORD     _CurFVFType;
-  // for storage of the flexible vertex format
-  BYTE *_pCurFvfBufPtr,*_pFvfBufBasePtr;
-  WORD *_index_buf;  // base of malloced array
-
-  D3DCOLOR _scene_graph_color_D3DCOLOR;
-  D3DCOLOR _d3dcolor_clear_value;
-//  D3DSHADEMODE _CurShadeMode;
-  bool _bGouraudShadingOn;
-  UINT _color_writemask;
-  bool _bDrawPrimDoSetupVertexBuffer;       // if true, draw methods just copy vertex data into pCurrentGeomContext
 
-  // iterators for primitives
-  Geom::VertexIterator vi;
-  Geom::NormalIterator ni;
-  Geom::TexCoordIterator ti;
-  Geom::ColorIterator ci;
+  void set_context(DXScreenData *new_context);
+  void set_render_target();
+
+  void set_texture_blend_mode(int i, const TextureStage *stage);
+
+  void dx_cleanup();
+  HRESULT reset_d3d_device(D3DPRESENT_PARAMETERS *p_presentation_params,
+                           DXScreenData **screen = NULL);
+
+  bool check_cooperative_level();
+
+  void show_frame();
+
+  bool create_swap_chain (DXScreenData *new_context);
+  bool release_swap_chain (DXScreenData *new_context);
+  void copy_pres_reset(DXScreenData *new_context);
+
+  static D3DTEXTUREFILTERTYPE get_d3d_min_type(Texture::FilterType filter_type);
+  static D3DTEXTUREFILTERTYPE get_d3d_mip_type(Texture::FilterType filter_type);
+  static D3DTEXTUREOP get_texture_operation(TextureStage::CombineMode mode, int scale);
+  static DWORD get_texture_argument(TextureStage::CombineSource source,
+                                    TextureStage::CombineOperand operand);
+  static DWORD get_texture_argument_modifier(TextureStage::CombineOperand operand);
 
-  // these are used for fastpaths that bypass the iterators above
-  // pointers to arrays in current geom, used to traverse indexed and non-indexed arrays
-  Vertexf *_coord_array,*_pCurCoord;
-  ushort *_coordindex_array,*_pCurCoordIndex;
+  void draw_primitive_up(D3DPRIMITIVETYPE primitive_type,
+       unsigned int primitive_count,
+       unsigned int first_vertex,
+       unsigned int num_vertices,
+       const unsigned char *buffer, size_t stride);
+  void draw_indexed_primitive_up(D3DPRIMITIVETYPE primitive_type,
+         unsigned int min_index, unsigned int max_index,
+         unsigned int num_primitives,
+         const unsigned char *index_data,
+         D3DFORMAT index_type,
+         const unsigned char *buffer, size_t stride);
 
-  TexCoordf *_texcoord_array,*_pCurTexCoord;
-  ushort *_texcoordindex_array,*_pCurTexCoordIndex;
+  INLINE static unsigned char *get_safe_buffer_start();
 
-/*
-  PTA_Normalf _norms;
-  PTA_Colorf _colors;
-  PTA_ushort _cindexes,_nindexes;
-*/
+protected:
+  DXScreenData *_screen;
+  LPDIRECT3DDEVICE9 _d3d_device;  // same as _screen->_d3d_device, cached for spd
+  IDirect3DSwapChain9 *_swap_chain;
+  D3DPRESENT_PARAMETERS _presentation_reset;  // This is built during reset device
+
+  bool _dx_is_ready;
+  HRESULT _last_testcooplevel_result;
+
+  bool _vertex_blending_enabled;
+
+  RenderBuffer::Type _cur_read_pixel_buffer;  // source for copy_pixel_buffer operation
+  bool _auto_rescale_normal;
+
+  D3DCOLOR _d3dcolor_clear_value;
+  UINT _color_writemask;
 
-  Colorf _lmodel_ambient;
   float _material_ambient;
   float _material_diffuse;
   float _material_specular;
   float _material_shininess;
   float _material_emission;
 
-  typedef enum {None,
-                PerVertexFog=D3DRS_FOGVERTEXMODE,
-                PerPixelFog=D3DRS_FOGTABLEMODE
-               } DxgsgFogType;
-  DxgsgFogType _doFogType;
-  bool _fog_enabled;
-/*
-  TODO: cache fog state
-  float _fog_start,_fog_end,_fog_density,float _fog_color;
-*/
-
-  float      _alpha_func_refval;  // d3d stores UINT, panda stores this as float.  we store float
-  D3DCMPFUNC _alpha_func;
-
-  D3DBLEND _blend_source_func;
-  D3DBLEND _blend_dest_func;
-
-  bool _line_smooth_enabled;
-  bool _color_material_enabled;
-  bool _texturing_enabled;
-  bool _clipping_enabled;
-  bool _dither_enabled;
-  bool _stencil_test_enabled;
-  bool _blend_enabled;
-  bool _depth_test_enabled;
-  bool _depth_write_enabled;
-  bool _alpha_test_enabled;
-  DWORD _clip_plane_bits;
-
-  RenderModeAttrib::Mode _current_fill_mode;  //poinr/wireframe/solid
+  enum DxgsgFogType {
+    None,
+    PerVertexFog=D3DRS_FOGVERTEXMODE,
+    PerPixelFog=D3DRS_FOGTABLEMODE
+  };
+  DxgsgFogType _do_fog_type;
 
-  // unused right now
-  //GraphicsChannel *_panda_gfx_channel;  // cache the 1 channel dx supports
+  DWORD _clip_plane_bits;
+  CullFaceAttrib::Mode _cull_face_mode;
+  RenderModeAttrib::Mode _current_fill_mode;  //point/wireframe/solid
 
-  // Cur Texture State
-  TextureStage::Mode _CurTexBlendMode;
-  D3DTEXTUREFILTERTYPE _CurTexMagFilter,_CurTexMinFilter,_CurTexMipFilter;
-  DWORD _CurTexAnisoDegree;
-  Texture::WrapMode _CurTexWrapModeU,_CurTexWrapModeV;
-  LMatrix4f _current_projection_mat;
-  int _projection_mat_stack_count;
+  LMatrix4f _projection_mat;
 
   CPT(DisplayRegion) _actual_display_region;
-
-  // Color/Alpha Matrix Transition stuff
-  INLINE void transform_color(Colorf &InColor,D3DCOLOR &OutColor);
+  const DXVertexBufferContext9 *_active_vbuffer;
+  const DXIndexBufferContext9 *_active_ibuffer;
 
   bool _overlay_windows_supported;
+  bool _tex_stats_retrieval_impossible;
 
-#if 0
-  // This is here just as a temporary hack so this file will still
-  // compile.  However, it is never initialized and will certainly
-  // cause the code to crash when it is referenced.  (This used to be
-  // inherited from the base class, but the new design requires that a
-  // GSG may be used for multiple windows, so it doesn't make sense to
-  // store a single window pointer any more.)
-  GraphicsWindow *_win;
-#endif
+  static D3DMATRIX _d3d_ident_mat;
 
-public:
-  static GraphicsStateGuardian*
-  make_DXGraphicsStateGuardian9(const FactoryParams &params);
-  void set_context(DXScreenData *pNewContextData);
-  void set_render_target();
+  static unsigned char *_temp_buffer;
+  static unsigned char *_safe_buffer_start;
 
-  static TypeHandle get_class_type();
-  static void init_type();
-  virtual TypeHandle get_type() const;
+public:
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
-  INLINE void SetDXReady(bool status)  { _bDXisReady = status; }
-  INLINE bool GetDXReady()  { return _bDXisReady;}
-  void DXGraphicsStateGuardian9::SetTextureBlendMode(TextureStage::Mode TexBlendMode,bool bJustEnable);
-
-  void  dx_cleanup(bool bRestoreDisplayMode,bool bAtExitFnCalled);
-  void reset_panda_gsg();
-  HRESULT reset_d3d_device(D3DPRESENT_PARAMETERS *pPresParams, DXScreenData **pScrn=NULL);
 
-  #define DO_REACTIVATE_WINDOW true
-  bool CheckCooperativeLevel(bool bDoReactivateWindow = false);
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
 
-  void show_frame(bool bNoNewFrameDrawn = false);
-  void dx_init();
-
-  void support_overlay_window(bool flag);
-
-  bool create_swap_chain (DXScreenData *pNewContextData);
-  bool release_swap_chain (DXScreenData *pNewContextData);
-  void copy_pres_reset(DXScreenData *pNewContextData);
+public:
+  static void init_type() {
+    GraphicsStateGuardian::init_type();
+    register_type(_type_handle, "DXGraphicsStateGuardian9",
+                  GraphicsStateGuardian::get_class_type());
+  }
 
 private:
   static TypeHandle _type_handle;
+
+  friend class wdxGraphicsWindow9;
+  friend class wdxGraphicsPipe9;
+  friend class wdxGraphicsWindowGroup9;
+  friend class DXTextureContext9;
 };
 
-HRESULT CreateDX9Cursor(LPDIRECT3DDEVICE9 pd3dDevice, HCURSOR hCursor,BOOL bAddWatermark);
+#include "dxGraphicsStateGuardian9.I"
 
-#include "DXGraphicsStateGuardian9.I"
 #endif
-

+ 17 - 0
panda/src/dxgsg9/dxIndexBufferContext9.I

@@ -0,0 +1,17 @@
+// Filename: dxIndexBufferContext9.I
+// Created by:  drose (18Mar05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////

+ 132 - 0
panda/src/dxgsg9/dxIndexBufferContext9.cxx

@@ -0,0 +1,132 @@
+// Filename: dxIndexBufferContext9.cxx
+// Created by:  drose (18Mar05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dxIndexBufferContext9.h"
+#include "geomPrimitive.h"
+#include "config_dxgsg9.h"
+#include "graphicsStateGuardian.h"
+#include "pStatTimer.h"
+#include <d3dx9.h>
+
+TypeHandle DXIndexBufferContext9::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXIndexBufferContext9::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+DXIndexBufferContext9::
+DXIndexBufferContext9(GeomPrimitive *data) :
+  IndexBufferContext(data),
+  _ibuffer(NULL)
+{
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXIndexBufferContext9::Destructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+DXIndexBufferContext9::
+~DXIndexBufferContext9() {
+  if (_ibuffer != NULL) {
+    if (dxgsg9_cat.is_debug()) {
+      dxgsg9_cat.debug()
+        << "deleting index buffer " << _ibuffer << "\n";
+    }
+
+    RELEASE(_ibuffer, dxgsg9, "index buffer", RELEASE_ONCE);
+    _ibuffer = NULL;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXIndexBufferContext9::create_ibuffer
+//       Access: Public
+//  Description: Creates a new index buffer (but does not upload data
+//               to it).
+////////////////////////////////////////////////////////////////////
+void DXIndexBufferContext9::
+create_ibuffer(DXScreenData &scrn) {
+  if (_ibuffer != NULL) {
+    RELEASE(_ibuffer, dxgsg9, "index buffer", RELEASE_ONCE);
+    _ibuffer = NULL;
+  }
+
+  PStatTimer timer(GraphicsStateGuardian::_create_index_buffer_pcollector);
+
+  D3DFORMAT index_type =
+    DXGraphicsStateGuardian9::get_index_type(get_data()->get_index_type());
+
+  HRESULT hr = scrn._d3d_device->CreateIndexBuffer
+
+//    (get_data()->get_data_size_bytes(), D3DUSAGE_WRITEONLY,
+//     index_type, D3DPOOL_MANAGED, &_ibuffer, NULL);
+    (get_data()->get_data_size_bytes(), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC,
+     index_type, D3DPOOL_DEFAULT, &_ibuffer, NULL);
+
+  if (FAILED(hr)) {
+    dxgsg9_cat.warning()
+      << "CreateIndexBuffer failed" << D3DERRORSTRING(hr);
+    _ibuffer = NULL;
+  } else {
+    if (dxgsg9_cat.is_debug()) {
+      dxgsg9_cat.debug()
+        << "creating index buffer " << _ibuffer << ": "
+        << get_data()->get_num_vertices() << " indices ("
+        << get_data()->get_vertices()->get_array_format()->get_column(0)->get_numeric_type()
+        << ")\n";
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXIndexBufferContext9::upload_data
+//       Access: Public
+//  Description: Copies the latest data from the client store to
+//               DirectX.
+////////////////////////////////////////////////////////////////////
+void DXIndexBufferContext9::
+upload_data() {
+  nassertv(_ibuffer != NULL);
+  PStatTimer timer(GraphicsStateGuardian::_load_index_buffer_pcollector);
+
+  int data_size = get_data()->get_data_size_bytes();
+
+  if (dxgsg9_cat.is_spam()) {
+    dxgsg9_cat.spam()
+      << "copying " << data_size
+      << " bytes into index buffer " << _ibuffer << "\n";
+  }
+
+  BYTE *local_pointer;
+
+//  HRESULT hr = _ibuffer->Lock(0, data_size, (void **) &local_pointer, 0);
+  HRESULT hr = _ibuffer->Lock(0, data_size, (void **) &local_pointer, D3DLOCK_DISCARD);
+
+  if (FAILED(hr)) {
+    dxgsg9_cat.error()
+      << "IndexBuffer::Lock failed" << D3DERRORSTRING(hr);
+    return;
+  }
+
+  GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size);
+  memcpy(local_pointer, get_data()->get_data(), data_size);
+
+  _ibuffer->Unlock();
+}

+ 61 - 0
panda/src/dxgsg9/dxIndexBufferContext9.h

@@ -0,0 +1,61 @@
+// Filename: dxIndexBufferContext9.h
+// Created by:  drose (18Mar05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DXINDEXBUFFERCONTEXT9_H
+#define DXINDEXBUFFERCONTEXT9_H
+
+#include "pandabase.h"
+#include "dxgsg9base.h"
+#include "indexBufferContext.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : DXIndexBufferContext9
+// Description : Caches a GeomPrimitive in the DirectX device as
+//               an index buffer.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDADX DXIndexBufferContext9 : public IndexBufferContext {
+public:
+  DXIndexBufferContext9(GeomPrimitive *data);
+  virtual ~DXIndexBufferContext9();
+
+  void create_ibuffer(DXScreenData &scrn);
+  void upload_data();
+
+  IDirect3DIndexBuffer9 *_ibuffer;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    IndexBufferContext::init_type();
+    register_type(_type_handle, "DXIndexBufferContext9",
+                  IndexBufferContext::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "dxIndexBufferContext9.I"
+
+#endif

+ 5 - 7
panda/src/dxgsg9/dxInput9.cxx

@@ -1,10 +1,10 @@
-// Filename: dxInput8.cxx
-// Created by:   masad (02Jan04)
+// Filename: dxInput9.cxx
+// Created by:  angelina jolie (07Oct99)
 //
 ////////////////////////////////////////////////////////////////////
 //
 // PANDA 3D SOFTWARE
-// Copyright (c) 2004, Disney Enterprises, Inc.  All rights reserved
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
 //
 // All use of this software is subject to the terms of the Panda 3d
 // Software license.  You should have received a copy of this license
@@ -102,7 +102,7 @@ bool DInput9Info::InitDirectInput() {
     return true;
 }
 
-bool DInput9Info::CreateJoystickOrPad(HWND hWnd) {
+bool DInput9Info::CreateJoystickOrPad(HWND _window) {
     bool bFoundDev = false;
     UINT devnum=0;
     char *errstr=NULL;
@@ -156,7 +156,7 @@ bool DInput9Info::CreateJoystickOrPad(HWND hWnd) {
 
     // Set the cooperative level to let DInput know how this device should
     // interact with the system and with other DInput applications.
-    hr = pJoyDevice->SetCooperativeLevel( hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
+    hr = pJoyDevice->SetCooperativeLevel( _window, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
     if(FAILED(hr)) {
         errstr="SetCooperativeLevel";
         goto handle_error;
@@ -272,5 +272,3 @@ bool DInput9Info::ReadJoystick(int devnum, DIJOYSTATE2 &js) {
      wdxdisplay_cat.fatal() << errstr << D3DERRORSTRING(hr);
      return false;
 }
-
-

+ 6 - 5
panda/src/dxgsg9/dxInput9.h

@@ -1,10 +1,10 @@
-// Filename: dxInput8.h
-// Created by:   masad (02Jan04)
+// Filename: dxInput9.h
+// Created by:  blllyjo (07Oct99)
 //
 ////////////////////////////////////////////////////////////////////
 //
 // PANDA 3D SOFTWARE
-// Copyright (c) 2004, Disney Enterprises, Inc.  All rights reserved
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
 //
 // All use of this software is subject to the terms of the Panda 3d
 // Software license.  You should have received a copy of this license
@@ -19,7 +19,7 @@
 #ifndef DXINPUT9_H
 #define DXINPUT9_H
 
-#define DIRECTINPUT_VERSION 0x800
+#define DIRECTINPUT_VERSION 0x900
 #include <dinput.h>
 typedef vector<DIDEVICEINSTANCE> DI_DeviceInfos;
 typedef vector<DIDEVICEOBJECTINSTANCE> DI_DeviceObjInfos;
@@ -29,7 +29,7 @@ public:
  DInput9Info();
  ~DInput9Info();
  bool InitDirectInput();
- bool CreateJoystickOrPad(HWND hWnd);
+ bool CreateJoystickOrPad(HWND _window);
  bool ReadJoystick(int devnum, DIJOYSTATE2 &js);
 
  HINSTANCE _hDInputDLL;
@@ -43,3 +43,4 @@ public:
 };
 
 #endif
+

+ 73 - 0
panda/src/dxgsg9/dxTextureContext9.I

@@ -0,0 +1,73 @@
+// Filename: dxTextureContext9.I
+// Created by:  drose (23May05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXTextureContext9::has_mipmaps
+//       Access: Public
+//  Description: Returns true if the texture was created with mipmaps,
+//               false otherwise.
+////////////////////////////////////////////////////////////////////
+INLINE bool DXTextureContext9::
+has_mipmaps() const {
+  return _has_mipmaps;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXTextureContext9::get_d3d_texture
+//       Access: Public
+//  Description: Returns the Direct3D object that represents the
+//               texture, whatever kind of texture it is.
+////////////////////////////////////////////////////////////////////
+INLINE IDirect3DBaseTexture9 *DXTextureContext9::
+get_d3d_texture() const {
+  return _d3d_texture;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXTextureContext9::get_d3d_2d_texture
+//       Access: Public
+//  Description: Returns the Direct3D object that represents the
+//               texture, in the case of a 1-d or 2-d texture.
+////////////////////////////////////////////////////////////////////
+INLINE IDirect3DTexture9 *DXTextureContext9::
+get_d3d_2d_texture() const {
+  return _d3d_2d_texture;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXTextureContext9::get_d3d_volume_texture
+//       Access: Public
+//  Description: Returns the Direct3D object that represents the
+//               texture, in the case of a 3-d texture.
+////////////////////////////////////////////////////////////////////
+INLINE IDirect3DVolumeTexture9 *DXTextureContext9::
+get_d3d_volume_texture() const {
+  return _d3d_volume_texture;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXTextureContext9::get_d3d_cube_texture
+//       Access: Public
+//  Description: Returns the Direct3D object that represents the
+//               texture, in the case of a cube map texture.
+////////////////////////////////////////////////////////////////////
+INLINE IDirect3DCubeTexture9 *DXTextureContext9::
+get_d3d_cube_texture() const {
+  return _d3d_cube_texture;
+}

+ 1182 - 929
panda/src/dxgsg9/dxTextureContext9.cxx

@@ -1,10 +1,10 @@
-// Filename: dxTextureContext8.cxx
-// Created by:   masad (02Jan04)
+// Filename: dxTextureContext9.cxx
+// Created by:  georges (02Feb02)
 //
 ////////////////////////////////////////////////////////////////////
 //
 // PANDA 3D SOFTWARE
-// Copyright (c) 2004, Disney Enterprises, Inc.  All rights reserved
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
 //
 // All use of this software is subject to the terms of the Panda 3d
 // Software license.  You should have received a copy of this license
@@ -16,1105 +16,1358 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#include <assert.h>
-#include <time.h>
 #include "dxTextureContext9.h"
 #include "config_dxgsg9.h"
 #include "dxGraphicsStateGuardian9.h"
-//#include "pnmImage.h"
+#include "pStatTimer.h"
 #include <d3dx9tex.h>
+#include <assert.h>
+#include <time.h>
+
+TypeHandle DXTextureContext9::_type_handle;
 
-//#define FORCE_16bpp_1555
 static const DWORD g_LowByteMask = 0x000000FF;
 
-#define PANDA_BGRA_ORDER
-
-#ifdef PANDA_BGRA_ORDER
-// assume Panda uses byte-order BGRA/LA to store pixels, which when read into little-endian word is ARGB/AL
-// these macros GET from Texture, (wont work from DDSurface)
-#define GET_RED_BYTE(PIXEL_DWORD)  ((BYTE)((PIXEL_DWORD >> 16) & g_LowByteMask))
-#define GET_BLUE_BYTE(PIXEL_DWORD) ((BYTE)((PIXEL_DWORD)       & g_LowByteMask))
-#else
-// otherwise Panda uses int ABGR (big-endian RGBA order), (byte-order RGBA or RGB)
-#define GET_RED_BYTE(PIXEL_DWORD)  ((BYTE)(PIXEL_DWORD         & g_LowByteMask))
-#define GET_BLUE_BYTE(PIXEL_DWORD) ((BYTE)((PIXEL_DWORD >> 16) & g_LowByteMask))
-#endif
+////////////////////////////////////////////////////////////////////
+//     Function: DXTextureContext9::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+DXTextureContext9::
+DXTextureContext9(Texture *tex) :
+  TextureContext(tex) {
+
+  if (dxgsg9_cat.is_spam()) {
+    dxgsg9_cat.spam()
+      << "Creating DX texture [" << tex->get_name() << "], minfilter(" << tex->get_minfilter() << "), magfilter(" << tex->get_magfilter() << "), anisodeg(" << tex->get_anisotropic_degree() << ")\n";
+  }
+
+  _d3d_texture = NULL;
+  _d3d_2d_texture = NULL;
+  _d3d_volume_texture = NULL;
+  _d3d_cube_texture = NULL;
+  _has_mipmaps = false;
+}
 
-#define GET_GREEN_BYTE(PIXEL_DWORD) ((BYTE)((PIXEL_DWORD >> 8) & g_LowByteMask))
-#define GET_ALPHA_BYTE(PIXEL_DWORD) ((BYTE)(((DWORD)PIXEL_DWORD) >> 24))  // unsigned >> shifts in 0's, so dont need to mask off upper bits
+////////////////////////////////////////////////////////////////////
+//     Function: DXTextureContext9::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+DXTextureContext9::
+~DXTextureContext9() {
+  if (dxgsg9_cat.is_spam()) {
+    dxgsg9_cat.spam()
+      << "Deleting texture context for " << _texture->get_name() << "\n";
+  }
+  delete_texture();
+  TextureContext::~TextureContext();
+}
 
-char *PandaFilterNameStrs[] = {"FT_nearest","FT_linear","FT_nearest_mipmap_nearest","FT_linear_mipmap_nearest",
-    "FT_nearest_mipmap_linear", "FT_linear_mipmap_linear"
-};
+////////////////////////////////////////////////////////////////////
+//     Function: DXTextureContext9::create_texture
+//       Access: Public
+//  Description: Use panda texture's pixelbuffer to create a texture
+//               for the specified device.  This code gets the
+//               attributes of the texture from the bitmap, creates
+//               the texture, and then copies the bitmap into the
+//               texture.  The return value is true if the texture is
+//               successfully created, false otherwise.
+////////////////////////////////////////////////////////////////////
+bool DXTextureContext9::
+create_texture(DXScreenData &scrn) {
+  HRESULT hr;
+  int num_alpha_bits;     //  number of alpha bits in texture pixfmt
+  D3DFORMAT target_pixel_format = D3DFMT_UNKNOWN;
+  bool needs_luminance = false;
 
+  nassertr(IS_VALID_PTR(_texture), false);
 
-TypeHandle DXTextureContext9::_type_handle;
+  delete_texture();
 
-#define SWAPDWORDS(X,Y)  { DWORD temp=X;  X=Y; Y=temp; }
+  clear_dirty_flags(Texture::DF_image | Texture::DF_mipmap);
 
-#ifdef _DEBUG
-/*
-static void DebugPrintPixFmt(DDPIXELFORMAT* pddpf) {
-    static int iddpfnum=0;
-    ostream *dbgout = &dxgsg_cat.debug();
+  // bpp indicates requested fmt, not texture fmt
+  DWORD target_bpp = get_bits_per_pixel(_texture->get_format(), &num_alpha_bits);
+  DWORD num_color_channels = _texture->get_num_components();
 
-    *dbgout << "DDPF[" << iddpfnum << "]: RGBBitCount:" << pddpf->dwRGBBitCount
-    << " Flags:"  << (void *)pddpf->dwFlags ;
+  //PRINT_REFCNT(dxgsg9, scrn._d3d9);
 
-    if(pddpf->dwFlags & DDPF_RGB) {
-        *dbgout << " RGBmask:" << (void *) (pddpf->dwRBitMask | pddpf->dwGBitMask | pddpf->dwBBitMask);
-        *dbgout << " Rmask:" << (void *) (pddpf->dwRBitMask);
-    }
+  DWORD orig_width = (DWORD)_texture->get_x_size();
+  DWORD orig_height = (DWORD)_texture->get_y_size();
+  DWORD orig_depth = (DWORD)_texture->get_z_size();
 
-    if(pddpf->dwFlags & DDPF_ALPHAPIXELS) {
-        *dbgout << " Amask:" << (void *) pddpf->dwRGBAlphaBitMask;
-    }
+  if ((_texture->get_format() == Texture::F_luminance_alpha)||
+      (_texture->get_format() == Texture::F_luminance_alphamask) ||
+      (_texture->get_format() == Texture::F_luminance)) {
+    needs_luminance = true;
+  }
 
-    if(pddpf->dwFlags & DDPF_LUMINANCE) {
-        *dbgout << " Lummask:" << (void *) pddpf->dwLuminanceBitMask;
+  if (num_alpha_bits > 0) {
+    if (num_color_channels == 3) {
+      dxgsg9_cat.error()
+        << "texture " << _texture->get_name()
+        << " has no inherent alpha channel, but alpha format is requested!\n";
     }
+  }
 
-    *dbgout << endl;
+  _d3d_format = D3DFMT_UNKNOWN;
 
-    iddpfnum++;
-}
-*/
-void PrintLastError(char *msgbuf) {
-    DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
-
-    if(msgbuf==NULL) {
-        LPVOID lpMsgBuf;
-        dwFlags|=FORMAT_MESSAGE_ALLOCATE_BUFFER;
-        FormatMessage( dwFlags,
-                       NULL,GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
-                       (LPTSTR) &lpMsgBuf,0,NULL );
-        MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION );
-        LocalFree(lpMsgBuf);
-    } else {
-        FormatMessage( dwFlags,
-                       NULL,GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
-                       (LPTSTR) msgbuf,500,NULL );
+  // figure out what 'D3DFMT' the Texture is in, so D3DXLoadSurfFromMem knows how to perform copy
+
+  switch (num_color_channels) {
+  case 1:
+    if (num_alpha_bits > 0) {
+      _d3d_format = D3DFMT_A8;
+    } else if (needs_luminance) {
+      _d3d_format = D3DFMT_L8;
+    }
+    break;
+  case 2:
+    nassertr(needs_luminance && (num_alpha_bits > 0), false);
+    _d3d_format = D3DFMT_A8L8;
+    break;
+  case 3:
+    _d3d_format = D3DFMT_R8G8B8;
+    break;
+  case 4:
+    _d3d_format = D3DFMT_A8R8G8B8;
+    break;
+  }
+
+  // make sure we handled all the possible cases
+  nassertr(_d3d_format != D3DFMT_UNKNOWN, false);
+
+  DWORD target_width = orig_width;
+  DWORD target_height = orig_height;
+  DWORD target_depth = orig_depth;
+
+  DWORD filter_caps;
+
+  switch (_texture->get_texture_type()) {
+  case Texture::TT_1d_texture:
+  case Texture::TT_2d_texture:
+    filter_caps = scrn._d3dcaps.TextureFilterCaps;
+
+    if (target_width > scrn._d3dcaps.MaxTextureWidth) {
+      target_width = scrn._d3dcaps.MaxTextureWidth;
+    }
+    if (target_height > scrn._d3dcaps.MaxTextureHeight) {
+      target_height = scrn._d3dcaps.MaxTextureHeight;
     }
-}
 
-#endif
+    if (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_POW2) {
+      if (!ISPOW2(target_width)) {
+        target_width = down_to_power_2(target_width);
+      }
+      if (!ISPOW2(target_height)) {
+        target_height = down_to_power_2(target_height);
+      }
+    }
+    break;
 
+  case Texture::TT_3d_texture:
+    if ((scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP) == 0) {
+      dxgsg9_cat.warning()
+        << "3-d textures are not supported by this graphics driver.\n";
+      return false;
+    }
 
-/* for reference
-enum Format {
-  F_color_index,
-  F_stencil_index,
-  F_depth_component,
-  F_red,
-  F_green,
-  F_blue,
-  F_alpha,
-  F_rgb,     // any suitable RGB mode, whatever the hardware prefers
-  F_rgb5,    // specifically, 5 bits per R,G,B channel
-  F_rgb8,    // 8 bits per R,G,B channel
-  F_rgb12,   // 12 bits per R,G,B channel
-  F_rgb332,  // 3 bits per R & G, 2 bits for B
-  F_rgba,    // any suitable RGBA mode, whatever the hardware prefers
-  F_rgbm,    // as above, but only requires 1 bit for alpha (i.e. mask)
-  F_rgba4,   // 4 bits per R,G,B,A channel
-  F_rgba5,   // 5 bits per R,G,B channel, 1 bit alpha
-  F_rgba8,   // 8 bits per R,G,B,A channel
-  F_rgba12,  // 12 bits per R,G,B,A channel
-  F_luminance,
-  F_luminance_alpha
-};
-
-  enum Type {
-    T_unsigned_byte,   // 1 byte per channel
-    T_unsigned_short,  // 2 byte per channel
-    T_unsigned_byte_332,  // RGB in 1 byte
-    T_float,             // 1 channel stored as float
-  };
-*/
+    filter_caps = scrn._d3dcaps.VolumeTextureFilterCaps;
 
-////////////////////////////////////////////////////////////////////
-//     Function: DXTextureContext9::get_bits_per_pixel
-//       Access: Protected
-//  Description: Maps from the Texture's Format symbols
-//               to bpp.  returns # of alpha bits
-//               Note: Texture's format indicates REQUESTED final format,
-//                     not the stored format, which is indicated by pixelbuffer type
-////////////////////////////////////////////////////////////////////
+    if (target_width > scrn._d3dcaps.MaxVolumeExtent) {
+      target_width = scrn._d3dcaps.MaxVolumeExtent;
+    }
+    if (target_height > scrn._d3dcaps.MaxVolumeExtent) {
+      target_height = scrn._d3dcaps.MaxVolumeExtent;
+    }
+    if (target_depth > scrn._d3dcaps.MaxVolumeExtent) {
+      target_depth = scrn._d3dcaps.MaxVolumeExtent;
+    }
 
-unsigned int DXTextureContext9::
-get_bits_per_pixel(Texture::Format format, int *alphbits) {
-    *alphbits = 0;      // assume no alpha bits
-    switch(format) {
-        case Texture::F_alpha:
-            *alphbits = 8;
-        case Texture::F_color_index:
-        case Texture::F_red:
-        case Texture::F_green:
-        case Texture::F_blue:
-        case Texture::F_rgb332:
-            return 8;
-        case Texture::F_luminance_alphamask:
-            *alphbits = 1;
-            return 16;
-        case Texture::F_luminance_alpha:
-            *alphbits = 8;
-            return 16;
-        case Texture::F_luminance:
-            return 8;
-        case Texture::F_rgba4:
-            *alphbits = 4;
-            return 16;
-        case Texture::F_rgba5:
-            *alphbits = 1;
-            return 16;
-        case Texture::F_depth_component:
-        case Texture::F_rgb5:
-            return 16;
-        case Texture::F_rgb8:
-        case Texture::F_rgb:
-            return 24;
-        case Texture::F_rgba8:
-        case Texture::F_rgba:
-        case Texture::F_rgbm:
-            if(format==Texture::F_rgbm)   // does this make any sense?
-             *alphbits = 1;
-            else *alphbits = 8;
-            return 32;
-        case Texture::F_rgb12:
-            return 36;
-        case Texture::F_rgba12:
-            *alphbits = 12;
-            return 48;
+    if (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2) {
+      if (!ISPOW2(target_width)) {
+        target_width = down_to_power_2(target_width);
+      }
+      if (!ISPOW2(target_height)) {
+        target_height = down_to_power_2(target_height);
+      }
+      if (!ISPOW2(target_depth)) {
+        target_depth = down_to_power_2(target_depth);
+      }
     }
-    return 8;
-}
+    break;
 
-// still need custom conversion since d3d/d3dx has no way to convert arbitrary fmt to ARGB in-memory user buffer
-HRESULT ConvertD3DSurftoPixBuf(RECT &SrcRect,IDirect3DSurface9 *pD3DSurf9,Texture *texture) {
-// copies SrcRect in pD3DSurf to upper left of texture
-    HRESULT hr;
-    DWORD dwNumComponents=texture->get_num_components();
+  case Texture::TT_cube_map:
+    if ((scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP) == 0) {
+      dxgsg9_cat.warning()
+        << "Cube map textures are not supported by this graphics driver.\n";
+      return false;
+    }
 
-    assert(texture->get_component_width()==sizeof(BYTE));   // cant handle anything else now
-    assert(texture->get_component_type()==Texture::T_unsigned_byte);   // cant handle anything else now
-    assert((dwNumComponents==3) || (dwNumComponents==4));  // cant handle anything else now
-    assert(IS_VALID_PTR(pD3DSurf9));
+    filter_caps = scrn._d3dcaps.CubeTextureFilterCaps;
 
-    BYTE *pbuf=texture->modify_ram_image().p();
+    if (target_width > scrn._d3dcaps.MaxTextureWidth) {
+      target_width = scrn._d3dcaps.MaxTextureWidth;
+    }
 
-    if(IsBadWritePtr(pD3DSurf9,sizeof(DWORD))) {
-        dxgsg9_cat.error() << "ConvertDDSurftoTexture failed: bad pD3DSurf ptr value (" << ((void*)pD3DSurf9) << ")\n";
-        exit(1);
+    if (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) {
+      if (!ISPOW2(target_width)) {
+        target_width = down_to_power_2(target_width);
+      }
     }
 
-    DWORD dwXWindowOffset,dwYWindowOffset;
-    DWORD dwCopyWidth,dwCopyHeight;
+    target_height = target_width;
+    break;
+  }
+
+  // checks for SQUARE reqmt (nvidia riva128 needs this)
+  if ((target_width != target_height) &&
+      (scrn._d3dcaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) != 0) {
+    // assume pow2 textures.  sum exponents, divide by 2 rounding down
+    // to get sq size
+    int i, width_exp, height_exp;
+    for (i = target_width, width_exp = 0; i > 1; width_exp++, i >>= 1) {
+    }
+    for (i = target_height, height_exp = 0; i > 1; height_exp++, i >>= 1) {
+    }
+    target_height = target_width = 1<<((width_exp+height_exp)>>1);
+  }
+
+  bool shrink_original = false;
+
+  if (orig_width != target_width || orig_height != target_height ||
+      orig_depth != target_depth) {
+    if (_texture->get_texture_type() == Texture::TT_3d_texture) {
+      dxgsg9_cat.info()
+        << "Reducing size of " << _texture->get_name()
+        << " from " << orig_width << "x" << orig_height << "x" << orig_depth
+        << " to " << target_width << "x" << target_height
+        << "x" << target_depth << "\n";
+    } else {
+      dxgsg9_cat.info()
+        << "Reducing size of " << _texture->get_name()
+        << " from " << orig_width << "x" << orig_height
+        << " to " << target_width << "x" << target_height << "\n";
+    }
 
-    D3DLOCKED_RECT LockedRect;
-    D3DSURFACE_DESC SurfDesc;
+    shrink_original = true;
+  }
 
-    hr = pD3DSurf9->GetDesc(&SurfDesc);
+  const char *error_message;
 
-    dwXWindowOffset=SrcRect.left,dwYWindowOffset=SrcRect.top;
-    dwCopyWidth=RECT_XSIZE(SrcRect);
-    dwCopyHeight=RECT_YSIZE(SrcRect);
+  error_message = "create_texture failed: couldn't find compatible device Texture Pixel Format for input texture";
 
-    //make sure there's enough space in the texture, its size must match (especially xsize)
-   // or scanlines will be too long
+  if (dxgsg9_cat.is_spam()) {
+    dxgsg9_cat.spam()
+      << "create_texture handling target bitdepth: " << target_bpp
+      << " alphabits: " << num_alpha_bits << endl;
+  }
 
-    if(!((dwCopyWidth==texture->get_x_size()) && (dwCopyHeight<=(DWORD)texture->get_y_size()))) {
-        dxgsg9_cat.error() << "ConvertDDSurftoPixBuf, Texture size too small to hold display surface!\n";
-        assert(0);
-        return E_FAIL;
-    }
+  // I could possibly replace some of this logic with
+  // D3DXCheckTextureRequirements(), but it wouldn't handle all my
+  // specialized low-memory cases perfectly
 
-    hr = pD3DSurf9->LockRect(&LockedRect,(CONST RECT*)NULL,(D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE /* | D3DLOCK_NOSYSLOCK */));
-    if(FAILED(hr)) {
-        dxgsg9_cat.error() << "ConvertDDSurftoPixBuf LockRect() failed!" << D3DERRORSTRING(hr);
-        return hr;
-    }
+#define CONVTYPE_STMT
 
-    // ones not listed not handled yet
-    assert((SurfDesc.Format==D3DFMT_A8R8G8B8)||(SurfDesc.Format==D3DFMT_X8R8G8B8)||(SurfDesc.Format==D3DFMT_R8G8B8)||
-           (SurfDesc.Format==D3DFMT_R5G6B5)||(SurfDesc.Format==D3DFMT_X1R5G5B5)||(SurfDesc.Format==D3DFMT_A1R5G5B5)||
-           (SurfDesc.Format==D3DFMT_A4R4G4B4));
+#define CHECK_FOR_FMT(FMT, CONV)  \
+                    if (scrn._supported_tex_formats_mask & FMT##_FLAG) {   \
+                        CONVTYPE_STMT;                             \
+                        target_pixel_format = D3DFMT_##FMT;                 \
+                        goto found_matching_format; }
 
-    //pbuf contains raw ARGB in Texture byteorder
+  // handle each target bitdepth separately.  might be less confusing
+  // to reorg by num_color_channels (input type, rather than desired
+  // 1st target)
+  switch (target_bpp) {
 
-    DWORD BytePitch = LockedRect.Pitch;
-    BYTE* pSurfBytes = (BYTE*)LockedRect.pBits;
+    // IMPORTANT NOTE:
+    // target_bpp is REQUESTED bpp, not what exists in the texture
+    // array (the texture array contains num_color_channels*8bits)
 
-    // writes out last line in DDSurf first in PixelBuf, so Y line order precedes inversely
+  case 32:
+    if (!((num_color_channels == 3) || (num_color_channels == 4)))
+      break; //bail
 
-    if(dxgsg9_cat.is_debug()) {
-      dxgsg9_cat.debug() 
-        << "ConvertD3DSurftoPixBuf converting " << D3DFormatStr(SurfDesc.Format) << "bpp DDSurf to "
-        <<  dwNumComponents << "-channel panda Texture\n";
+    if (!dx_force_16bpptextures) {
+      if (num_color_channels == 4) {
+        CHECK_FOR_FMT(A8R8G8B8, Conv32to32);
+      } else {
+        CHECK_FOR_FMT(A8R8G8B8, Conv24to32);
+      }
     }
 
-    DWORD *pDstWord = (DWORD *) pbuf;
-    BYTE *pDstByte = (BYTE *) pbuf;
-
-    switch(SurfDesc.Format) {
-        case D3DFMT_A8R8G8B8:
-        case D3DFMT_X8R8G8B8: {
-            if(dwNumComponents==4) {
-                    DWORD *pSrcWord;
-                   #ifdef PANDA_BGRA_ORDER
-                    BYTE *pDstLine = (BYTE*)pDstWord;
-                   #endif
-
-                        pSurfBytes+=BytePitch*(dwYWindowOffset+dwCopyHeight-1);
-                        for(DWORD y=0; y<dwCopyHeight; y++,pSurfBytes-=BytePitch) {
-                            pSrcWord = ((DWORD*)pSurfBytes)+dwXWindowOffset;
-                            #ifdef PANDA_BGRA_ORDER
-                                memcpy(pDstLine,pSrcWord,BytePitch);
-                                pDstLine+=BytePitch;
-                            #else
-                                for(DWORD x=0; x<dwCopyWidth; x++,pSrcWord++,pDstWord++) {
-                                      DWORD dwPixel = *pSrcWord;
-                                      BYTE r,b;
-
-                                      // DDsurf is in ARGB
-                                      r=  (BYTE) ((dwPixel >> 16) & g_LowByteMask);
-                                      b = (BYTE)  (dwPixel & g_LowByteMask);
-
-                                      // want to write out ABGR
-                                      *pDstWord = (dwPixel & 0xFF00FF00) | (b<<16) | r;
-                                }
-                            #endif
-                        }
-            } else {
-                // 24bpp texture case (numComponents==3)
-                DWORD *pSrcWord;
-                pSurfBytes+=BytePitch*(dwYWindowOffset+dwCopyHeight-1);
-                for(DWORD y=0; y<dwCopyHeight; y++,pSurfBytes-=BytePitch) {
-                    pSrcWord = ((DWORD*)pSurfBytes)+dwXWindowOffset;
-
-                    for(DWORD x=0; x<dwCopyWidth; x++,pSrcWord++) {
-                        BYTE r,g,b;
-                        DWORD dwPixel = *pSrcWord;
-
-                        r = (BYTE)((dwPixel>>16) & g_LowByteMask);
-                        g = (BYTE)((dwPixel>> 8) & g_LowByteMask);
-                        b = (BYTE)((dwPixel    ) & g_LowByteMask);
-
-                        #ifdef PANDA_BGRA_ORDER
-                            *pDstByte++ = b;
-                            *pDstByte++ = g;
-                            *pDstByte++ = r;
-                        #else
-                            *pDstByte++ = r;
-                            *pDstByte++ = g;
-                            *pDstByte++ = b;
-                        #endif
-                    }
-                }
-            }
-            break;
-        }
+    if (num_alpha_bits>0) {
+      nassertr(num_color_channels == 4, false);
 
-        case D3DFMT_R8G8B8: {
-                BYTE *pSrcByte;
-                pSurfBytes+=BytePitch*(dwYWindowOffset+dwCopyHeight-1);
-
-                if(dwNumComponents==4) {
-                    for(DWORD y=0; y<dwCopyHeight; y++,pSurfBytes-=BytePitch) {
-                        pSrcByte = pSurfBytes+dwXWindowOffset*3*sizeof(BYTE);
-                        for(DWORD x=0; x<dwCopyWidth; x++,pDstWord++) {
-                            DWORD r,g,b;
-
-                            b = *pSrcByte++;
-                            g = *pSrcByte++;
-                            r = *pSrcByte++;
-
-                            #ifdef PANDA_BGRA_ORDER
-                               *pDstWord = 0xFF000000 | (r << 16) | (g << 8) | b;
-                            #else
-                               *pDstWord = 0xFF000000 | (b << 16) | (g << 8) | r;
-                            #endif
-                        }
-                    }
-                } else {
-                    // 24bpp texture case (numComponents==3)
-                    for(DWORD y=0; y<dwCopyHeight; y++,pSurfBytes-=BytePitch) {
-                        pSrcByte = pSurfBytes+dwXWindowOffset*3*sizeof(BYTE);
-                     #ifdef PANDA_BGRA_ORDER
-                        memcpy(pDstByte,pSrcByte,BytePitch);
-                        pDstByte+=BytePitch;
-                     #else
-                        for(DWORD x=0; x<dwCopyWidth; x++) {
-                            BYTE r,g,b;
-
-                            // pixel buffer is in ABGR format(it stores big-endian RGBA)
-                            // need to change byte order from ARGB
-
-                            b = *pSrcByte++;
-                            g = *pSrcByte++;
-                            r = *pSrcByte++;
-
-                            *pDstByte++ = r;
-                            *pDstByte++ = g;
-                            *pDstByte++ = b;
-                        }
-                      #endif
-                    }
-                }
-                break;
-        }
+      // no 32-bit fmt, look for 16 bit w/alpha  (1-15)
 
-        case D3DFMT_R5G6B5:
-        case D3DFMT_X1R5G5B5:
-        case D3DFMT_A1R5G5B5:
-        case D3DFMT_A4R4G4B4: {
-                WORD  *pSrcWord;
-                // handle 0555,1555,0565,4444 in same loop
-
-                BYTE redshift,greenshift,blueshift;
-                DWORD redmask,greenmask,bluemask;
-
-                if(SurfDesc.Format==D3DFMT_R5G6B5) {
-                    redshift=(11-3);
-                    redmask=0xF800;
-                    greenmask=0x07E0;
-                    greenshift=(5-2);
-                    bluemask=0x001F;
-                    blueshift=3;
-                } else if(SurfDesc.Format==D3DFMT_A4R4G4B4) {
-                    redmask=0x0F00;
-                    redshift=4;
-                    greenmask=0x00F0;
-                    greenshift=0;
-                    bluemask=0x000F;
-                    blueshift=4;
-                } else {  // 1555 or x555
-                    redmask=0x7C00;
-                    redshift=(10-3);
-                    greenmask=0x03E0;
-                    greenshift=(5-3);
-                    bluemask=0x001F;
-                    blueshift=3;
-                }
-
-                pSurfBytes+=BytePitch*(dwYWindowOffset+dwCopyHeight-1);
-                if(dwNumComponents==4) {
-                    // Note: these 16bpp loops ignore input alpha completely (alpha is set to fully opaque in texture!)
-                    //       if we need to capture alpha, probably need to make separate loops for diff 16bpp fmts
-                    //       for best speed
-
-                    for(DWORD y=0; y<dwCopyHeight; y++,pSurfBytes-=BytePitch) {
-                        pSrcWord = ((WORD*)pSurfBytes)+dwXWindowOffset;
-                        for(DWORD x=0; x<dwCopyWidth; x++,pSrcWord++,pDstWord++) {
-                            WORD dwPixel = *pSrcWord;
-                            BYTE r,g,b;
-
-                            b = (dwPixel & bluemask) << blueshift;
-                            g = (dwPixel & greenmask) >> greenshift;
-                            r = (dwPixel & redmask) >> redshift;
-
-                            // alpha is just set to 0xFF
-
-                            #ifdef PANDA_BGRA_ORDER
-                              *pDstWord = 0xFF000000 | (r << 16) | (g << 8) | b;
-                            #else
-                              *pDstWord = 0xFF000000 | (b << 16) | (g << 8) | r;
-                            #endif
-                        }
-                    }
-                } else {
-                    // 24bpp texture case (numComponents==3)
-                    for(DWORD y=0; y<dwCopyHeight; y++,pSurfBytes-=BytePitch) {
-                        pSrcWord = ((WORD*)pSurfBytes)+dwXWindowOffset;
-                        for(DWORD x=0; x<dwCopyWidth; x++,pSrcWord++) {
-                            WORD dwPixel = *pSrcWord;
-                            BYTE r,g,b;
-
-                            b = (dwPixel & bluemask) << blueshift;
-                            g = (dwPixel & greenmask) >> greenshift;
-                            r = (dwPixel & redmask) >> redshift;
-
-                            #ifdef PANDA_BGRA_ORDER
-                                *pDstByte++ = b;
-                                *pDstByte++ = g;
-                                *pDstByte++ = r;
-                            #else
-                                *pDstByte++ = r;
-                                *pDstByte++ = g;
-                                *pDstByte++ = b;
-                            #endif
-                        }
-                    }
-                }
-                break;
-        }
+      // 32 bit RGBA was requested, but only 16 bit alpha fmts are
+      // avail.  By default, convert to 4-4-4-4 which has 4-bit alpha
+      // for blurry edges.  If we know tex only needs 1 bit alpha
+      // (i.e. for a mask), use 1555 instead.
 
-        default:
-            dxgsg9_cat.error() << "ConvertD3DSurftoPixBuf: unsupported D3DFORMAT!\n";
-    }
 
-    pD3DSurf9->UnlockRect();
-    return S_OK;
-}
+      //  ConversionType ConvTo1 = Conv32to16_4444, ConvTo2 = Conv32to16_1555;
+      //  DWORD dwAlphaMask1 = 0xF000, dwAlphaMask2 = 0x8000;
 
-//-----------------------------------------------------------------------------
-// Name: CreateTexture()
-// Desc: Use panda texture's pixelbuffer to create a texture for the specified device.
-//       This code gets the attributes of the texture from the bitmap, creates the
-//       texture, and then copies the bitmap into the texture.
-//-----------------------------------------------------------------------------
-IDirect3DTexture9 *DXTextureContext9::CreateTexture(DXScreenData &scrn) {
-    HRESULT hr;
-    int cNumAlphaBits;     //  number of alpha bits in texture pixfmt
-    D3DFORMAT TargetPixFmt=D3DFMT_UNKNOWN;
-    bool bNeedLuminance = false;
-
-    assert(IS_VALID_PTR(_texture));
-
-    // bpp indicates requested fmt, not texture fmt
-    DWORD target_bpp = get_bits_per_pixel(_texture->get_format(), &cNumAlphaBits);
-    DWORD cNumColorChannels = _texture->get_num_components();
-
-    //PRINT_REFCNT(dxgsg9,scrn.pD3D9);
-
-    DWORD dwOrigWidth  = (DWORD)_texture->get_x_size();
-    DWORD dwOrigHeight = (DWORD)_texture->get_y_size();
-
-    if((_texture->get_format() == Texture::F_luminance_alpha)||
-       (_texture->get_format() == Texture::F_luminance_alphamask) ||
-       (_texture->get_format() == Texture::F_luminance)) {
-        bNeedLuminance = true;
-    }
+      // assume ALPHAMASK is x8000 and RGBMASK is x7fff to simplify
+      // 32->16 conversion.  This should be true on most cards.
 
-    if(cNumAlphaBits>0) {
-        if(cNumColorChannels==3) {
-            dxgsg9_cat.error() << "ERROR: texture " << _tex->get_name() << " has no inherent alpha channel, but alpha format is requested (that would be wasteful)!\n";
-            exit(1);
+#ifndef FORCE_16bpp_1555
+      if (num_alpha_bits == 1)
+#endif
+        {
+          CHECK_FOR_FMT(A1R5G5B5, Conv32to16_1555);
         }
-    }
-
-    _PixBufD3DFmt=D3DFMT_UNKNOWN;
-
-    // figure out what 'D3DFMT' the Texture is in, so D3DXLoadSurfFromMem knows how to perform copy
-
-    switch(cNumColorChannels) {
-        case 1:
-            if(cNumAlphaBits>0)
-                _PixBufD3DFmt=D3DFMT_A8;
-            else if(bNeedLuminance)
-                   _PixBufD3DFmt=D3DFMT_L8;
-            break;
-        case 2:
-            assert(bNeedLuminance && (cNumAlphaBits>0));
-            _PixBufD3DFmt=D3DFMT_A8L8;
-            break;
-        case 3:
-            _PixBufD3DFmt=D3DFMT_R8G8B8;
-            break;
-        case 4:
-            _PixBufD3DFmt=D3DFMT_A8R8G8B8;
-            break;
-    }
 
-    // make sure we handled all the possible cases
-    assert(_PixBufD3DFmt!=D3DFMT_UNKNOWN);
+      // normally prefer 4444 due to better alpha channel resolution
+      CHECK_FOR_FMT(A4R4G4B4, Conv32to16_4444);
+      CHECK_FOR_FMT(A1R5G5B5, Conv32to16_1555);
 
-    DWORD TargetWidth=dwOrigWidth;
-    DWORD TargetHeight=dwOrigHeight;
+      // At this point, bail.  Don't worry about converting to
+      // non-alpha formats yet, I think this will be a very rare case.
+      error_message = "create_texture failed: couldn't find compatible Tex DDPIXELFORMAT! no available 16 or 32-bit alpha formats!";
+    } else {
+      // convert 3 or 4 channel to closest 16bpp color fmt
 
-    if(!ISPOW2(dwOrigWidth) || !ISPOW2(dwOrigHeight)) {
-        dxgsg9_cat.error() << "ERROR: texture dimensions are not a power of 2 for " << _tex->get_name() << "! Please rescale them so it doesnt have to be done at runtime.\n";
-        #ifndef NDEBUG
-          exit(1);  // want to catch badtexsize errors
-        #else
-          goto error_exit;
-        #endif
+      if (num_color_channels == 3) {
+        CHECK_FOR_FMT(R5G6B5, Conv24to16_4444);
+        CHECK_FOR_FMT(X1R5G5B5, Conv24to16_X555);
+      } else {
+        CHECK_FOR_FMT(R5G6B5, Conv32to16_4444);
+        CHECK_FOR_FMT(X1R5G5B5, Conv32to16_X555);
+      }
     }
+    break;
 
-    bool bShrinkOriginal;
-    bShrinkOriginal=false;
+  case 24:
+    nassertr(num_color_channels == 3, false);
 
-    if((dwOrigWidth>scrn.d3dcaps.MaxTextureWidth)||(dwOrigHeight>scrn.d3dcaps.MaxTextureHeight)) {
-        #ifdef _DEBUG
-           dxgsg9_cat.error() << "WARNING: " <<_tex->get_name() << ": Image size exceeds max texture dimensions of (" << scrn.d3dcaps.MaxTextureWidth << "," << scrn.d3dcaps.MaxTextureHeight << ") !!\n"
-           << "Scaling "<< _tex->get_name() << " ("<< dwOrigWidth<<"," <<dwOrigHeight << ") => ("<<  scrn.d3dcaps.MaxTextureWidth << "," << scrn.d3dcaps.MaxTextureHeight << ") !\n";
-        #endif
+    if (!dx_force_16bpptextures) {
+      CHECK_FOR_FMT(R8G8B8, Conv24to24);
 
-        if(dwOrigWidth>scrn.d3dcaps.MaxTextureWidth)
-            TargetWidth=scrn.d3dcaps.MaxTextureWidth;
-        if(dwOrigHeight>scrn.d3dcaps.MaxTextureHeight)
-            TargetHeight=scrn.d3dcaps.MaxTextureHeight;
-        bShrinkOriginal=true;
-    }
+      // no 24-bit fmt.  look for 32 bit fmt (note: this is
+      // memory-hogging choice instead I could look for
+      // memory-conserving 16-bit fmt).
 
-    // checks for SQUARE reqmt (nvidia riva128 needs this)
-    if((TargetWidth != TargetHeight) && (scrn.d3dcaps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)) {
-        // assume pow2 textures.   sum exponents, divide by 2 rounding down to get sq size
-        int i,width_exp,height_exp;
-        for(i=TargetWidth,width_exp=0;i>1;width_exp++,i>>=1);
-        for(i=TargetHeight,height_exp=0;i>1;height_exp++,i>>=1);
-        TargetHeight = TargetWidth = 1<<((width_exp+height_exp)>>1);
-        bShrinkOriginal=true;
-
-#ifdef _DEBUG
-        dxgsg9_cat.debug() << "Scaling "<< _tex->get_name() << " ("<< dwOrigWidth<<"," <<dwOrigHeight << ") => ("<< TargetWidth<<"," << TargetHeight << ") to meet HW square texture reqmt\n";
-#endif
-    }
-/*
-    // we now use D3DXLoadSurfFromMem to do resizing as well as fmt conversion
-    if(bShrinkOriginal) {
-        // need 2 add checks for errors
-        PNMImage pnmi_src;
-        PNMImage *pnmi = new PNMImage(TargetWidth, TargetHeight, cNumColorChannels);
-        _texture->store(pnmi_src);
-        pnmi->quick_filter_from(pnmi_src,0,0);
-
-        _texture->load(*pnmi);  // violates device independence of pixbufs
-
-        dwOrigWidth  = (DWORD)_texture->get_x_size();
-        dwOrigHeight = (DWORD)_texture->get_y_size();
-        delete pnmi;
+      CHECK_FOR_FMT(X8R8G8B8, Conv24to32);
     }
-*/
 
-    char *szErrorMsg;
+    // no 24-bit or 32 fmt.  look for 16 bit fmt (higher res 565 1st)
+    CHECK_FOR_FMT(R5G6B5, Conv24to16_0565);
+    CHECK_FOR_FMT(X1R5G5B5, Conv24to16_X555);
+    break;
 
-    szErrorMsg = "CreateTexture failed: couldn't find compatible device Texture Pixel Format for input texture";
+  case 16:
+    if (needs_luminance) {
+      nassertr(num_alpha_bits > 0, false);
+      nassertr(num_color_channels == 2, false);
 
-    if(dxgsg9_cat.is_spam())
-        dxgsg9_cat.spam() << "CreateTexture handling target bitdepth: " << target_bpp << " alphabits: " << cNumAlphaBits << endl;
-
-    // I could possibly replace some of this logic with D3DXCheckTextureRequirements(), but
-    // it wouldnt handle all my specialized low-memory cases perfectly
-
-#define CONVTYPE_STMT
+      CHECK_FOR_FMT(A8L8, ConvLum16to16);
 
-#define CHECK_FOR_FMT(FMT,CONV)  \
-                    if(scrn.SupportedTexFmtsMask & FMT##_FLAG) {   \
-                        CONVTYPE_STMT;                             \
-                        TargetPixFmt=D3DFMT_##FMT;                 \
-                        goto found_matching_format; }
-
-    // handle each target bitdepth separately.  might be less confusing to reorg by cNumColorChannels (input type, rather
-    // than desired 1st target)
-    switch(target_bpp) {
+      if (!dx_force_16bpptextures) {
+        CHECK_FOR_FMT(A8R8G8B8, ConvLum16to32);
+      }
 
-    // IMPORTANT NOTE:
-    // target_bpp is REQUESTED bpp, not what exists in the texture array (the texture array contains cNumColorChannels*8bits)
+#ifndef FORCE_16bpp_1555
+      if (num_alpha_bits == 1)
+#endif
+        {
+          CHECK_FOR_FMT(A1R5G5B5, ConvLum16to16_1555);
+        }
 
-        case 32:
-            if(!((cNumColorChannels==3) || (cNumColorChannels==4)))
-                break; //bail
+      // normally prefer 4444 due to better alpha channel resolution
+      CHECK_FOR_FMT(A4R4G4B4, ConvLum16to16_4444);
+      CHECK_FOR_FMT(A1R5G5B5, ConvLum16to16_1555);
+    } else {
+      nassertr((num_color_channels == 3)||(num_color_channels == 4), false);
+      // look for compatible 16bit fmts, if none then give up
+      // (dont worry about other bitdepths for 16 bit)
+      switch(num_alpha_bits) {
+      case 0:
+        if (num_color_channels == 3) {
+          CHECK_FOR_FMT(R5G6B5, Conv24to16_0565);
+          CHECK_FOR_FMT(X1R5G5B5, Conv24to16_X555);
+        } else {
+          nassertr(num_color_channels == 4, false);
+          // it could be 4 if user asks us to throw away the alpha channel
+          CHECK_FOR_FMT(R5G6B5, Conv32to16_0565);
+          CHECK_FOR_FMT(X1R5G5B5, Conv32to16_X555);
+        }
+        break;
+      case 1:
+        // app specifically requests 1-5-5-5 F_rgba5 case, where you
+        // explicitly want 1-5-5-5 fmt, as opposed to F_rgbm, which
+        // could use 32bpp ARGB.  fail if this particular fmt not
+        // avail.
+        nassertr(num_color_channels == 4, false);
+        CHECK_FOR_FMT(X1R5G5B5, Conv32to16_X555);
+        break;
+      case 4:
+        // app specifically requests 4-4-4-4 F_rgba4 case, as opposed
+        // to F_rgba, which could use 32bpp ARGB
+        nassertr(num_color_channels == 4, false);
+        CHECK_FOR_FMT(A4R4G4B4, Conv32to16_4444);
+        break;
+      default:
+        nassertr(false, false);  // problem in get_bits_per_pixel()?
+      }
+    }
+  case 8:
+    if (needs_luminance) {
+      // dont bother handling those other 8bit lum fmts like 4-4,
+      // since 16 8-8 is usually supported too
+      nassertr(num_color_channels == 1, false);
+
+      // look for native lum fmt first
+      CHECK_FOR_FMT(L8, ConvLum8to8);
+      CHECK_FOR_FMT(L8, ConvLum8to16_A8L8);
+
+      if (!dx_force_16bpptextures) {
+        CHECK_FOR_FMT(R8G8B8, ConvLum8to24);
+        CHECK_FOR_FMT(X8R8G8B8, ConvLum8to32);
+      }
 
-            if(!dx_force_16bpptextures) {
-                if(cNumColorChannels==4) {
-                    CHECK_FOR_FMT(A8R8G8B8,Conv32to32);
-                } else {
-                    CHECK_FOR_FMT(A8R8G8B8,Conv24to32);
-                }
-            }
+      CHECK_FOR_FMT(R5G6B5, ConvLum8to16_0565);
+      CHECK_FOR_FMT(X1R5G5B5, ConvLum8to16_X555);
 
-            if(cNumAlphaBits>0) {
-                assert(cNumColorChannels==4);
+    } else if (num_alpha_bits == 8) {
+      // look for 16bpp A8L8, else 32-bit ARGB, else 16-4444.
 
-            // no 32-bit fmt, look for 16 bit w/alpha  (1-15)
+      // skip 8bit alpha only (D3DFMT_A8), because I think only voodoo
+      // supports it and the voodoo support isn't the kind of blending
+      // model we need somehow (is it that voodoo assumes color is
+      // white?  isnt that what we do in ConvAlpha8to32 anyway?)
 
-            // 32 bit RGBA was requested, but only 16 bit alpha fmts are avail
-            // by default, convert to 4-4-4-4 which has 4-bit alpha for blurry edges
-            // if we know tex only needs 1 bit alpha (i.e. for a mask), use 1555 instead
+      CHECK_FOR_FMT(A8L8, ConvAlpha8to16_A8L8);
 
-//                ConversionType ConvTo1=Conv32to16_4444,ConvTo2=Conv32to16_1555;
-//                DWORD dwAlphaMask1=0xF000,dwAlphaMask2=0x8000;
-            // assume ALPHAMASK is x8000 and RGBMASK is x7fff to simplify 32->16 conversion
-            // this should be true on most cards.
+      if (!dx_force_16bpptextures) {
+        CHECK_FOR_FMT(A8R8G8B8, ConvAlpha8to32);
+      }
 
-#ifndef FORCE_16bpp_1555
-                if(cNumAlphaBits==1)
-#endif
-                {
-                    CHECK_FOR_FMT(A1R5G5B5,Conv32to16_1555);
-                }
-
-                // normally prefer 4444 due to better alpha channel resolution
-                CHECK_FOR_FMT(A4R4G4B4,Conv32to16_4444);
-                CHECK_FOR_FMT(A1R5G5B5,Conv32to16_1555);
-
-                // at this point, bail.  dont worry about converting to non-alpha formats yet,
-                // I think this will be a very rare case
-                szErrorMsg = "CreateTexture failed: couldn't find compatible Tex DDPIXELFORMAT! no available 16 or 32-bit alpha formats!";
-            } else {
-                // convert 3 or 4 channel to closest 16bpp color fmt
-
-                if(cNumColorChannels==3) {
-                    CHECK_FOR_FMT(R5G6B5,Conv24to16_4444);
-                    CHECK_FOR_FMT(X1R5G5B5,Conv24to16_X555);
-                } else {
-                    CHECK_FOR_FMT(R5G6B5,Conv32to16_4444);
-                    CHECK_FOR_FMT(X1R5G5B5,Conv32to16_X555);
-                }
-            }
-            break;
-
-        case 24:
-            assert(cNumColorChannels==3);
-
-            if(!dx_force_16bpptextures) {
-                CHECK_FOR_FMT(R8G8B8,Conv24to24);
-
-                // no 24-bit fmt.  look for 32 bit fmt  (note: this is memory-hogging choice
-                // instead I could look for memory-conserving 16-bit fmt).
-
-                CHECK_FOR_FMT(X8R8G8B8,Conv24to32);
-            }
-
-             // no 24-bit or 32 fmt.  look for 16 bit fmt (higher res 565 1st)
-            CHECK_FOR_FMT(R5G6B5,Conv24to16_0565);
-            CHECK_FOR_FMT(X1R5G5B5,Conv24to16_X555);
-            break;
-
-        case 16:
-            if(bNeedLuminance) {
-                assert(cNumAlphaBits>0);
-                assert(cNumColorChannels==2);
-
-                CHECK_FOR_FMT(A8L8,ConvLum16to16);
-
-                if(!dx_force_16bpptextures) {
-                    CHECK_FOR_FMT(A8R8G8B8,ConvLum16to32);
-                }
-
-              #ifndef FORCE_16bpp_1555
-                if(cNumAlphaBits==1)
-              #endif
-                {
-                    CHECK_FOR_FMT(A1R5G5B5,ConvLum16to16_1555);
-                }
-
-                // normally prefer 4444 due to better alpha channel resolution
-                CHECK_FOR_FMT(A4R4G4B4,ConvLum16to16_4444);
-                CHECK_FOR_FMT(A1R5G5B5,ConvLum16to16_1555);
-            } else {
-               assert((cNumColorChannels==3)||(cNumColorChannels==4));
-          // look for compatible 16bit fmts, if none then give up
-          // (dont worry about other bitdepths for 16 bit)
-                switch(cNumAlphaBits) {
-                    case 0:
-                      if(cNumColorChannels==3) {
-                          CHECK_FOR_FMT(R5G6B5,Conv24to16_0565);
-                          CHECK_FOR_FMT(X1R5G5B5,Conv24to16_X555);
-                      } else {
-                          assert(cNumColorChannels==4);
-                        // it could be 4 if user asks us to throw away the alpha channel
-                          CHECK_FOR_FMT(R5G6B5,Conv32to16_0565);
-                          CHECK_FOR_FMT(X1R5G5B5,Conv32to16_X555);
-                      }
-                      break;
-                    case 1:
-                      // app specifically requests 1-5-5-5 F_rgba5 case, where you explicitly want 1-5-5-5 fmt, as opposed
-                      // to F_rgbm, which could use 32bpp ARGB.  fail if this particular fmt not avail.
-                      assert(cNumColorChannels==4);
-                      CHECK_FOR_FMT(X1R5G5B5,Conv32to16_X555);
-                      break;
-                    case 4:
-                      // app specifically requests 4-4-4-4 F_rgba4 case, as opposed to F_rgba, which could use 32bpp ARGB
-                      assert(cNumColorChannels==4);
-                      CHECK_FOR_FMT(A4R4G4B4,Conv32to16_4444);
-                      break;
-                    default: assert(0);  // problem in get_bits_per_pixel()?
-                }
-            }
-        case 8:
-            if(bNeedLuminance) {
-                // dont bother handling those other 8bit lum fmts like 4-4, since 16 8-8 is usually supported too
-                assert(cNumColorChannels==1);
-
-                // look for native lum fmt first
-                CHECK_FOR_FMT(L8,ConvLum8to8);
-                CHECK_FOR_FMT(L8,ConvLum8to16_A8L8);
-
-                if(!dx_force_16bpptextures) {
-                    CHECK_FOR_FMT(R8G8B8,ConvLum8to24);
-                    CHECK_FOR_FMT(X8R8G8B8,ConvLum8to32);
-                }
-
-                CHECK_FOR_FMT(R5G6B5,ConvLum8to16_0565);
-                CHECK_FOR_FMT(X1R5G5B5,ConvLum8to16_X555);
-
-            } else if(cNumAlphaBits==8) {
-                // look for 16bpp A8L8, else 32-bit ARGB, else 16-4444.
-
-                // skip 8bit alpha only (D3DFMT_A8), because I think only voodoo supports it
-                // and the voodoo support isn't the kind of blending model we need somehow
-                // (is it that voodoo assumes color is white?  isnt that what we do in ConvAlpha8to32 anyway?)
-
-                CHECK_FOR_FMT(A8L8,ConvAlpha8to16_A8L8);
-
-                if(!dx_force_16bpptextures) {
-                    CHECK_FOR_FMT(A8R8G8B8,ConvAlpha8to32);
-                }
-
-                CHECK_FOR_FMT(A4R4G4B4,ConvAlpha8to16_4444);
-            }
-            break;
-
-        default:
-            szErrorMsg = "CreateTexture failed: unhandled pixel bitdepth in DX loader";
+      CHECK_FOR_FMT(A4R4G4B4, ConvAlpha8to16_4444);
     }
+    break;
 
-    // if we've gotten here, haven't found a match
-    dxgsg9_cat.error() << szErrorMsg << ": " << _tex->get_name() << endl
-                      << "NumColorChannels: " <<cNumColorChannels << "; NumAlphaBits: " << cNumAlphaBits
-                      << "; targetbpp: " <<target_bpp << "; SupportedTexFmtsMask: 0x" << (void*)scrn.SupportedTexFmtsMask
-                      << "; NeedLuminance: " << bNeedLuminance << endl;
-    goto error_exit;
+  default:
+    error_message = "create_texture failed: unhandled pixel bitdepth in DX loader";
+  }
+
+  // if we've gotten here, haven't found a match
+  dxgsg9_cat.error()
+    << error_message << ": " << _texture->get_name() << endl
+    << "NumColorChannels: " << num_color_channels << "; NumAlphaBits: "
+    << num_alpha_bits << "; targetbpp: " <<target_bpp
+    << "; _supported_tex_formats_mask: 0x"
+    << (void*)scrn._supported_tex_formats_mask
+    << "; NeedLuminance: " << needs_luminance << endl;
+  goto error_exit;
 
-    ///////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////
 
  found_matching_format:
-    // We found a suitable format that matches the texture's format.
-
-    if (_texture->get_match_framebuffer_format()) {
-      // Instead of creating a texture with the found format, we will
-      // need to make one that exactly matches the framebuffer's
-      // format.  Look up what that format is.
-      IDirect3DSurface9 *pCurRenderTarget;
-      hr = scrn.pD3DDevice->GetRenderTarget(0, &pCurRenderTarget);
-      if(FAILED(hr)) {
-        dxgsg9_cat.error() << "GetRenderTgt failed in CreateTexture: " << D3DERRORSTRING(hr);
+  // We found a suitable format that matches the texture's format.
+
+  if (_texture->get_match_framebuffer_format()) {
+    // Instead of creating a texture with the found format, we will
+    // need to make one that exactly matches the framebuffer's
+    // format.  Look up what that format is.
+  DWORD render_target_index;
+    IDirect3DSurface9 *render_target;
+
+  render_target_index = 0;
+    hr = scrn._d3d_device->GetRenderTarget(render_target_index, &render_target);
+    if (FAILED(hr)) {
+      dxgsg9_cat.error()
+        << "GetRenderTgt failed in create_texture: " << D3DERRORSTRING(hr);
+    } else {
+      D3DSURFACE_DESC surface_desc;
+      hr = render_target->GetDesc(&surface_desc);
+      if (FAILED(hr)) {
+        dxgsg9_cat.error()
+          << "GetDesc failed in create_texture: " << D3DERRORSTRING(hr);
       } else {
-        D3DSURFACE_DESC SurfDesc;
-        hr = pCurRenderTarget->GetDesc(&SurfDesc);    
-        if (FAILED(hr)) {
-          dxgsg9_cat.error()
-            << "GetDesc failed in CreateTexture: " << D3DERRORSTRING(hr);
-        } else {
-          if (TargetPixFmt != SurfDesc.Format) {
-            if (dxgsg9_cat.is_debug()) {
-              dxgsg9_cat.debug()
-                << "Chose format " << D3DFormatStr(SurfDesc.Format)
-                << " instead of " << D3DFormatStr(TargetPixFmt) 
-                << " for texture to match framebuffer.\n";
-            }
-            TargetPixFmt = SurfDesc.Format;
+        if (target_pixel_format != surface_desc.Format) {
+          if (dxgsg9_cat.is_debug()) {
+            dxgsg9_cat.debug()
+              << "Chose format " << D3DFormatStr(surface_desc.Format)
+              << " instead of " << D3DFormatStr(target_pixel_format)
+              << " for texture to match framebuffer.\n";
           }
+          target_pixel_format = surface_desc.Format;
         }
-        SAFE_RELEASE(pCurRenderTarget);
       }
-    }        
+      SAFE_RELEASE(render_target);
+    }
+  }
 
-    // validate magfilter setting
-    // degrade filtering if no HW support
+  // validate magfilter setting
+  // degrade filtering if no HW support
 
-    Texture::FilterType ft;
+  Texture::FilterType ft;
 
-    ft =_tex->get_magfilter();
-    if((ft!=Texture::FT_linear) && ft!=Texture::FT_nearest) {
+  ft = _texture->get_magfilter();
+  if ((ft != Texture::FT_linear) && ft != Texture::FT_nearest) {
     // mipmap settings make no sense for magfilter
-        if(ft==Texture::FT_nearest_mipmap_nearest)
-            ft=Texture::FT_nearest;
-        else ft=Texture::FT_linear;
+    if (ft == Texture::FT_nearest_mipmap_nearest) {
+      ft = Texture::FT_nearest;
+    } else {
+      ft = Texture::FT_linear;
     }
+  }
 
-    if((ft==Texture::FT_linear) && !(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR))
-        ft=Texture::FT_nearest;
-    _tex->set_magfilter(ft);
-
-    // figure out if we are mipmapping this texture
-    ft =_tex->get_minfilter();
-    _bHasMipMaps=FALSE;
-
-    if(!dx_ignore_mipmaps) {  // set if no HW mipmap capable
-        switch(ft) {
-            case Texture::FT_nearest_mipmap_nearest:
-            case Texture::FT_linear_mipmap_nearest:
-            case Texture::FT_nearest_mipmap_linear:  // pick nearest in each, interpolate linearly b/w them
-            case Texture::FT_linear_mipmap_linear:
-                _bHasMipMaps=TRUE;
-        }
+  if (ft == Texture::FT_linear &&
+      (filter_caps & D3DPTFILTERCAPS_MAGFLINEAR) == 0) {
+    ft = Texture::FT_nearest;
+  }
+  _texture->set_magfilter(ft);
 
-        if(dx_mipmap_everything) {  // debug toggle, ok to leave in since its just a creation cost
-           _bHasMipMaps=TRUE;
-           if(dxgsg9_cat.is_spam()) {
-               if(ft != Texture::FT_linear_mipmap_linear)
-                   dxgsg9_cat.spam() << "Forcing trilinear mipmapping on DX texture [" << _tex->get_name() << "]\n";
-           }
-           ft = Texture::FT_linear_mipmap_linear;
-           _tex->set_minfilter(ft);
+  // figure out if we are mipmapping this texture
+  ft = _texture->get_minfilter();
+  _has_mipmaps = false;
+
+  if (!dx_ignore_mipmaps) {  // set if no HW mipmap capable
+    switch(ft) {
+    case Texture::FT_nearest_mipmap_nearest:
+    case Texture::FT_linear_mipmap_nearest:
+    case Texture::FT_nearest_mipmap_linear:  // pick nearest in each, interpolate linearly b/w them
+    case Texture::FT_linear_mipmap_linear:
+      _has_mipmaps = true;
+    }
+
+    if (dx_mipmap_everything) {  // debug toggle, ok to leave in since its just a creation cost
+      _has_mipmaps = true;
+      if (dxgsg9_cat.is_spam()) {
+        if (ft != Texture::FT_linear_mipmap_linear) {
+          dxgsg9_cat.spam()
+            << "Forcing trilinear mipmapping on DX texture ["
+            << _texture->get_name() << "]\n";
         }
-    } else if((ft==Texture::FT_nearest_mipmap_nearest) ||   // cvt to no-mipmap filter types
-              (ft==Texture::FT_nearest_mipmap_linear)) {
-        ft=Texture::FT_nearest;
-    } else if((ft==Texture::FT_linear_mipmap_nearest) ||
-              (ft==Texture::FT_linear_mipmap_linear)) {
-        ft=Texture::FT_linear;
+      }
+      ft = Texture::FT_linear_mipmap_linear;
+      _texture->set_minfilter(ft);
     }
 
-    assert((scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFPOINT)!=0);
+  } else if ((ft == Texture::FT_nearest_mipmap_nearest) ||   // cvt to no-mipmap filter types
+             (ft == Texture::FT_nearest_mipmap_linear)) {
+    ft = Texture::FT_nearest;
+
+  } else if ((ft == Texture::FT_linear_mipmap_nearest) ||
+            (ft == Texture::FT_linear_mipmap_linear)) {
+    ft = Texture::FT_linear;
+  }
+
+  nassertr((filter_caps & D3DPTFILTERCAPS_MINFPOINT) != 0, false);
 
 #define TRILINEAR_MIPMAP_TEXFILTERCAPS (D3DPTFILTERCAPS_MIPFLINEAR | D3DPTFILTERCAPS_MINFLINEAR)
 
-    // do any other filter type degradations necessary
-    switch(ft) {
-        case Texture::FT_linear_mipmap_linear:
-            if((scrn.d3dcaps.TextureFilterCaps & TRILINEAR_MIPMAP_TEXFILTERCAPS)!=TRILINEAR_MIPMAP_TEXFILTERCAPS) {
-               if(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR)
-                   ft=Texture::FT_linear_mipmap_nearest;
-                else ft=Texture::FT_nearest_mipmap_nearest;  // if you cant do linear in a level, you probably cant do linear b/w levels, so just do nearest-all
-            }
-            break;
-        case Texture::FT_nearest_mipmap_linear:
-            // if we dont have bilinear, do nearest_nearest
-            if(!((scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFPOINT) &&
-                 (scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR)))
-                ft=Texture::FT_nearest_mipmap_nearest;
-            break;
-        case Texture::FT_linear_mipmap_nearest:
-            // if we dont have mip linear, do nearest_nearest
-            if(!(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR))
-                ft=Texture::FT_nearest_mipmap_nearest;
-            break;
-        case Texture::FT_linear:
-            if(!(scrn.d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR))
-                ft=Texture::FT_nearest;
-            break;
+  // do any other filter type degradations necessary
+  switch(ft) {
+  case Texture::FT_linear_mipmap_linear:
+    if ((filter_caps & TRILINEAR_MIPMAP_TEXFILTERCAPS) != TRILINEAR_MIPMAP_TEXFILTERCAPS) {
+      if (filter_caps & D3DPTFILTERCAPS_MINFLINEAR) {
+        ft = Texture::FT_linear_mipmap_nearest;
+      } else {
+        // if you cant do linear in a level, you probably cant do
+        // linear b/w levels, so just do nearest-all
+        ft = Texture::FT_nearest_mipmap_nearest;
+      }
     }
+    break;
 
-    _tex->set_minfilter(ft);
+  case Texture::FT_nearest_mipmap_linear:
+    // if we dont have bilinear, do nearest_nearest
+    if (!((filter_caps & D3DPTFILTERCAPS_MIPFPOINT) &&
+          (filter_caps & D3DPTFILTERCAPS_MINFLINEAR))) {
+      ft = Texture::FT_nearest_mipmap_nearest;
+    }
+    break;
 
-    uint aniso_degree;
+  case Texture::FT_linear_mipmap_nearest:
+    // if we dont have mip linear, do nearest_nearest
+    if (!(filter_caps & D3DPTFILTERCAPS_MIPFLINEAR)) {
+      ft = Texture::FT_nearest_mipmap_nearest;
+    }
+    break;
 
-    aniso_degree=1;
-    if(scrn.d3dcaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) {
-        aniso_degree=_tex->get_anisotropic_degree();
-        if((aniso_degree>scrn.d3dcaps.MaxAnisotropy) || dx_force_anisotropic_filtering)
-            aniso_degree=scrn.d3dcaps.MaxAnisotropy;
+  case Texture::FT_linear:
+    if (!(filter_caps & D3DPTFILTERCAPS_MINFLINEAR)) {
+      ft = Texture::FT_nearest;
     }
-    _tex->set_anisotropic_degree(aniso_degree);
+    break;
+  }
+
+  _texture->set_minfilter(ft);
+
+  uint aniso_degree;
+
+  aniso_degree = 1;
+  if (scrn._d3dcaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) {
+    aniso_degree = _texture->get_anisotropic_degree();
+    if ((aniso_degree>scrn._d3dcaps.MaxAnisotropy) ||
+        dx_force_anisotropic_filtering) {
+      aniso_degree = scrn._d3dcaps.MaxAnisotropy;
+    }
+  }
+  _texture->set_anisotropic_degree(aniso_degree);
 
 #ifdef _DEBUG
-    dxgsg9_cat.spam() << "CreateTexture: setting aniso degree for "<< _tex->get_name() << " to: " << aniso_degree << endl;
+  dxgsg9_cat.spam()
+    << "create_texture: setting aniso degree for " << _texture->get_name()
+    << " to: " << aniso_degree << endl;
 #endif
 
-    UINT cMipLevelCount;
-
-    if(_bHasMipMaps) {
-        cMipLevelCount=0;  // tell CreateTex to alloc space for all mip levels down to 1x1
+  UINT mip_level_count;
 
-        if(dxgsg9_cat.is_debug())
-            dxgsg9_cat.debug() << "CreateTexture: generating mipmaps for "<< _tex->get_name() << endl;
-    } else cMipLevelCount=1;
+  if (_has_mipmaps) {
+    // tell CreateTex to alloc space for all mip levels down to 1x1
+    mip_level_count = 0;
 
-    if(FAILED( hr = scrn.pD3DDevice->CreateTexture(TargetWidth,TargetHeight,cMipLevelCount,0x0,
-                                                   TargetPixFmt,D3DPOOL_MANAGED,&_pD3DTexture9, NULL) )) {
-        dxgsg9_cat.error() << "D3D CreateTexture failed!" << D3DERRORSTRING(hr);
-        goto error_exit;
+    if (dxgsg9_cat.is_debug()) {
+      dxgsg9_cat.debug()
+        << "create_texture: generating mipmaps for " << _texture->get_name()
+        << endl;
     }
+  } else {
+    mip_level_count = 1;
+  }
+
+  switch (_texture->get_texture_type()) {
+  case Texture::TT_1d_texture:
+  case Texture::TT_2d_texture:
+    hr = scrn._d3d_device->CreateTexture
+      (target_width, target_height, mip_level_count, 0x0,
+       target_pixel_format, D3DPOOL_MANAGED, &_d3d_2d_texture, NULL);
+    _d3d_texture = _d3d_2d_texture;
+    break;
+
+  case Texture::TT_3d_texture:
+    hr = scrn._d3d_device->CreateVolumeTexture
+      (target_width, target_height, target_depth, mip_level_count, 0x0,
+       target_pixel_format, D3DPOOL_MANAGED, &_d3d_volume_texture, NULL);
+    _d3d_texture = _d3d_volume_texture;
+    break;
+
+  case Texture::TT_cube_map:
+    hr = scrn._d3d_device->CreateCubeTexture
+      (target_width, mip_level_count, 0x0,
+       target_pixel_format, D3DPOOL_MANAGED, &_d3d_cube_texture, NULL);
+    _d3d_texture = _d3d_cube_texture;
+    break;
+  }
+
+  if (FAILED(hr)) {
+    dxgsg9_cat.error()
+      << "D3D create_texture failed!" << D3DERRORSTRING(hr);
+    goto error_exit;
+  }
 
-    if (dxgsg9_cat.is_debug()) {
-      dxgsg9_cat.debug() << "CreateTexture: "<< _tex->get_name() <<" converting panda equivalent of " << D3DFormatStr(_PixBufD3DFmt) << " => " << D3DFormatStr(TargetPixFmt) << endl;
+  if (dxgsg9_cat.is_debug()) {
+    dxgsg9_cat.debug()
+      << "create_texture: " << _texture->get_name()
+      << " converting panda equivalent of " << D3DFormatStr(_d3d_format)
+      << " => " << D3DFormatStr(target_pixel_format) << endl;
+  }
+
+  hr = fill_d3d_texture_pixels();
+  if (FAILED(hr)) {
+    goto error_exit;
+  }
+
+  // PRINT_REFCNT(dxgsg9, scrn._d3d9);
+
+  return true;
+
+ error_exit:
+
+  RELEASE(_d3d_texture, dxgsg9, "texture", RELEASE_ONCE);
+  _d3d_2d_texture = NULL;
+  _d3d_volume_texture = NULL;
+  _d3d_cube_texture = NULL;
+  return false;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXTextureContext9::delete_texture
+//       Access: Public
+//  Description: Release the surface used to store the texture
+////////////////////////////////////////////////////////////////////
+void DXTextureContext9::
+delete_texture() {
+  if (_d3d_texture == NULL) {
+    // dont bother printing the msg below, since we already released it.
+    return;
+  }
+
+  RELEASE(_d3d_texture, dxgsg9, "texture", RELEASE_ONCE);
+  _d3d_2d_texture = NULL;
+  _d3d_volume_texture = NULL;
+  _d3d_cube_texture = NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXTextureContext9::d3d_surface_to_texture
+//       Access: Public, Static
+//  Description: copies source_rect in pD3DSurf to upper left of
+//               texture
+////////////////////////////////////////////////////////////////////
+HRESULT DXTextureContext9::
+d3d_surface_to_texture(RECT &source_rect, IDirect3DSurface9 *d3d_surface,
+           bool inverted, Texture *result, int z) {
+  // still need custom conversion since d3d/d3dx has no way to convert
+  // arbitrary fmt to ARGB in-memory user buffer
+
+  HRESULT hr;
+  DWORD num_components = result->get_num_components();
+
+  nassertr(result->get_component_width() == sizeof(BYTE), E_FAIL);   // cant handle anything else now
+  nassertr(result->get_component_type() == Texture::T_unsigned_byte, E_FAIL);   // cant handle anything else now
+  nassertr((num_components == 3) || (num_components == 4), E_FAIL);  // cant handle anything else now
+  nassertr(IS_VALID_PTR(d3d_surface), E_FAIL);
+
+  BYTE *buf = result->modify_ram_image();
+  if (z >= 0) {
+    nassertr(z < result->get_z_size(), E_FAIL);
+    buf += z * result->get_expected_ram_page_size();
+  }
+
+  if (IsBadWritePtr(d3d_surface, sizeof(DWORD))) {
+    dxgsg9_cat.error()
+      << "d3d_surface_to_texture failed: bad pD3DSurf ptr value ("
+      << ((void*)d3d_surface) << ")\n";
+    exit(1);
+  }
+
+  DWORD x_window_offset, y_window_offset;
+  DWORD copy_width, copy_height;
+
+  D3DLOCKED_RECT locked_rect;
+  D3DSURFACE_DESC surface_desc;
+
+  hr = d3d_surface->GetDesc(&surface_desc);
+
+  x_window_offset = source_rect.left, y_window_offset = source_rect.top;
+  copy_width = RECT_XSIZE(source_rect);
+  copy_height = RECT_YSIZE(source_rect);
+
+  // make sure there's enough space in the texture, its size must
+  // match (especially xsize) or scanlines will be too long
+
+  if (!((copy_width == result->get_x_size()) && (copy_height <= (DWORD)result->get_y_size()))) {
+    dxgsg9_cat.error()
+      << "d3d_surface_to_texture, Texture size (" << result->get_x_size()
+      << ", " << result->get_y_size()
+      << ") too small to hold display surface ("
+      << copy_width << ", " << copy_height << ")\n";
+    nassertr(false, E_FAIL);
+    return E_FAIL;
+  }
+
+  hr = d3d_surface->LockRect(&locked_rect, (CONST RECT*)NULL, (D3DLOCK_READONLY | D3DLOCK_NO_DIRTY_UPDATE));
+  if (FAILED(hr)) {
+    dxgsg9_cat.error()
+      << "d3d_surface_to_texture LockRect() failed!" << D3DERRORSTRING(hr);
+    return hr;
+  }
+
+  // ones not listed not handled yet
+  nassertr((surface_desc.Format == D3DFMT_A8R8G8B8) ||
+           (surface_desc.Format == D3DFMT_X8R8G8B8) ||
+           (surface_desc.Format == D3DFMT_R8G8B8) ||
+           (surface_desc.Format == D3DFMT_R5G6B5) ||
+           (surface_desc.Format == D3DFMT_X1R5G5B5) ||
+           (surface_desc.Format == D3DFMT_A1R5G5B5) ||
+           (surface_desc.Format == D3DFMT_A4R4G4B4), E_FAIL);
+
+  //buf contains raw ARGB in Texture byteorder
+
+  int byte_pitch = locked_rect.Pitch;
+  BYTE *surface_bytes = (BYTE *)locked_rect.pBits;
+
+  if (inverted) {
+    surface_bytes += byte_pitch * (y_window_offset + copy_height - 1);
+    byte_pitch = -byte_pitch;
+  } else {
+    surface_bytes += byte_pitch * y_window_offset;
+  }
+
+  // writes out last line in DDSurf first in PixelBuf, so Y line order
+  // precedes inversely
+
+  if (dxgsg9_cat.is_debug()) {
+    dxgsg9_cat.debug()
+      << "d3d_surface_to_texture converting "
+      << D3DFormatStr(surface_desc.Format)
+      << " DDSurf to " <<  num_components << "-channel panda Texture\n";
+  }
+
+  DWORD *dest_word = (DWORD *)buf;
+  BYTE *dest_byte = (BYTE *)buf;
+
+  switch(surface_desc.Format) {
+  case D3DFMT_A8R8G8B8:
+  case D3DFMT_X8R8G8B8: {
+    if (num_components == 4) {
+      DWORD *source_word;
+      BYTE *dest_line = (BYTE*)dest_word;
+
+      for (DWORD y = 0; y < copy_height; y++) {
+        source_word = ((DWORD*)surface_bytes) + x_window_offset;
+        memcpy(dest_line, source_word, byte_pitch);
+        dest_line += byte_pitch;
+  surface_bytes += byte_pitch;
+      }
+    } else {
+      // 24bpp texture case (numComponents == 3)
+      DWORD *source_word;
+      for (DWORD y = 0; y < copy_height; y++) {
+        source_word = ((DWORD*)surface_bytes) + x_window_offset;
+
+        for (DWORD x = 0; x < copy_width; x++) {
+          BYTE r, g, b;
+          DWORD pixel = *source_word;
+
+          r = (BYTE)((pixel>>16) & g_LowByteMask);
+          g = (BYTE)((pixel>> 8) & g_LowByteMask);
+          b = (BYTE)((pixel    ) & g_LowByteMask);
+
+          *dest_byte++ = b;
+          *dest_byte++ = g;
+          *dest_byte++ = r;
+    source_word++;
+        }
+  surface_bytes += byte_pitch;
+      }
     }
+    break;
+  }
+
+  case D3DFMT_R8G8B8: {
+    BYTE *source_byte;
 
-    hr = FillDDSurfTexturePixels();
-    if(FAILED(hr)) {
-      goto error_exit;
+    if (num_components == 4) {
+      for (DWORD y = 0; y < copy_height; y++) {
+        source_byte = surface_bytes + x_window_offset * 3 * sizeof(BYTE);
+        for (DWORD x = 0; x < copy_width; x++) {
+          DWORD r, g, b;
+
+          b = *source_byte++;
+          g = *source_byte++;
+          r = *source_byte++;
+
+          *dest_word = 0xFF000000 | (r << 16) | (g << 8) | b;
+    dest_word++;
+        }
+  surface_bytes += byte_pitch;
+      }
+    } else {
+      // 24bpp texture case (numComponents == 3)
+      for (DWORD y = 0; y < copy_height; y++) {
+        source_byte = surface_bytes + x_window_offset * 3 * sizeof(BYTE);
+        memcpy(dest_byte, source_byte, byte_pitch);
+        dest_byte += byte_pitch;
+  surface_bytes += byte_pitch;
+      }
+    }
+    break;
+  }
+
+  case D3DFMT_R5G6B5:
+  case D3DFMT_X1R5G5B5:
+  case D3DFMT_A1R5G5B5:
+  case D3DFMT_A4R4G4B4: {
+    WORD  *source_word;
+    // handle 0555, 1555, 0565, 4444 in same loop
+
+    BYTE redshift, greenshift, blueshift;
+    DWORD redmask, greenmask, bluemask;
+
+    if (surface_desc.Format == D3DFMT_R5G6B5) {
+      redshift = (11-3);
+      redmask = 0xF800;
+      greenmask = 0x07E0;
+      greenshift = (5-2);
+      bluemask = 0x001F;
+      blueshift = 3;
+    } else if (surface_desc.Format == D3DFMT_A4R4G4B4) {
+      redmask = 0x0F00;
+      redshift = 4;
+      greenmask = 0x00F0;
+      greenshift = 0;
+      bluemask = 0x000F;
+      blueshift = 4;
+    } else {  // 1555 or x555
+      redmask = 0x7C00;
+      redshift = (10-3);
+      greenmask = 0x03E0;
+      greenshift = (5-3);
+      bluemask = 0x001F;
+      blueshift = 3;
     }
 
-    // PRINT_REFCNT(dxgsg9,scrn.pD3D9);
+    if (num_components == 4) {
+      // Note: these 16bpp loops ignore input alpha completely (alpha
+      // is set to fully opaque in texture!)
 
-    // Return the newly created texture
-    return _pD3DTexture9;
+      // if we need to capture alpha, probably need to make separate
+      // loops for diff 16bpp fmts for best speed
 
-  error_exit:
+      for (DWORD y = 0; y < copy_height; y++) {
+        source_word = ((WORD*)surface_bytes) + x_window_offset;
+        for (DWORD x = 0; x < copy_width; x++) {
+          WORD pixel = *source_word;
+          BYTE r, g, b;
 
-    RELEASE(_pD3DTexture9,dxgsg9,"texture",RELEASE_ONCE);
-    return NULL;
+          b = (pixel & bluemask) << blueshift;
+          g = (pixel & greenmask) >> greenshift;
+          r = (pixel & redmask) >> redshift;
+
+          // alpha is just set to 0xFF
+
+          *dest_word = 0xFF000000 | (r << 16) | (g << 8) | b;
+    source_word++;
+    dest_word++;
+        }
+  surface_bytes += byte_pitch;
+      }
+    } else {
+      // 24bpp texture case (numComponents == 3)
+      for (DWORD y = 0; y < copy_height; y++) {
+        source_word = ((WORD*)surface_bytes) + x_window_offset;
+        for (DWORD x = 0; x < copy_width; x++) {
+          WORD pixel = *source_word;
+          BYTE r, g, b;
+
+          b = (pixel & bluemask) << blueshift;
+          g = (pixel & greenmask) >> greenshift;
+          r = (pixel & redmask) >> redshift;
+
+          *dest_byte += b;
+          *dest_byte += g;
+          *dest_byte += r;
+    source_word++;
+        }
+  surface_bytes += byte_pitch;
+      }
+    }
+    break;
+  }
+
+  default:
+    dxgsg9_cat.error()
+      << "d3d_surface_to_texture: unsupported D3DFORMAT!\n";
+  }
+
+  d3d_surface->UnlockRect();
+  return S_OK;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: DXTextureContext9::fill_d3d_texture_pixels
+//       Access: Private
+//  Description:
+////////////////////////////////////////////////////////////////////
 HRESULT DXTextureContext9::
-FillDDSurfTexturePixels() {
-    HRESULT hr=E_FAIL;
-    assert(IS_VALID_PTR(_texture));
-
-    CPTA_uchar image = _texture->get_ram_image();
-    if (image.is_null()) {
-      // The texture doesn't have an image to load.  That's ok; it
-      // might be a texture we've rendered to by frame buffer
-      // operations or something.
-      return S_OK;
-    }
+fill_d3d_texture_pixels() {
+  if (_texture->get_texture_type() == Texture::TT_3d_texture) {
+    return fill_d3d_volume_texture_pixels();
+  }
+
+  HRESULT hr = E_FAIL;
+  nassertr(IS_VALID_PTR(_texture), E_FAIL);
+
+  CPTA_uchar image = _texture->get_ram_image();
+  if (image.is_null()) {
+    // The texture doesn't have an image to load.  That's ok; it
+    // might be a texture we've rendered to by frame buffer
+    // operations or something.
+    return S_OK;
+  }
 
-    assert(IS_VALID_PTR(_pD3DTexture9));
+  PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
 
-    DWORD OrigWidth  = (DWORD) _texture->get_x_size();
-    DWORD OrigHeight = (DWORD) _texture->get_y_size();
-    DWORD cNumColorChannels = _texture->get_num_components();
-    D3DFORMAT SrcFormat=_PixBufD3DFmt;
-    BYTE *pPixels=(BYTE*)image.p();
-    int component_width = _texture->get_component_width();
+  nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
 
-    assert(IS_VALID_PTR(pPixels));
+  DWORD orig_width  = (DWORD) _texture->get_x_size();
+  DWORD orig_height = (DWORD) _texture->get_y_size();
+  DWORD orig_depth = (DWORD) _texture->get_z_size();
+  DWORD num_color_channels = _texture->get_num_components();
+  D3DFORMAT source_format = _d3d_format;
+  BYTE *image_pixels = (BYTE*)image.p();
+  int component_width = _texture->get_component_width();
 
-    IDirect3DSurface9 *pMipLevel0;
-    hr=_pD3DTexture9->GetSurfaceLevel(0,&pMipLevel0);
-    if(FAILED(hr)) {
-       dxgsg9_cat.error() << "FillDDSurfaceTexturePixels failed for "<< _tex->get_name() <<", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
-       return E_FAIL;
+  nassertr(IS_VALID_PTR(image_pixels), E_FAIL);
+
+  IDirect3DSurface9 *mip_level_0 = NULL;
+  bool using_temp_buffer = false;
+  BYTE *pixels = NULL;
+
+  for (unsigned int di = 0; di < orig_depth; di++) {
+    pixels = image_pixels + di * _texture->get_expected_ram_page_size();
+    mip_level_0 = NULL;
+
+    if (_texture->get_texture_type() == Texture::TT_cube_map) {
+      nassertr(IS_VALID_PTR(_d3d_cube_texture), E_FAIL);
+      hr = _d3d_cube_texture->GetCubeMapSurface((D3DCUBEMAP_FACES)di, 0, &mip_level_0);
+    } else {
+      nassertr(IS_VALID_PTR(_d3d_2d_texture), E_FAIL);
+      hr = _d3d_2d_texture->GetSurfaceLevel(0, &mip_level_0);
     }
 
-    RECT SrcSize;
-    SrcSize.left = SrcSize.top = 0;
-    SrcSize.right = OrigWidth;
-    SrcSize.bottom = OrigHeight;
+    if (FAILED(hr)) {
+      dxgsg9_cat.error()
+        << "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
+      << ", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
+      return E_FAIL;
+    }
+
+    RECT source_size;
+    source_size.left = source_size.top = 0;
+    source_size.right = orig_width;
+    source_size.bottom = orig_height;
 
-    UINT SrcPixBufRowByteLength=OrigWidth*cNumColorChannels;
+    UINT source_row_byte_length = orig_width * num_color_channels;
 
-    DWORD Lev0Filter,MipFilterFlags;
-    bool bUsingTempPixBuf=false;
+    DWORD level_0_filter, mip_filter_flags;
+    using_temp_buffer = false;
 
-    // need filtering if size changes, (also if bitdepth reduced (need dithering)??)
-    Lev0Filter = D3DX_FILTER_LINEAR ; //| D3DX_FILTER_DITHER;  //dithering looks ugly on i810 for 4444 textures
+    // need filtering if size changes, (also if bitdepth reduced (need
+    // dithering)??)
+    level_0_filter = D3DX_FILTER_LINEAR ; //| D3DX_FILTER_DITHER;  //dithering looks ugly on i810 for 4444 textures
 
-    // D3DXLoadSurfaceFromMemory will load black luminance and we want full white,
-    // so convert to explicit luminance-alpha format
-    if (_PixBufD3DFmt==D3DFMT_A8) {
+    // D3DXLoadSurfaceFromMemory will load black luminance and we want
+    // full white, so convert to explicit luminance-alpha format
+    if (_d3d_format == D3DFMT_A8) {
       // alloc buffer for explicit D3DFMT_A8L8
-      USHORT *pTempPixBuf=new USHORT[OrigWidth*OrigHeight];
-      if(!IS_VALID_PTR(pTempPixBuf)) {
-        dxgsg9_cat.error() << "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
+      USHORT *temp_buffer = new USHORT[orig_width * orig_height];
+      if (!IS_VALID_PTR(temp_buffer)) {
+        dxgsg9_cat.error()
+          << "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
         goto exit_FillDDSurf;
       }
-      bUsingTempPixBuf=true;
-      
-      USHORT *pOutPix=pTempPixBuf;
-      BYTE *pSrcPix=pPixels + component_width - 1;
-      for (UINT y = 0; y < OrigHeight; y++) {
-        for (UINT x = 0; 
-             x < OrigWidth; 
-             x++, pSrcPix += component_width, pOutPix++) {
+      using_temp_buffer = true;
+
+      USHORT *out_pixels = temp_buffer;
+      BYTE *source_pixels = pixels + component_width - 1;
+      for (UINT y = 0; y < orig_height; y++) {
+        for (UINT x = 0;
+             x < orig_width;
+             x++, source_pixels += component_width, out_pixels++) {
           // add full white, which is our interpretation of alpha-only
           // (similar to default adding full opaque alpha 0xFF to
           // RGB-only textures)
-          *pOutPix = ((*pSrcPix) << 8 ) | 0xFF;
+          *out_pixels = ((*source_pixels) << 8 ) | 0xFF;
         }
       }
-      
-      SrcFormat=D3DFMT_A8L8;
-      SrcPixBufRowByteLength=OrigWidth*sizeof(USHORT);
-      pPixels=(BYTE*)pTempPixBuf;
-      
+
+      source_format = D3DFMT_A8L8;
+      source_row_byte_length = orig_width * sizeof(USHORT);
+      pixels = (BYTE*)temp_buffer;
+
     } else if (component_width != 1) {
       // Convert from 16-bit per channel (or larger) format down to
       // 8-bit per channel.  This throws away precision in the
-      // original image.  dx9 does support some of these
-      // high-precision formats, but we don't right now.
+      // original image, but dx8 doesn't support high-precision images
+      // anyway.
 
       int num_components = _texture->get_num_components();
-      int num_pixels = OrigWidth * OrigHeight * num_components;
-      BYTE *pTempPixBuf = new BYTE[num_pixels];
-      if(!IS_VALID_PTR(pTempPixBuf)) {
+      int num_pixels = orig_width * orig_height * num_components;
+      BYTE *temp_buffer = new BYTE[num_pixels];
+      if (!IS_VALID_PTR(temp_buffer)) {
         dxgsg9_cat.error() << "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
         goto exit_FillDDSurf;
       }
-      bUsingTempPixBuf=true;
+      using_temp_buffer = true;
 
-      BYTE *pSrcPix = pPixels + component_width - 1;
+      BYTE *source_pixels = pixels + component_width - 1;
       for (int i = 0; i < num_pixels; i++) {
-        pTempPixBuf[i] = *pSrcPix;
-        pSrcPix += component_width;
+        temp_buffer[i] = *source_pixels;
+        source_pixels += component_width;
       }
-      pPixels=(BYTE*)pTempPixBuf;
+      pixels = (BYTE*)temp_buffer;
     }
 
 
-    // filtering may be done here if texture if targetsize!=origsize
-    hr=D3DXLoadSurfaceFromMemory(pMipLevel0,(PALETTEENTRY*)NULL,(RECT*)NULL,(LPCVOID)pPixels,SrcFormat,
-                                 SrcPixBufRowByteLength,(PALETTEENTRY*)NULL,&SrcSize,Lev0Filter,(D3DCOLOR)0x0);
-    if(FAILED(hr)) {
-      dxgsg9_cat.error() << "FillDDSurfaceTexturePixels failed for "<< _tex->get_name() <<", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
+    // filtering may be done here if texture if targetsize != origsize
+#ifdef DO_PSTATS
+    GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_row_byte_length * orig_height);
+#endif
+    hr = D3DXLoadSurfaceFromMemory
+      (mip_level_0, (PALETTEENTRY*)NULL, (RECT*)NULL, (LPCVOID)pixels,
+       source_format, source_row_byte_length, (PALETTEENTRY*)NULL,
+       &source_size, level_0_filter, (D3DCOLOR)0x0);
+    if (FAILED(hr)) {
+      dxgsg9_cat.error()
+        << "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
+        << ", D3DXLoadSurfFromMem failed" << D3DERRORSTRING(hr);
       goto exit_FillDDSurf;
     }
 
-    if(_bHasMipMaps) {
-      if(!dx_use_triangle_mipgen_filter)
-        MipFilterFlags = D3DX_FILTER_BOX;
-      else MipFilterFlags = D3DX_FILTER_TRIANGLE;
-      
-      //    MipFilterFlags|= D3DX_FILTER_DITHER;
-      
-      hr=D3DXFilterTexture(_pD3DTexture9,(PALETTEENTRY*)NULL,0,MipFilterFlags);
-      if(FAILED(hr)) {
-        dxgsg9_cat.error() << "FillDDSurfaceTexturePixels failed for "<< _tex->get_name() <<", D3DXFilterTex failed" << D3DERRORSTRING(hr);
+    if (_has_mipmaps) {
+      if (!dx_use_triangle_mipgen_filter) {
+        mip_filter_flags = D3DX_FILTER_BOX;
+      } else {
+        mip_filter_flags = D3DX_FILTER_TRIANGLE;
+      }
+
+      //    mip_filter_flags| = D3DX_FILTER_DITHER;
+
+      hr = D3DXFilterTexture(_d3d_texture, (PALETTEENTRY*)NULL, 0,
+                             mip_filter_flags);
+      if (FAILED(hr)) {
+        dxgsg9_cat.error()
+          << "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
+          << ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
         goto exit_FillDDSurf;
       }
     }
+    if (using_temp_buffer) {
+      SAFE_DELETE_ARRAY(pixels);
+    }
+    RELEASE(mip_level_0, dxgsg9, "FillDDSurf MipLev0 texture ptr", RELEASE_ONCE);
+  }
+  return hr;
 
  exit_FillDDSurf:
-    if(bUsingTempPixBuf) {
-      SAFE_DELETE_ARRAY(pPixels);
-    }
-    RELEASE(pMipLevel0,dxgsg9,"FillDDSurf MipLev0 texture ptr",RELEASE_ONCE);
-    return hr;
+  if (using_temp_buffer) {
+    SAFE_DELETE_ARRAY(pixels);
+  }
+  RELEASE(mip_level_0, dxgsg9, "FillDDSurf MipLev0 texture ptr", RELEASE_ONCE);
+  return hr;
 }
 
-//-----------------------------------------------------------------------------
-// Name: DeleteTexture()
-// Desc: Release the surface used to store the texture
-//-----------------------------------------------------------------------------
-void DXTextureContext9::
-DeleteTexture( ) {
-    if(_pD3DTexture9==NULL) {
-        // dont bother printing the msg below, since we already released it.
-        return;
+////////////////////////////////////////////////////////////////////
+//     Function: DXTextureContext9::fill_d3d_volume_texture_pixels
+//       Access: Private
+//  Description:
+////////////////////////////////////////////////////////////////////
+HRESULT DXTextureContext9::
+fill_d3d_volume_texture_pixels() {
+  HRESULT hr = E_FAIL;
+  nassertr(IS_VALID_PTR(_texture), E_FAIL);
+
+  CPTA_uchar image = _texture->get_ram_image();
+  if (image.is_null()) {
+    // The texture doesn't have an image to load.  That's ok; it
+    // might be a texture we've rendered to by frame buffer
+    // operations or something.
+    return S_OK;
+  }
+
+  PStatTimer timer(GraphicsStateGuardian::_load_texture_pcollector);
+
+  nassertr(IS_VALID_PTR(_d3d_texture), E_FAIL);
+  nassertr(_texture->get_texture_type() == Texture::TT_3d_texture, E_FAIL);
+
+  DWORD orig_width  = (DWORD) _texture->get_x_size();
+  DWORD orig_height = (DWORD) _texture->get_y_size();
+  DWORD orig_depth = (DWORD) _texture->get_z_size();
+  DWORD num_color_channels = _texture->get_num_components();
+  D3DFORMAT source_format = _d3d_format;
+  BYTE *image_pixels = (BYTE*)image.p();
+  int component_width = _texture->get_component_width();
+
+  nassertr(IS_VALID_PTR(image_pixels), E_FAIL);
+
+  IDirect3DVolume9 *mip_level_0 = NULL;
+  bool using_temp_buffer = false;
+  BYTE *pixels = image_pixels;
+
+  nassertr(IS_VALID_PTR(_d3d_volume_texture), E_FAIL);
+  hr = _d3d_volume_texture->GetVolumeLevel(0, &mip_level_0);
+
+  if (FAILED(hr)) {
+    dxgsg9_cat.error()
+      << "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
+      << ", GetSurfaceLevel failed" << D3DERRORSTRING(hr);
+    return E_FAIL;
+  }
+
+  D3DBOX source_size;
+  source_size.Left = source_size.Top = source_size.Front = 0;
+  source_size.Right = orig_width;
+  source_size.Bottom = orig_height;
+  source_size.Back = orig_depth;
+
+  UINT source_row_byte_length = orig_width * num_color_channels;
+  UINT source_page_byte_length = orig_height * source_row_byte_length;
+
+  DWORD level_0_filter, mip_filter_flags;
+  using_temp_buffer = false;
+
+  // need filtering if size changes, (also if bitdepth reduced (need
+  // dithering)??)
+  level_0_filter = D3DX_FILTER_LINEAR ; //| D3DX_FILTER_DITHER;  //dithering looks ugly on i810 for 4444 textures
+
+  // D3DXLoadSurfaceFromMemory will load black luminance and we want
+  // full white, so convert to explicit luminance-alpha format
+  if (_d3d_format == D3DFMT_A8) {
+    // alloc buffer for explicit D3DFMT_A8L8
+    USHORT *temp_buffer = new USHORT[orig_width * orig_height * orig_depth];
+    if (!IS_VALID_PTR(temp_buffer)) {
+      dxgsg9_cat.error()
+        << "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
+      goto exit_FillDDSurf;
+    }
+    using_temp_buffer = true;
+
+    USHORT *out_pixels = temp_buffer;
+    BYTE *source_pixels = pixels + component_width - 1;
+    for (UINT z = 0; z < orig_depth; z++) {
+      for (UINT y = 0; y < orig_height; y++) {
+        for (UINT x = 0;
+             x < orig_width;
+             x++, source_pixels += component_width, out_pixels++) {
+          // add full white, which is our interpretation of alpha-only
+          // (similar to default adding full opaque alpha 0xFF to
+          // RGB-only textures)
+          *out_pixels = ((*source_pixels) << 8 ) | 0xFF;
+        }
+      }
     }
 
-    if(dxgsg9_cat.is_spam()) {
-        dxgsg9_cat.spam() << "Deleting DX texture for " << _tex->get_name() << "\n";
+    source_format = D3DFMT_A8L8;
+    source_row_byte_length = orig_width * sizeof(USHORT);
+    source_page_byte_length = orig_height * source_row_byte_length;
+    pixels = (BYTE*)temp_buffer;
+
+  } else if (component_width != 1) {
+    // Convert from 16-bit per channel (or larger) format down to
+    // 8-bit per channel.  This throws away precision in the
+    // original image, but dx8 doesn't support high-precision images
+    // anyway.
+
+    int num_components = _texture->get_num_components();
+    int num_pixels = orig_width * orig_height * orig_depth * num_components;
+    BYTE *temp_buffer = new BYTE[num_pixels];
+    if (!IS_VALID_PTR(temp_buffer)) {
+      dxgsg9_cat.error() << "FillDDSurfaceTexturePixels couldnt alloc mem for temp pixbuf!\n";
+      goto exit_FillDDSurf;
     }
+    using_temp_buffer = true;
 
-    RELEASE(_pD3DTexture9,dxgsg9,"texture",RELEASE_ONCE);
-/*
-#ifdef DEBUG_RELEASES
-    if(_surface) {
-        LPDIRECTDRAW7 pDD;
-        _surface->GetDDInterface( (VOID**)&pDD );
-        pDD->Release();
-
-        PRINTREFCNT(pDD,"before DeleteTex, IDDraw7");
-        RELEASE(_surface,dxgsg9,"texture",false);
-        PRINTREFCNT(pDD,"after DeleteTex, IDDraw7");
+    BYTE *source_pixels = pixels + component_width - 1;
+    for (int i = 0; i < num_pixels; i++) {
+      temp_buffer[i] = *source_pixels;
+      source_pixels += component_width;
     }
-#else
+    pixels = (BYTE*)temp_buffer;
+  }
 
-    RELEASE(_pD3DSurf9,dxgsg9,"texture",false);
- #endif
-*/
-}
 
+  // filtering may be done here if texture if targetsize != origsize
+#ifdef DO_PSTATS
+  GraphicsStateGuardian::_data_transferred_pcollector.add_level(source_page_byte_length * orig_depth);
+#endif
+  hr = D3DXLoadVolumeFromMemory
+    (mip_level_0, (PALETTEENTRY*)NULL, (D3DBOX*)NULL, (LPCVOID)pixels,
+     source_format, source_row_byte_length, source_page_byte_length,
+     (PALETTEENTRY*)NULL,
+     &source_size, level_0_filter, (D3DCOLOR)0x0);
+  if (FAILED(hr)) {
+    dxgsg9_cat.error()
+      << "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
+      << ", D3DXLoadVolumeFromMem failed" << D3DERRORSTRING(hr);
+    goto exit_FillDDSurf;
+  }
+
+  if (_has_mipmaps) {
+    if (!dx_use_triangle_mipgen_filter) {
+      mip_filter_flags = D3DX_FILTER_BOX;
+    } else {
+      mip_filter_flags = D3DX_FILTER_TRIANGLE;
+    }
 
-////////////////////////////////////////////////////////////////////
-//     Function: DXTextureContext9::Constructor
-//       Access: Public
-//  Description:
-////////////////////////////////////////////////////////////////////
-DXTextureContext9::
-DXTextureContext9(Texture *tex) :
-TextureContext(tex) {
+    //    mip_filter_flags| = D3DX_FILTER_DITHER;
 
-    if(dxgsg9_cat.is_spam()) {
-       dxgsg9_cat.spam() << "Creating DX texture [" << tex->get_name() << "], minfilter(" << PandaFilterNameStrs[tex->get_minfilter()] << "), magfilter("<<PandaFilterNameStrs[tex->get_magfilter()] << "), anisodeg(" << tex->get_anisotropic_degree() << ")\n";
+    hr = D3DXFilterTexture(_d3d_texture, (PALETTEENTRY*)NULL, 0,
+                           mip_filter_flags);
+    if (FAILED(hr)) {
+      dxgsg9_cat.error()
+        << "FillDDSurfaceTexturePixels failed for " << _texture->get_name()
+        << ", D3DXFilterTex failed" << D3DERRORSTRING(hr);
+      goto exit_FillDDSurf;
     }
+  }
 
-    _pD3DTexture9 = NULL;
-    _bHasMipMaps = FALSE;
-    _tex = tex;
+ exit_FillDDSurf:
+  if (using_temp_buffer) {
+    SAFE_DELETE_ARRAY(pixels);
+  }
+  RELEASE(mip_level_0, dxgsg9, "FillDDSurf MipLev0 texture ptr", RELEASE_ONCE);
+  return hr;
 }
 
-DXTextureContext9::
-~DXTextureContext9() {
-    if(dxgsg9_cat.is_spam()) {
-        dxgsg9_cat.spam() << "Deleting DX9 TexContext for " << _tex->get_name() << "\n";
-    }
-    DeleteTexture();
-    TextureContext::~TextureContext();
-    _tex = NULL;
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXTextureContext9::down_to_power_2
+//       Access: Private, Static
+//  Description: Returns the largest power of 2 less than or equal
+//               to value.
+////////////////////////////////////////////////////////////////////
+int DXTextureContext9::
+down_to_power_2(int value) {
+  int x = 1;
+  while ((x << 1) <= value) {
+    x = (x << 1);
+  }
+  return x;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXTextureContext9::get_bits_per_pixel
+//       Access: Private
+//  Description: Maps from the Texture's Format symbols to bpp.
+//               Returns # of alpha bits.  Note: Texture's format
+//               indicates REQUESTED final format, not the stored
+//               format, which is indicated by pixelbuffer type
+////////////////////////////////////////////////////////////////////
+unsigned int DXTextureContext9::
+get_bits_per_pixel(Texture::Format format, int *alphbits) {
+  *alphbits = 0;      // assume no alpha bits
+  switch(format) {
+  case Texture::F_alpha:
+    *alphbits = 8;
+  case Texture::F_color_index:
+  case Texture::F_red:
+  case Texture::F_green:
+  case Texture::F_blue:
+  case Texture::F_rgb332:
+    return 8;
+  case Texture::F_luminance_alphamask:
+    *alphbits = 1;
+    return 16;
+  case Texture::F_luminance_alpha:
+    *alphbits = 8;
+    return 16;
+  case Texture::F_luminance:
+    return 8;
+  case Texture::F_rgba4:
+    *alphbits = 4;
+    return 16;
+  case Texture::F_rgba5:
+    *alphbits = 1;
+    return 16;
+  case Texture::F_depth_component:
+  case Texture::F_rgb5:
+    return 16;
+  case Texture::F_rgb8:
+  case Texture::F_rgb:
+    return 24;
+  case Texture::F_rgba8:
+  case Texture::F_rgba:
+  case Texture::F_rgbm:
+    if (format == Texture::F_rgbm)   // does this make any sense?
+      *alphbits = 1;
+    else *alphbits = 8;
+    return 32;
+  case Texture::F_rgb12:
+    return 36;
+  case Texture::F_rgba12:
+    *alphbits = 12;
+    return 48;
+  }
+  return 8;
 }
 

+ 29 - 25
panda/src/dxgsg9/dxTextureContext9.h

@@ -1,10 +1,10 @@
-// Filename: dxTextureContext8.h
-// Created by:   masad (02Jan04)
+// Filename: dxTextureContext9.h
+// Created by:  drose (07Oct99)
 //
 ////////////////////////////////////////////////////////////////////
 //
 // PANDA 3D SOFTWARE
-// Copyright (c) 2004, Disney Enterprises, Inc.  All rights reserved
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
 //
 // All use of this software is subject to the terms of the Panda 3d
 // Software license.  You should have received a copy of this license
@@ -23,38 +23,43 @@
 #include "texture.h"
 #include "textureContext.h"
 
-//#define DO_CUSTOM_CONVERSIONS
-
 ////////////////////////////////////////////////////////////////////
-//   Class : DXTextureContext9
+//       Class : DXTextureContext9
 // Description :
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDADX DXTextureContext9 : public TextureContext {
-  friend class DXGraphicsStateGuardian;
-  friend class wdxGraphicsWindow;
-
 public:
   DXTextureContext9(Texture *tex);
-  ~DXTextureContext9();
+  virtual ~DXTextureContext9();
 
-  IDirect3DTexture9  *_pD3DTexture9;
-  Texture *_tex;            // ptr to parent, primarily for access to namestr
-  IDirect3DTexture9 *CreateTexture(DXScreenData &scrn);
+  bool create_texture(DXScreenData &scrn);
+  void delete_texture();
 
-  D3DFORMAT _PixBufD3DFmt;    // the 'D3DFORMAT' the Panda TextureBuffer fmt corresponds to
+  INLINE bool has_mipmaps() const;
+  INLINE IDirect3DBaseTexture9 *get_d3d_texture() const;
+  INLINE IDirect3DTexture9 *get_d3d_2d_texture() const;
+  INLINE IDirect3DVolumeTexture9 *get_d3d_volume_texture() const;
+  INLINE IDirect3DCubeTexture9 *get_d3d_cube_texture() const;
 
-  bool _bHasMipMaps;
+  static HRESULT d3d_surface_to_texture(RECT &source_rect,
+          IDirect3DSurface9 *d3d_surface,
+          bool inverted, Texture *result,
+          int z);
 
-#ifdef DO_CUSTOM_CONVERSIONS
-  DWORD _PixBufConversionType;  // enum ConversionType
-#endif
+private:
+  HRESULT fill_d3d_texture_pixels();
+  HRESULT fill_d3d_volume_texture_pixels();
+  static int down_to_power_2(int value);
+  unsigned int get_bits_per_pixel(Texture::Format format, int *alphbits);
 
-  // must be public since called from global callback fns
-  void DeleteTexture();
-  HRESULT FillDDSurfTexturePixels();
+private:
+  D3DFORMAT _d3d_format;    // the 'D3DFORMAT' the Panda TextureBuffer fmt corresponds to
+  IDirect3DBaseTexture9 *_d3d_texture;
+  IDirect3DTexture9 *_d3d_2d_texture;
+  IDirect3DVolumeTexture9 *_d3d_volume_texture;
+  IDirect3DCubeTexture9 *_d3d_cube_texture;
 
-protected:
-    unsigned int get_bits_per_pixel(Texture::Format format, int *alphbits);
+  bool _has_mipmaps;
 
 public:
   static TypeHandle get_class_type() {
@@ -74,7 +79,6 @@ private:
   static TypeHandle _type_handle;
 };
 
-extern HRESULT ConvertD3DSurftoPixBuf(RECT &SrcRect,IDirect3DSurface9 *pD3DSurf9,Texture *pixbuf);
+#include "dxTextureContext9.I"
 
 #endif
-

+ 17 - 0
panda/src/dxgsg9/dxVertexBufferContext9.I

@@ -0,0 +1,17 @@
+// Filename: dxVertexBufferContext9.I
+// Created by:  drose (18Mar05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////

+ 254 - 0
panda/src/dxgsg9/dxVertexBufferContext9.cxx

@@ -0,0 +1,254 @@
+// Filename: dxVertexBufferContext9.cxx
+// Created by:  drose (18Mar05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dxVertexBufferContext9.h"
+#include "geomVertexArrayData.h"
+#include "geomVertexArrayFormat.h"
+#include "graphicsStateGuardian.h"
+#include "pStatTimer.h"
+#include "internalName.h"
+#include "config_dxgsg9.h"
+#include <d3dx9.h>
+
+TypeHandle DXVertexBufferContext9::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXVertexBufferContext9::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+DXVertexBufferContext9::
+DXVertexBufferContext9(GeomVertexArrayData *data) :
+  VertexBufferContext(data),
+  _vbuffer(NULL)
+{
+  // Now fill in the FVF code.
+  const GeomVertexArrayFormat *array_format = data->get_array_format();
+
+  // We have to start with the vertex data, and work up from there in
+  // order, since that's the way the FVF is defined.
+  int n = 0;
+  int num_columns = array_format->get_num_columns();
+
+  _fvf = 0;
+
+  if (n < num_columns &&
+      array_format->get_column(n)->get_name() == InternalName::get_vertex()) {
+    ++n;
+
+    int num_blend_values = 0;
+
+    if (n < num_columns &&
+        array_format->get_column(n)->get_name() == InternalName::get_transform_weight()) {
+      // We have hardware vertex animation.
+      num_blend_values = array_format->get_column(n)->get_num_values();
+      ++n;
+    }
+
+    if (n < num_columns &&
+        array_format->get_column(n)->get_name() == InternalName::get_transform_index()) {
+      // Furthermore, it's indexed vertex animation.
+      _fvf |= D3DFVF_LASTBETA_UBYTE4;
+      ++num_blend_values;
+      ++n;
+    }
+
+    switch (num_blend_values) {
+    case 0:
+      _fvf |= D3DFVF_XYZ;
+      break;
+
+    case 1:
+      _fvf |= D3DFVF_XYZB1;
+      break;
+
+    case 2:
+      _fvf |= D3DFVF_XYZB2;
+      break;
+
+    case 3:
+      _fvf |= D3DFVF_XYZB3;
+      break;
+
+    case 4:
+      _fvf |= D3DFVF_XYZB4;
+      break;
+
+    case 5:
+      _fvf |= D3DFVF_XYZB5;
+      break;
+    }
+  }
+
+  if (n < num_columns &&
+      array_format->get_column(n)->get_name() == InternalName::get_normal()) {
+    _fvf |= D3DFVF_NORMAL;
+    ++n;
+  }
+  if (n < num_columns &&
+      array_format->get_column(n)->get_name() == InternalName::get_color()) {
+    _fvf |= D3DFVF_DIFFUSE;
+    ++n;
+  }
+
+  // Now look for all of the texcoord names and enable them in the
+  // same order they appear in the array.
+  int texcoord_index = 0;
+  while (n < num_columns &&
+         array_format->get_column(n)->get_contents() == Geom::C_texcoord) {
+    const GeomVertexColumn *column = array_format->get_column(n);
+    switch (column->get_num_values()) {
+    case 1:
+      _fvf |= D3DFVF_TEXCOORDSIZE1(texcoord_index);
+      ++n;
+      break;
+    case 2:
+      _fvf |= D3DFVF_TEXCOORDSIZE2(texcoord_index);
+      ++n;
+      break;
+    case 3:
+      _fvf |= D3DFVF_TEXCOORDSIZE3(texcoord_index);
+      ++n;
+      break;
+    case 4:
+      _fvf |= D3DFVF_TEXCOORDSIZE4(texcoord_index);
+      ++n;
+      break;
+    }
+    ++texcoord_index;
+  }
+
+  switch (texcoord_index) {
+  case 0:
+    break;
+  case 1:
+    _fvf |= D3DFVF_TEX1;
+    break;
+  case 2:
+    _fvf |= D3DFVF_TEX2;
+    break;
+  case 3:
+    _fvf |= D3DFVF_TEX3;
+    break;
+  case 4:
+    _fvf |= D3DFVF_TEX4;
+    break;
+  case 5:
+    _fvf |= D3DFVF_TEX5;
+    break;
+  case 6:
+    _fvf |= D3DFVF_TEX6;
+    break;
+  case 7:
+    _fvf |= D3DFVF_TEX7;
+    break;
+  case 8:
+    _fvf |= D3DFVF_TEX8;
+    break;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXVertexBufferContext9::Destructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+DXVertexBufferContext9::
+~DXVertexBufferContext9() {
+  if (_vbuffer != NULL) {
+    if (dxgsg9_cat.is_debug()) {
+      dxgsg9_cat.debug()
+        << "deleting vertex buffer " << _vbuffer << "\n";
+    }
+
+    RELEASE(_vbuffer, dxgsg9, "vertex buffer", RELEASE_ONCE);
+    _vbuffer = NULL;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXVertexBufferContext9::create_vbuffer
+//       Access: Public
+//  Description: Creates a new vertex buffer (but does not upload data
+//               to it).
+////////////////////////////////////////////////////////////////////
+void DXVertexBufferContext9::
+create_vbuffer(DXScreenData &scrn) {
+  if (_vbuffer != NULL) {
+    RELEASE(_vbuffer, dxgsg9, "vertex buffer", RELEASE_ONCE);
+    _vbuffer = NULL;
+  }
+
+  PStatTimer timer(GraphicsStateGuardian::_create_vertex_buffer_pcollector);
+
+  HRESULT hr = scrn._d3d_device->CreateVertexBuffer
+
+//    (get_data()->get_data_size_bytes(), D3DUSAGE_WRITEONLY,
+//    _fvf, D3DPOOL_MANAGED, &_vbuffer, NULL);
+      (get_data()->get_data_size_bytes(), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC,
+      _fvf, D3DPOOL_DEFAULT, &_vbuffer, NULL);
+
+  if (FAILED(hr)) {
+    dxgsg9_cat.warning()
+      << "CreateVertexBuffer failed" << D3DERRORSTRING(hr);
+    _vbuffer = NULL;
+  } else {
+    if (dxgsg9_cat.is_debug()) {
+      dxgsg9_cat.debug()
+        << "created vertex buffer " << _vbuffer << ": "
+        << get_data()->get_num_rows() << " vertices "
+        << *get_data()->get_array_format() << "\n";
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXVertexBufferContext9::upload_data
+//       Access: Public
+//  Description: Copies the latest data from the client store to
+//               DirectX.
+////////////////////////////////////////////////////////////////////
+void DXVertexBufferContext9::
+upload_data() {
+  nassertv(_vbuffer != NULL);
+  PStatTimer timer(GraphicsStateGuardian::_load_vertex_buffer_pcollector);
+
+  int data_size = get_data()->get_data_size_bytes();
+
+  if (dxgsg9_cat.is_spam()) {
+    dxgsg9_cat.spam()
+      << "copying " << data_size
+      << " bytes into vertex buffer " << _vbuffer << "\n";
+  }
+
+  BYTE *local_pointer;
+
+//  HRESULT hr = _vbuffer->Lock(0, data_size, (void **) &local_pointer, 0);
+  HRESULT hr = _vbuffer->Lock(0, data_size, (void **) &local_pointer, D3DLOCK_DISCARD);
+
+  if (FAILED(hr)) {
+    dxgsg9_cat.error()
+      << "VertexBuffer::Lock failed" << D3DERRORSTRING(hr);
+    return;
+  }
+
+  GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size);
+  memcpy(local_pointer, get_data()->get_data(), data_size);
+
+  _vbuffer->Unlock();
+}

+ 62 - 0
panda/src/dxgsg9/dxVertexBufferContext9.h

@@ -0,0 +1,62 @@
+// Filename: dxVertexBufferContext9.h
+// Created by:  drose (18Mar05)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DXVERTEXBUFFERCONTEXT9_H
+#define DXVERTEXBUFFERCONTEXT9_H
+
+#include "pandabase.h"
+#include "dxgsg9base.h"
+#include "vertexBufferContext.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : DXVertexBufferContext9
+// Description : Caches a GeomVertexArrayData in the DirectX device as
+//               a vertex buffer.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDADX DXVertexBufferContext9 : public VertexBufferContext {
+public:
+  DXVertexBufferContext9(GeomVertexArrayData *data);
+  virtual ~DXVertexBufferContext9();
+
+  void create_vbuffer(DXScreenData &scrn);
+  void upload_data();
+
+  IDirect3DVertexBuffer9 *_vbuffer;
+  int _fvf;
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    VertexBufferContext::init_type();
+    register_type(_type_handle, "DXVertexBufferContext9",
+                  VertexBufferContext::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+#include "dxVertexBufferContext9.I"
+
+#endif

+ 3 - 1
panda/src/dxgsg9/dxgsg9_composite1.cxx

@@ -1,7 +1,9 @@
 #include "dxgsg9base.h"
 #include "config_dxgsg9.cxx"
 #include "dxTextureContext9.cxx"
-#include "d3dfont9.cxx"
+#include "dxVertexBufferContext9.cxx"
+#include "dxIndexBufferContext9.cxx"
+#include "dxGeomMunger9.cxx"
 #include "wdxGraphicsPipe9.cxx"
 #include "wdxGraphicsWindow9.cxx"
 #include "dxGraphicsDevice9.cxx"

+ 39 - 42
panda/src/dxgsg9/dxgsg9base.h

@@ -1,10 +1,10 @@
-// Filename: dxgsg8base.h
-// Created by:   masad (02Jan04)
+// Filename: dxgsg9base.h
+// Created by:  georges (07Oct01)
 //
 ////////////////////////////////////////////////////////////////////
 //
 // PANDA 3D SOFTWARE
-// Copyright (c) 2004, Disney Enterprises, Inc.  All rights reserved
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
 //
 // All use of this software is subject to the terms of the Panda 3d
 // Software license.  You should have received a copy of this license
@@ -19,10 +19,9 @@
 #ifndef DXGSG9BASE_H
 #define DXGSG9BASE_H
 
-// include win32 defns for everything up to WinServer2003, and assume I'm smart enough to
-// use GetProcAddress for backward compat on newer fns
-// Note DX9 cannot be installed on w95, so OK to assume base of win98
-#define _WIN32_WINNT 0x0502
+#include "pandabase.h"
+#include "graphicsWindow.h"
+#include "pmap.h"
 
 #define WIN32_LEAN_AND_MEAN   // get rid of mfc win32 hdr stuff
 #ifndef STRICT
@@ -38,20 +37,19 @@
 #include <dxerr9.h>
 #undef WIN32_LEAN_AND_MEAN
 
-#include "pandabase.h"
-#include "graphicsWindow.h"
-
-#if D3D_SDK_VERSION < 31
-#error you have DX 8.0/8.1 headers, not DX 9, you need to install DX 9 SDK!
+/* ***** DX9
+#if D3D_SDK_VERSION != 220
+#error you have DX 8.0 headers, not DX 8.1, you need to install DX 8.1 SDK!
 #endif
 
 #if DIRECT3D_VERSION != 0x0900
-#error DX9 headers not available, you need to install newer MS Platform SDK!
+#error DX8.1 headers not available, you need to install newer MS Platform SDK!
 #endif
 
 #ifndef D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD
 #error you have pre-release DX8.1 headers, you need to install final DX 8.1 SDK!
 #endif
+*/
 
 #ifndef D3DERRORSTRING
 #ifdef NDEBUG
@@ -78,7 +76,7 @@ typedef DWORD DXShaderHandle;
     type var;                       \
     ZeroMemory(&var, sizeof(type)); \
     var.dwSize = sizeof(type);
-    
+
 #define SAFE_DELSHADER(TYPE,HANDLE,PDEVICE)  \
   if((HANDLE!=NULL)&&IS_VALID_PTR(PDEVICE)) { PDEVICE->Delete##TYPE##Shader(HANDLE);  HANDLE=NULL; }
 
@@ -94,7 +92,7 @@ typedef DWORD DXShaderHandle;
 #define RELEASE_ONCE false
 
 
-// uncomment to add refcnt debug output 
+// uncomment to add refcnt debug output
 #define DEBUG_RELEASES
 
 #ifdef DEBUG_RELEASES
@@ -116,7 +114,7 @@ typedef DWORD DXShaderHandle;
 
 #define PRINT_REFCNT(MODULE,p) { ULONG refcnt;  (p)->AddRef();  refcnt=(p)->Release(); \
                                  MODULE##_cat.debug() << #p << " has refcnt = " << refcnt << " at " << __FILE__ << ":" << __LINE__ << endl; }
-                                 
+
 #else
 #define RELEASE(OBJECT,MODULE,DBGSTR,bDoDownToZero)   { \
    ULONG refcnt;                                        \
@@ -132,7 +130,7 @@ typedef DWORD DXShaderHandle;
    }}
 
 #define PRINT_REFCNT(MODULE,p)
-#endif    
+#endif
 
 #ifdef DO_PSTATS
 #define DO_PSTATS_STUFF(XX) XX;
@@ -156,7 +154,7 @@ typedef enum {
     A8_FLAG =           FLG(8),
     A8R3G3B2_FLAG =     FLG(9),
     X4R4G4B4_FLAG =     FLG(10),
-    A2R10G10B10_FLAG =  FLG(11),
+    A2B10G10R10_FLAG =  FLG(11),
     G16R16_FLAG =       FLG(12),
     A8P8_FLAG =         FLG(13),
     P8_FLAG =           FLG(14),
@@ -189,34 +187,33 @@ typedef enum {
 #define RECT_XSIZE(REC) (REC.right-REC.left)
 #define RECT_YSIZE(REC) (REC.bottom-REC.top)
 
-typedef struct {
-      LPDIRECT3DDEVICE9 pD3DDevice;
-      IDirect3DSwapChain9 *pSwapChain;
-      LPDIRECT3D9       pD3D9;  // copied from DXGraphicsPipe9 for convenience
-      HWND              hWnd;
-      HMONITOR          hMon;
-      DWORD             MaxAvailVidMem;
-      ushort            CardIDNum;  // adapter ID
-      ushort            depth_buffer_bitdepth;  //GetSurfaceDesc is not reliable so must store this explicitly
-      bool              bCanDirectDisableColorWrites;  // if true, dont need blending for this
-      bool              bIsLowVidMemCard;
-      bool              bIsTNLDevice;
-      bool              bCanUseHWVertexShaders;
-      bool              bCanUsePixelShaders;
-      bool              bIsDX9;
-      UINT              SupportedScreenDepthsMask;
-      UINT              SupportedTexFmtsMask;
-      D3DCAPS9          d3dcaps;
-      D3DDISPLAYMODE    DisplayMode;
-      D3DPRESENT_PARAMETERS PresParams;  // not redundant with DisplayMode since width/height must be 0 for windowed mode
-      D3DADAPTER_IDENTIFIER9 DXDeviceID;
-} DXScreenData;
+struct DXScreenData {
+  LPDIRECT3DDEVICE9 _d3d_device;
+  IDirect3DSwapChain9 *_swap_chain;
+  LPDIRECT3D9 _d3d9;  // copied from DXGraphicsPipe9 for convenience
+  HWND _window;
+  HMONITOR _monitor;
+  DWORD _max_available_video_memory;
+  ushort _card_id;  // adapter ID
+  ushort _depth_buffer_bitdepth;  //GetSurfaceDesc is not reliable so must store this explicitly
+  bool _can_direct_disable_color_writes;  // if true, dont need blending for this
+  bool _is_low_memory_card;
+  bool _is_tnl_device;
+  bool _can_use_hw_vertex_shaders;
+  bool _can_use_pixel_shaders;
+  bool _is_dx9_1;
+  UINT _supported_screen_depths_mask;
+  UINT _supported_tex_formats_mask;
+  D3DCAPS9 _d3dcaps;
+  D3DDISPLAYMODE _display_mode;
+  D3DPRESENT_PARAMETERS _presentation_params;  // not redundant with _display_mode since width/height must be 0 for windowed mode
+  D3DADAPTER_IDENTIFIER9 _dx_device_id;
+};
 
 
 //utility stuff
-extern map<D3DFORMAT_FLAG,D3DFORMAT> g_D3DFORMATmap;
+extern pmap<D3DFORMAT_FLAG,D3DFORMAT> g_D3DFORMATmap;
 extern void Init_D3DFORMAT_map();
 extern const char *D3DFormatStr(D3DFORMAT fmt);
 
 #endif
-

+ 4 - 4
panda/src/dxgsg9/wdxGraphicsPipe9.I

@@ -1,10 +1,10 @@
-// Filename: wdxGraphicsPipe8.I
-// Created by:   masad (02Jan04)
+// Filename: wdxGraphicsPipe9.I
+// Created by:  drose (20Dec02)
 //
 ////////////////////////////////////////////////////////////////////
 //
 // PANDA 3D SOFTWARE
-// Copyright (c) 2004, Disney Enterprises, Inc.  All rights reserved
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
 //
 // All use of this software is subject to the terms of the Panda 3d
 // Software license.  You should have received a copy of this license
@@ -14,4 +14,4 @@
 // To contact the maintainers of this program write to
 // [email protected] .
 //
-////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////

File diff ditekan karena terlalu besar
+ 329 - 422
panda/src/dxgsg9/wdxGraphicsPipe9.cxx


+ 21 - 32
panda/src/dxgsg9/wdxGraphicsPipe9.h

@@ -1,10 +1,10 @@
-// Filename: wdxGraphicsPipe8.h
-// Created by:   masad (02Jan04)
+// Filename: wdxGraphicsPipe9.h
+// Created by:  drose (20Dec02)
 //
 ////////////////////////////////////////////////////////////////////
 //
 // PANDA 3D SOFTWARE
-// Copyright (c) 2004, Disney Enterprises, Inc.  All rights reserved
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
 //
 // All use of this software is subject to the terms of the Panda 3d
 // Software license.  You should have received a copy of this license
@@ -25,20 +25,10 @@
 #include "dxgsg9base.h"
 #include <ddraw.h>
 
-typedef struct {
-   UINT    cardID;
-   char    szDriver[MAX_DEVICE_IDENTIFIER_STRING];
-   char    szDescription[MAX_DEVICE_IDENTIFIER_STRING];
-   GUID    guidDeviceIdentifier;
-   DWORD   VendorID, DeviceID;
-   HMONITOR hMon;
-} DXDeviceInfo;
-typedef pvector<DXDeviceInfo> DXDeviceInfoVec;
-
 ////////////////////////////////////////////////////////////////////
 //       Class : wdxGraphicsPipe9
 // Description : This graphics pipe represents the interface for
-//               creating DirectX graphics windows.
+//               creating DirectX9 graphics windows.
 ////////////////////////////////////////////////////////////////////
 class EXPCL_PANDADX wdxGraphicsPipe9 : public WinGraphicsPipe {
 public:
@@ -52,18 +42,18 @@ public:
                                              GraphicsStateGuardian *share_with);
   virtual PT(GraphicsDevice) make_device(void *scrn);
 
-  bool find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &TestDisplayMode,
-                       D3DFORMAT *pBestFmt, bool bWantStencil,
-                       bool bForce16bpp, bool bVerboseMode = false) const;
+  bool find_best_depth_format(DXScreenData &Display, D3DDISPLAYMODE &Test_display_mode,
+                              D3DFORMAT *pBestFmt, bool bWantStencil,
+                              bool bForce16bpp, bool bVerboseMode = false) const;
 
   void search_for_valid_displaymode(DXScreenData &scrn,
-                             UINT RequestedX_Size, UINT RequestedY_Size,
-                             bool bWantZBuffer, bool bWantStencil,
-                             UINT *pSupportedScreenDepthsMask,
-                             bool *pCouldntFindAnyValidZBuf,
-                             D3DFORMAT *pSuggestedPixFmt,
-                             bool bForce16bppZBuffer,
-                             bool bVerboseMode = false);
+                                    UINT RequestedX_Size, UINT RequestedY_Size,
+                                    bool bWantZBuffer, bool bWantStencil,
+                                    UINT *p_supported_screen_depths_mask,
+                                    bool *pCouldntFindAnyValidZBuf,
+                                    D3DFORMAT *pSuggestedPixFmt,
+                                    bool bForce16bppZBuffer,
+                                    bool bVerboseMode = false);
 
    bool special_check_fullscreen_resolution(DXScreenData &scrn, UINT x_size,UINT y_size);
 
@@ -81,7 +71,7 @@ private:
 private:
   HINSTANCE _hDDrawDLL;
   HINSTANCE _hD3D9_DLL;
-  LPDIRECT3D9 _pD3D9;
+  LPDIRECT3D9 __d3d9;
 
 
   typedef LPDIRECT3D9 (WINAPI *Direct3DCreate9_ProcPtr)(UINT SDKVersion);
@@ -91,20 +81,19 @@ private:
   LPDIRECTDRAWENUMERATEEX _DirectDrawEnumerateExA;
   Direct3DCreate9_ProcPtr _Direct3DCreate9;
 
-  // CardID is used in DX7 lowmem card-classification pass so DX9 can
+  // CardID is used in DX7 lowmem card-classification pass so DX8 can
   // establish correspondence b/w DX7 mem info & DX8 device
   struct CardID {
-    HMONITOR hMon;
-    DWORD MaxAvailVidMem;
-    bool  bIsLowVidMemCard;
+    HMONITOR _monitor;
+    DWORD _max_available_video_memory;
+    bool  _is_low_memory_card;
     GUID  DX7_DeviceGUID;
     DWORD VendorID, DeviceID;
-    //   char  szDriver[MAX_DEVICE_IDENTIFIER_STRING];
   };
-  
+
   typedef pvector<CardID> CardIDs;
   CardIDs _card_ids;
-  bool _bIsDX9;
+  bool __is_dx9_1;
 
 public:
   static TypeHandle get_class_type() {

+ 4 - 3
panda/src/dxgsg9/wdxGraphicsWindow9.I

@@ -1,10 +1,10 @@
-// Filename: wdxGraphicsWindow8.I
-// Created by:   masad (02Jan04)
+// Filename: wdxGraphicsWindow9.I
+// Created by:  drose (20Dec02)
 //
 ////////////////////////////////////////////////////////////////////
 //
 // PANDA 3D SOFTWARE
-// Copyright (c) 2004, Disney Enterprises, Inc.  All rights reserved
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
 //
 // All use of this software is subject to the terms of the Panda 3d
 // Software license.  You should have received a copy of this license
@@ -15,3 +15,4 @@
 // [email protected] .
 //
 ////////////////////////////////////////////////////////////////////
+ 

File diff ditekan karena terlalu besar
+ 296 - 475
panda/src/dxgsg9/wdxGraphicsWindow9.cxx


+ 24 - 30
panda/src/dxgsg9/wdxGraphicsWindow9.h

@@ -1,5 +1,5 @@
-// Filename: wdxGraphicsWindow8.h
-// Created by:   masad (02Jan04)
+// Filename: wdxGraphicsWindow9.h
+// Created by:  mike (09Jan97)
 //
 ////////////////////////////////////////////////////////////////////
 //
@@ -16,8 +16,8 @@
 //
 ////////////////////////////////////////////////////////////////////
 
-#ifndef wdxGraphicsWindow9_H
-#define wdxGraphicsWindow9_H
+#ifndef WDXGRAPHICSWINDOW9_H
+#define WDXGRAPHICSWINDOW9_H
 
 #include "pandabase.h"
 #include "winGraphicsWindow.h"
@@ -27,11 +27,6 @@
 
 class wdxGraphicsPipe9;
 
-static const int WDXWIN_CONFIGURE = 4;
-static const int WDXWIN_EVENT = 8;
-
-//#define FIND_CARD_MEMAVAILS
-
 ////////////////////////////////////////////////////////////////////
 //       Class : wdxGraphicsWindow9
 // Description : A single graphics window for rendering DirectX under
@@ -42,40 +37,40 @@ public:
   wdxGraphicsWindow9(GraphicsPipe *pipe, GraphicsStateGuardian *gsg,
                      const string &name);
   virtual ~wdxGraphicsWindow9();
-  virtual bool open_window();
-  virtual void close_window();
-  virtual void reset_window(bool swapchain);
 
-  virtual int verify_window_sizes(int numsizes, int *dimen);
+  virtual void make_current();
 
   virtual bool begin_frame();
   virtual void end_flip();
-  virtual LONG window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
-  virtual bool handle_mouse_motion(int x, int y);
+
+  virtual int verify_window_sizes(int numsizes, int *dimen);
 
 protected:
+  virtual void close_window();
+  virtual bool open_window();
+  virtual void reset_window(bool swapchain);
+
   virtual void fullscreen_restored(WindowProperties &properties);
   virtual void handle_reshape();
   virtual bool do_fullscreen_resize(int x_size, int y_size);
-  virtual void support_overlay_window(bool flag);
 
 private:
-  //  bool set_to_temp_rendertarget();
-  bool create_screen_buffers_and_device(DXScreenData &Display,
+  struct DXDeviceInfo {
+    UINT cardID;
+    char szDriver[MAX_DEVICE_IDENTIFIER_STRING];
+    char szDescription[MAX_DEVICE_IDENTIFIER_STRING];
+    GUID guidDeviceIdentifier;
+    DWORD VendorID, DeviceID;
+    HMONITOR _monitor;
+  };
+  typedef pvector<DXDeviceInfo> DXDeviceInfoVec;
+
+  bool create_screen_buffers_and_device(DXScreenData &display,
                                         bool force_16bpp_zbuffer);
 
   bool choose_device();
   bool search_for_device(wdxGraphicsPipe9 *dxpipe, DXDeviceInfo *device_info);
 
-  //  void set_coop_levels_and_display_modes();
-/*
-  void search_for_valid_displaymode(UINT RequestedX_Size, UINT RequestedY_Size,
-                                    bool bWantZBuffer, bool bWantStencil,
-                                    UINT *pSupportedScreenDepthsMask,
-                                    bool *pCouldntFindAnyValidZBuf,
-                                    D3DFORMAT *pSuggestedPixFmt,
-                                    bool bVerboseMode = false);
-*/
   bool reset_device_resize_window(UINT new_xsize, UINT new_ysize);
   void init_resized_window();
   static int D3DFMT_to_DepthBits(D3DFORMAT fmt);
@@ -84,6 +79,7 @@ private:
   DXGraphicsStateGuardian9 *_dxgsg;
   DXScreenData _wcontext;
 
+  int _buffer_mask;
   int _depth_buffer_bpp;
   bool _awaiting_restore;
 
@@ -100,15 +96,13 @@ public:
     return get_class_type();
   }
   virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
-  virtual void make_current();
 
 private:
   static TypeHandle _type_handle;
   friend class wdxGraphicsPipe9;
 };
 
-//extern bool is_badvidmem_card(D3DADAPTER_IDENTIFIER9 *pDevID);
 
 #include "wdxGraphicsWindow9.I"
 
-#endif
+#endif

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini