Foros - Stratos

Programadores => Código de la Semana => Mensaje iniciado por: ethernet en 18 de Octubre de 2003, 01:29:35 PM

Título: Infovid - Zaelsius
Publicado por: ethernet en 18 de Octubre de 2003, 01:29:35 PM
 
(http://www.stratos-ad.com/forums/style_images/1/pip.gif)      InfoVid  (http://www.stratos-ad.com/forums/style_images/1/pip.gif)
//  InfoVid.h;
--------------------------------------------------------------------


#include "d3dx9.h";

#define VENDORID_NVIDIA 0x000010de

namespace
ivid
{

   struct
sVideoMode
   {

       UINT    uWidth;
       UINT    uHeight;
       UINT    uRefreshRate;
       UINT    uFormat;
       char
   szModeDesc[32];
   };


   struct
sVideoAdapter
   {

       char
szDescription[MAX_DEVICE_IDENTIFIER_STRING];
       char
szDriverName[MAX_DEVICE_IDENTIFIER_STRING];
       DWORD dwDriverVersionLo;
       DWORD dwDriverVersionHi;
       UINT uModeCount;
       sVideoMode* pModes;
   };


   class
InfoVid
   {

   public
:

       int
                       Init();
       int
                       GetAdapterCount() const;
       const
sVideoAdapter*    GetAdapterInfo() const;

                               InfoVid();
                               ~
InfoVid();
   private
:

       virtual
void            FormatMode(sVideoMode* pMode);

       UINT                    m_uAdapterCount;
       sVideoAdapter*            m_pInfo;
   };
}

//--------------------------------------------------------------------




La función miembro FormatMode() se encarga de crear una cadena describiendo
cada modo de vídeo, p.ej. "800x600, 32bpp, 85hz".

FormatMode() crea las cadenas de una manera por defecto, pero podeis cambiar
el formato predefinido derivando de InfoVid...


// InfoVid.cpp
--------------------------------------------------------------------

#include "InfoVid.h"
#include "Safe.h"
#include "d3dx9.h";
#include "cstdio";

#pragma comment(lib,"d3d9.lib")


using namespace
ivid;

InfoVid::InfoVid()
:
m_uAdapterCount(0),m_pInfo(0)
{

}


int
InfoVid::Init()
{

   HMODULE D3DLibrary = LoadLibrary("d3d9.dll");
   IDirect3D9 *pID3D;

   if
(!D3DLibrary)
   {

       OutputDebugString("Error, could not load D3D9.DLL");
       return
0;
   }


   typedef
IDirect3D9 * (__stdcall *D3DCREATETYPE)(UINT);
   D3DCREATETYPE d3dCreate = (D3DCREATETYPE) GetProcAddress(D3DLibrary, "Direct3DCreate9");

   if
(!d3dCreate)
   {

       OutputDebugString("Error, could not get proc adress of Direct3DCreate9");
       FreeLibrary(D3DLibrary);
       return
0;
   }


   // Like pID3D = Direct3DCreate9(D3D_SDK_VERSION);
   pID3D = (*d3dCreate)(D3D_SDK_VERSION);

   if
(!pID3D)
   {

       OutputDebugString("Error initializing D3D.");
       FreeLibrary(D3DLibrary);
       return
0;
   }


   //Return number of available devices
   m_uAdapterCount = pID3D->GetAdapterCount();


   D3DADAPTER_IDENTIFIER9* pAdapterId=0;

   m_pInfo = new sVideoAdapter[m_uAdapterCount];

   pAdapterId = new D3DADAPTER_IDENTIFIER9[m_uAdapterCount];

   for
(UINT i=0; i < m_uAdapterCount ; i++)
   {

       pID3D->GetAdapterIdentifier(i,0,&pAdapterId[i]);
       strcpy(m_pInfo[i].szDescription,pAdapterId[i].Description);
       strcpy(m_pInfo[i].szDriverName,pAdapterId[i].Driver);
       m_pInfo[i].dwDriverVersionHi = pAdapterId[i].DriverVersion.HighPart;
       m_pInfo[i].dwDriverVersionLo = pAdapterId[i].DriverVersion.LowPart;

       // Si es NVIDIA sabemos sacar los números de versión
       if(pAdapterId[i].VendorId == VENDORID_NVIDIA)
       {

           int
iNVversion = m_pInfo[i].dwDriverVersionLo & 0x0000FFFF;
           m_pInfo[i].dwDriverVersionHi = iNVversion/100;
           m_pInfo[i].dwDriverVersionLo = iNVversion - (iNVversion/100)*100;
       }

   }


   SafeDeleteArray(pAdapterId);

   // Allowed formats in DX9 are:
   D3DFORMAT lstFormat[]= { D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8, D3DFMT_A2B10G10R10,
       D3DFMT_X1R5G5B5, D3DFMT_A1R5G5B5, D3DFMT_R5G6B5};


   D3DDISPLAYMODE mode;

   for
(UINT i=0; i < m_uAdapterCount ; i++)
   {

       UINT uTotalModes = 0;
       for
(UINT h=0; h < 6; h++)
       {

           uTotalModes += pID3D->GetAdapterModeCount(i,lstFormat[h]);
       }


       m_pInfo[i].uModeCount = uTotalModes;
       m_pInfo[i].pModes = new sVideoMode[uTotalModes];

       UINT k=0;

       for
(UINT h=0; h < 6; h++)
       {

           UINT uModeCount = pID3D->GetAdapterModeCount(i,lstFormat[h]);

           for
(UINT j=0;j<uModeCount;j++)
           {

               pID3D->EnumAdapterModes(i,lstFormat[h],j,&mode);
               m_pInfo[i].pModes[k].uWidth = mode.Width;
               m_pInfo[i].pModes[k].uHeight = mode.Height;
               m_pInfo[i].pModes[k].uRefreshRate = mode.RefreshRate;
               m_pInfo[i].pModes[k].uFormat = (UINT)lstFormat[h];
               FormatMode(&(m_pInfo[i].pModes[k]));

               k++;
           }
       }
   }


   pID3D->Release();

   FreeLibrary(D3DLibrary);


   return
m_uAdapterCount ;
}


InfoVid::~InfoVid()
{

   if
(m_pInfo)
   {

       for
(UINT i=0;i<m_uAdapterCount;i++)
       {

           for
(UINT k=0;k<m_pInfo[i].uModeCount;k++)
           {

               SafeDeleteArray(m_pInfo[i].pModes);
           }
       }


       SafeDeleteArray(m_pInfo);
   }

}


int
InfoVid::GetAdapterCount() const
{

   return
m_uAdapterCount;
}


const
sVideoAdapter* InfoVid::GetAdapterInfo() const
{

   return
(const sVideoAdapter*)m_pInfo;
}


void
InfoVid::FormatMode(sVideoMode* pMode)
{

   sprintf((char*)&(pMode->szModeDesc),"%dx%d %dhz",
       pMode->uWidth,pMode->uHeight,pMode->uRefreshRate);
}

--------------------------------------------------------------------



Y Ahora un ejemplo de utilización:


--------------------------------------------------------------------

#include "iostream.h"
#include "InfoVid.h"
#include "d3dx9.h";

using namespace
ivid;

int
main(int argc, char* argv[])
{

   InfoVid iv;

   int
iAdapters = iv.Init();

   if
(iAdapters)
   {

       const
sVideoAdapter* pInfo = iv.GetAdapterInfo();

       // Recorremos tarjetas gráficas instaladas
       for(UINT i=0;i< iAdapters; i++)
       {

           cout << pInfo[i].szDescription << endl
               <<
pInfo[i].szDriverName << " \nDriver version: "
               <<
pInfo[i].dwDriverVersionHi << "."
               <<
pInfo[i].dwDriverVersionLo << endl;

           cout << "Pulsa una tecla para ver los modos...\n";
           cin.get();


           // Recorremos modos de vídeo disponibles
           for(UINT k=0; k<pInfo[i].uModeCount;k++)
           {

               cout << pInfo[i].pModes[k].uFormat << " "
                    <<
pInfo[i].pModes[k].szModeDesc << endl;
           }

       }
   }

   else

       cerr << "No se pudo obtener la informacion de video\n";

   cout << "Pulsa una tecla para salir...\n";
   cin.get();

   return
0;
}



Autor: Julio Gorgé, a.k.a. Zaelsius
Web: http://www.zsgames.tk

Código: http://www.alu.ua.es/j/jgf8/code/InfoVid.zip


Si quieres enviar tu propio código hazlo a eth_cotd@lycos.es

[/list]

Título: Infovid - Zaelsius
Publicado por: Haddd en 18 de Octubre de 2003, 01:52:28 PM
 Muy buen trabajo y muy claro, enhorabuena!!
Título: Infovid - Zaelsius
Publicado por: Zaelsius en 18 de Octubre de 2003, 02:53:26 PM
 Si alguien tiene una tarjeta ATI y sabe sacar el nº de versión de los Catalyst.. que lo ponga aquí y lo añado  :) .
Título: Infovid - Zaelsius
Publicado por: AgeR en 18 de Octubre de 2003, 07:44:31 PM
 El código está genial!  (ole)
Me mola la sencillez y sobre todo la claridad.

Por cierto, el Refresh Rate parece que no me lo pilla (0 hz), aunque también me ha pasado con alguna demo que me he bajado últimamente. Será algo de las dx9 o de mis drivers?

(uoh)  
Título: Infovid - Zaelsius
Publicado por: Zaelsius en 18 de Octubre de 2003, 08:33:07 PM
 
Cita de: "AgeR"... el Refresh Rate parece que no me lo pilla (0 hz), aunque también me ha pasado con alguna demo que me he bajado últimamente. Será algo de las dx9 o de mis drivers?
Pues ni idea  :huh: . Pregunta obligada y aburrida: ¿tienes DirectX 9.0b y los últimos drivers de tu tarjeta gráfica instalados?

Otra pregunta: tu tarjeta gráfica es nVidia? en caso afirmativo.. ¿te salió la versión correcta del driver detonator?(es que no lo he probado mucho, y podrían cambiar la codificación de la versión en cualquier momento).
Título: Infovid - Zaelsius
Publicado por: AgeR en 18 de Octubre de 2003, 08:44:01 PM
 Tengo las Developer Runtime de las DX9 (no la summer release). En cuanto a los drivers sí, tengo los 44.03 y sí que lo ha detectado bien  (ole) . Me estoy bajando los últimos drivers a ver. Si no, supongo que será ya cosa de las DX9.

Saludos!

He actualizado los drivers y sigue sin aparecer el refresco, será cosa de la versión de dx9. (Me ha detectado los nuevos drivers perfectamente  :) )
Título: Infovid - Zaelsius
Publicado por: ethernet en 19 de Octubre de 2003, 01:09:05 AM
 Por que cargas la dll y no linkas directamente ?
Título: Infovid - Zaelsius
Publicado por: Zaelsius en 19 de Octubre de 2003, 12:01:10 PM
 Mi idea es usar esta clase desde una aplicación "Launcher"(Un GUI para lanzar el juego y seleccionar opciones), así que si DirectX 9 no está instalado quiero poder capturar el error e informar al usuario en vez de mostrar el típico error de "falta dll".

Edit: además enlazar estáticamente con dx suele aumentar bastante el tamaño del ejecutable, y total, para 3 funciones que llamo...
Título: Infovid - Zaelsius
Publicado por: ethernet en 25 de Octubre de 2003, 10:13:15 AM
 No entiendo entonces para que linkas con d3d9 -> #pragma comment(lib,"d3d9.lib")

Por otra parte veo q en el main incluyes iostream.h. A ti tb te ha dado problemas a incluir iostream a secas ? a mi me da esos problemas con la stl de sgi y no los he conseguido resolver   (grrr)

saludos
Título: Infovid - Zaelsius
Publicado por: Zaelsius en 25 de Octubre de 2003, 10:34:00 AM
 
CitarNo entiendo entonces para que linkas con d3d9 -> #pragma comment(lib,"d3d9.lib")

Esa línea es un despiste  :P , sorry. No debería estar ahí.

Citar
Por otra parte veo q en el main incluyes iostream.h. A ti tb te ha dado problemas a incluir iostream a secas ? a mi me da esos problemas con la stl de sgi y no los he conseguido resolver   (grrr)

Pues en este ejemplo en concreto no sé si dará problemas(creo que no), pero normalmente pongo iostream.h por costumbre, pq como bien dices da muchos problemas cuando lo juntas con STL de sgi o STL-Port.. es un problema que aun no se ha solucionado. Si te fijas, sí he usado "cstdio" en vez de "stdio.h"(esta no da problems)

Edit: maldito foro, no me deja poner cosas entre los símbolos < y >  (grrr)  
Título: Infovid - Zaelsius
Publicado por: ethernet en 25 de Octubre de 2003, 09:56:32 PM
 a mi me lo vas a decir que cuando tengo q poner un include tengo que cambiar todos los < y los > por " XD

saludos
Título: Infovid - Zaelsius
Publicado por: Loover en 22 de Diciembre de 2003, 01:06:23 AM
 Buen currele ;)

#define VENDORID_ATI 0x00001002 ===> ATI Technologies Inc ;)

Un saludo
Título: Infovid - Zaelsius
Publicado por: Zaelsius en 22 de Diciembre de 2003, 03:02:29 PM
 Tomo nota,  aunque estaría bien saber cómo se codifica el nº de versión de los Catalyst. :lol: