Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Abstraer Contexto De Renderizado

Iniciado por Minos, 26 de Diciembre de 2003, 01:11:07 PM

« anterior - próximo »

Minos

 Ante todo muchas gracias por tu ejemplo, me ha servido de mucha ayuda.

Como he seguido investigando sobre el tema pues voy a poner aqui un articulo de gamedev sobre el mismo para todos los que quieran informarse lo hagan:

http://www.gamedev.net/reference/programmi...s/rendererdll1/

http://www.gamedev.net/reference/programmi...s/rendererdll2/

http://www.gamedev.net/reference/programmi...s/rendererdll3/

http://www.gamedev.net/reference/programmi...s/rendererdll4/


Se trata de 4 articulos sobre la independencia de las APIs graficas.

Animo y a hacer motores  (uoh)  

saludos

ethernet

 Podriais pegar algunos de vuestros interfaces para ver que funciones debe implementar en modulo de render.

saludos

Kriller

 Pues ahí va mi clase base CGEGraphicEngine en su estado actual, clase principal del módulo de render (después del código lo comento un poco):


class CGEGraphicEngine
{
public:

 virtual                   ~CGEGraphicEngine         ()  { End(); }

 virtual void              End                       ();
 bool                      IsOk                      () const  { return m_bOk; }

 CGEFactory               *GetFactory                () const  { return m_pFactory; }
 CGEVertexBufferManager   *GetVertexBufferManager    ()  { return &m_VertexBufferManager; }
//  CGEIndexBufferManager    *GetIndexBufferManager     ()  { return &m_IndexBufferManager; }
 CGETextureManager        *GetTextureManager         ()  { return &m_TextureManager; }

 bool                      SetVideoMode              (const TGEVideoMode &VideoMode);
 TGEVideoMode              GetVideoMode              () const  { return m_VideoMode; }

 inline void               SetWorldTransform         (const TMatrix4 &mWorldTransform);
 inline CGECamera         *GetCamera                 ()  { return m_pCamera; }


 //
 // Render configuration
 //

 inline void               SetLightingEnabled        (bool bEnabled);
 inline void               SetTexture                (unsigned uTextureStage, CGETexture *pTexture);
 inline void               SetTransparencyType       (TGETransparencyType TransparencyType);
 inline void               SetBackfaceCullingType    (TGECullingType BackfaceCullingType);
 inline void               SetDepthBufferType        (TGEDepthBufferType DepthBufferType);
 inline void               SetDepthBufferWriteEnabled(bool bEnabled);
 inline void               SetTextureMinFilter       (unsigned uTextureStage, TGETextureFilterType FilterType);
 inline void               SetTextureMagFilter       (unsigned uTextureStage, TGETextureFilterType FilterType);


 //
 // Drawing operations
 //

 virtual void              BeginDraw                 () = 0;
 virtual void              EndDraw                   () = 0;

 virtual void              DrawMesh                  (const CGEMeshData *pMeshData) = 0;


protected:

 // Constructor and Init() are protected to avoid instantiating this class
                           CGEGraphicEngine          ()  { m_bOk = false; }
 bool                      Init                      (const TGEWindow &Window, const TGEVideoMode &VideoMode);
 void                      PostInit                  ();

 void                      ResetVars                 ();
 void                      FreeVars                  ();

 inline void               SetViewTransform          (const TMatrix4 &mViewTransform);
 inline void               SetProjectionTransform    (const TMatrix4 &mProjectionTransform);


 //
 // Pure virtual methods that must be implemented by concrete graphics engines
 //

 virtual bool              SetVideoMode_Impl           (const TGEVideoMode &VideoMode) = 0;
 virtual void              SetWorldTransform_Impl      (const TMatrix4 &mWorldTransform) = 0;
 virtual void              SetViewTransform_Impl       (const TMatrix4 &mViewTransform) = 0;
 virtual void              SetProjectionTransform_Impl (const TMatrix4 &mProjectionTransform) = 0;
 virtual void              SetLightingEnabled_Impl     (bool bEnabled) = 0;
 virtual void              SetTexture_Impl             (unsigned uTextureStage, CGETexture *pTexture) = 0;
 virtual void              SetTransparencyType_Impl    (TGETransparencyType TransparencyType) = 0;
 virtual void              SetBackfaceCullingType_Impl (TGECullingType BackfaceCullingType) = 0;
 virtual void              SetDepthBufferType_Impl     (TGEDepthBufferType DepthBufferType) = 0;
 virtual void              SetDepthBufferWriteEnabled_Impl (bool bEnabled) = 0;
 virtual void              SetTextureMinFilter_Impl    (unsigned uTextureStage, TGETextureFilterType FilterType) = 0;
 virtual void              SetTextureMagFilter_Impl    (unsigned uTextureStage, TGETextureFilterType FilterType) = 0;

//
// Variables miembro eliminadas para que no ocupe tanto
//


private:


};


Como veis, cada operación básica que debe hacer un renderer aparece aquí como método virtual puro. Además tengo una clase CGEFactory que también implementa cada renderer que sigue el esquema del patrón de diseño Abstract Factory y cuya misión es crear y destruir los objetos que son dependientes del renderer (vertex buffers, index buffers y texturas por ahora).

Por cierto, algo que se me ocurrió y que me ha simplificado mucho la vida. En vez de obligar al renderer a que sea capaz de dibujar muchos tipos de objetos visuales (malla, texto2D, quad, partícula, etc., etc.), el renderer sólo entiende de objetos CGEMeshData, que no son más que una encapsulación de un vertex buffer y opcionalmente un index buffer, y que acepta cualquier tipo de vértice y de primitiva. En la capa de mayor nivel de mi motor es donde tengo toda una jerarquía de objetos visuales, y la mayoría de ellos encapsulan un CGEMeshData imponiéndole cada uno sus propias restricciones. Con esto, consigo simplificar un montón tanto la capa del renderer como la capa superior.

Saludos.

P.D.: Lo siento por el post tan largo.

Kriller

 Vaya, el código ha salido descolocado. ¿Cómo hacéis para que salga con colorines y que todas las letras tengan la misma anchura?

ethernet

 yo uso un cpp2html y pego el contenido de html
mola la implementacion

saludos

Loover

 Prácticamente igual al mio, tb uso el sistema este de Jare http://www.iguanademos.com/Jare/ y métodos virtuales puros. Pero me apunto lo de CGEMeshData, muy buena idea.

Un saludo!
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Loover

 Hi, me estoy planteando cambiar mi método por el de un plugin aparte como hace Drakkar. Porque la verdad, es algo que facilita mucho la portabilidad. He estado mirando en gamedev.com los 4 artículos son "api independence" y controlo todo lo que sería esa parte. En esos artículos, implementa una clase que tiene muchas funciones propias de un motor 3d, como crear un vertex buffer, seleccionar cierta textura, etc. Y el programador utiliza esa clase (en vez de D3D u OGL) para programar la parte gráfica. Es al inicializar esa clase cuando se elige entre un renderer u otro.

De forma que por ejemplo tenemos (en pseudocódigo), algo del estilo:

Render->Init ("OpenGl");
...
Render->CreateVB ( ... )
Render->LockVB ( ... )
Render->SetTriangeInVB (...)
Render->UnLockVB (... )

Y según el render elegido se utiliza una api u otra.

El caso es que la duda me entra por ejemplo para todo el tema de matrices, traslaciones, que no viene en esos artículos que digo y que cambia bastante según sea D3D/OGL.
¿Drakkar tu por ejemplo lo tienes de esa manera? ¿Tu motor es de código abierto para que pueda echarle un vistazo?

A ver si podeís orientarme.
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Zaelsius

 Las matrices en DirectX y OpenGL son diferentes. La primera API utiliza la regla de mano izquierda(si no me equivoco) y la segunda mano derecha.  El motor 3D tiene que utilizar un tipo u otro por defecto, y realizar una conversión en caso de usar la API opuesta.

Pego un trozo de CVideoOpenGL.cpp de Irrlicht Engine, que usa matrices compatibles con DirectX por defecto:

//! sets transformation
void CVideoOpenGL::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)
{
Transformation3DChanged = true;

GLfloat glmat[16];
Matrizes[state] = mat;

switch(state)
{
case ETS_VIEW:
 // OpenGL only has a model matrix, view and world is not existent. so lets fake these two.
 createGLMatrix(glmat, Matrizes[ETS_VIEW] * Matrizes[ETS_WORLD]);
 glMatrixMode(GL_MODELVIEW);
 glLoadMatrixf(glmat);
 break;
case ETS_WORLD:
 // OpenGL only has a model matrix, view and world is not existent. so lets fake these two.
 createGLMatrix(glmat, Matrizes[ETS_VIEW] * Matrizes[ETS_WORLD]);
 glMatrixMode(GL_MODELVIEW);
 glLoadMatrixf(glmat);
 break;
case ETS_PROJECTION:
 {
  createGLMatrix(glmat, mat);
 
  // flip z to compensate OpenGLs right-hand coordinate system
  glmat[12]*= -1.0f;

  glMatrixMode(GL_PROJECTION);
  glLoadMatrixf(glmat);
 }
 break;
}
}


Donde core::matrix4 es una clase para matrices, similar a la D3DXMatrix de DirectX.

Loover

 Gracias, ya empiezo a verlo más claro. Lo de que en ogl sea mátriz vista-transformación puede ser un poco lioso a la hora de portarlo, miraré como lo hace el motor este.

Otra cosa, como podría hacerse en ogl esto: D3DXVec3Transform o D3DXVec2Transform
Las utilizo bastante para colisiones.
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Loover

 Bueno, según he leído en el foro de gamedev esta preparando otro artículo en el que ya mete cámaras, matrices y transformaciones. Así que de momento seguiré terminando otras partes y dejaré el plugin para más tarde. De todos modos, si sabeis responder a la pregunta anterior pues algo que llevaré adelantado, gracias.

EDITADO: Cambio de planes de nuevo. Me he bajado este RenderSystem: http://www.flipcode.com/cgi-bin/msg.cgi?sh...orum=cotd&id=-1

Y es justo lo que estaba buscando. En vez de OGL o Direct3d intentaré usar directamente eso, junto con las modificaciones que me vea obligado a hacerle.
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

BeRSeRKeR

 
Cita de: "Loover"Otra cosa, como podría hacerse en ogl esto: D3DXVec3Transform o D3DXVec2Transform
Las utilizo bastante para colisiones.
Aquí te pongo el supuesto código de las funciones de D3DX...

D3DXVec3Transform:

CitarD3DXVECTOR4 * D3DXVec3Transform(
    D3DXVECTOR4 * pOut,
    const D3DXVECTOR3 * pV,
    const D3DXMATRIX * pM)
{
    float   x, y, z;

    x = pV->x; y = pV->y; z = pV->z;

    pOut->x = x * pM->_11 + y * pM->_21 + z * pM->_31 + pM->_41;
    pOut->y = x * pM->_12 + y * pM->_22 + z * pM->_32 + pM->_42;
    pOut->z = x * pM->_13 + y * pM->_23 + z * pM->_33 + pM->_43;
    pOut->w = x * pM->_14 + y * pM->_24 + z * pM->_34 + pM->_44;

    return pOut;
}

D3DXVec2Transform:

CitarD3DXVECTOR4 * mxVec2Transform(
    D3DXVECTOR4 * pOut,
    const D3DXVECTOR2 * pV,
    const D3DXMATRIX * pM)
{
    float x, y;

    x = pV->x; y = pV->y;

    pOut->x = x * pM->_11 + y * pM->_21 + pM->_41;
    pOut->y = x * pM->_12 + y * pM->_22 + pM->_42;
    pOut->z = x * pM->_13 + y * pM->_23 + pM->_43;
    pOut->w = x * pM->_14 + y * pM->_24 + pM->_44;

    return pOut;
}

Espero que esté bien...  :D

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

Loover

 Gracias... pero estas utilizando objetos de D3D... ¿no? Bueno, bastaría con que usara mis propios objetos desde OGL similares, ¿no?

Aún así, eso son multiplicaciones de matrices a pelo. ¿No hay alguna forma de aprovechar el T&L usando alguna funcioncilla de OGL?
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

BeRSeRKeR

 
Cita de: "Loover"Gracias... pero estas utilizando objetos de D3D... ¿no? Bueno, bastaría con que usara mis propios objetos desde OGL similares, ¿no?
En realidad he puesto los tipos de Direct3D pero te servirá para hacerte una idea de cómo implementarlo. De todas formas, supongo que te harás (o tendrás) clases matemáticas que manejen matrices y vectores, al estilo de las D3DX. Si es así no debería costarte mucho adaptarlo a tu motor.

Cita de: "Loover"Aún así, eso son multiplicaciones de matrices a pelo. ¿No hay alguna forma de aprovechar el T&L usando alguna funcioncilla de OGL?
No creo que las funciones matemáticas de D3DX se realicen a través de la GPU. Ahora bien, estarán optimizadas para las distintas extensiones de los procesadores.

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.