mmmm.... estoy planeando hacer unas cosillas (un octree pa ser exactos) con este metodo (IDirect3DDevice8.ProcessVertices) pero necesitaria llamarlo numerosas veces (100, 250, incluso mas... 500 y puede que mas aun) en cada frame.
la pregunta q tengo es sencilla,.. ¿estoy loco? ¿planeo hacer alguna barbaridad? ¿resultara muy lento?
cualquier tipo de contestación que ilumine mi camino sera bienvenida :ojo:
Hombre, el dilema del octree y como colocar los vertices para q sea lo mas optimo posible.
Seguire muy decerca el post.
( por segunda vez )
Por si te pica la curiosidad te dire que mi intencion es crear los buffers con los poligonos a pintar al mismo tiempo que transformo los vertices con la susodicha funcion. Asi mato dos pajarracos de un tiro.
Además despues puedo usar el buffer creado para realizar varias pasadas (para lightmaps y texturas detalladas) sin tener que volver a transformar la geometria ni volver a tener que procesar el octree :riendo:
Pero weno, ya veremos si lo acabo de diseñar, lo codifico y luego ademas funciona bien... el ultimo intento lo deje a medias.... (prometia ser una chapuza...)
Si funciona publicare en mi web una demo con su source code (eso si, en delphi) y con un potito paper (en español) que lo explique muy bien.
[ Este Mensaje fue editado por: Lord Trancos el 2002-04-30 22:25 ]
No entiendo como quieres usar ProcessVertex() para hacer octree, pero ten en cuenta que si usas ProcessVertex() lo hace por software, es decir el T&L se queda fuera.
Saludos.
Yo no usaría el ProcessVertex() por la misma razon que _Grey, además a estas alturas es mejor plantearse la forma optima para el T&L por hw aunque no sea la optima para el sw, no? ten en cuenta que por hw la 'T' es inevitable asi que no te ahorrarias nada usando el processvertex para varias pasadas... de hecho incluso iría mas lento.
[ Este Mensaje fue editado por: mallrat el 2002-05-01 05:33 ]
No quiero usar ProcessVertices para hacer el octree, sino para dibujarlo, mas exactamente para preparar el vertex buffer que enviaria (ya transformado) a la pipeline.
En cuanto a lo de T&L, la verdad es que me preocupa mas que mi engine vaya rapido en un ordenador lento como el mio (que no tiene T&L por HW)...
De todos modos, ¿estais seguros de que no se usa HW? En el archivo de ayuda del SDK no pone nada... :triste:
[ Este Mensaje fue editado por: Lord Trancos el 2002-05-01 13:06 ]
ProcessVertex no usa HW, absolutamente seguro... ninguna tarjeta de T&L por HW es capaz de "devolver" el resultado de sus cálculos (no están pensadas para eso, en el fondo es lógico)
Como cuenta mallrat, absolutamente seguro.
Pero es que ademas, si no voy equivocado el draw(Index?)Primitive() pasa los vertices por la matriz de mundo, con lo que se vuelve a calcular.
Si piensas hacer varias pasadas para aplicar texturas, luego lightmap, luego otras y asi... lo mejor seria aprovechar las posibilidades multitextura que te sean posibles.
Saludos!!
Grey, creo que te equivocas,... dudo mucho que unos vertices transformados se vuelvan a transformar... :lengua:
En mi motor utilizo una técnica parecida a la tuya, pero matizando. En Merlín, los vertices se transforman a coordenadas mundo y se almacenan después en un vertexbuffer. La gran ventaja de este sistema, una ventaja que tu no puedes utilizar puesto que procesas también la cámara, es que si un objeto no modifica su estado, se puede guardar en caché los vértices y ya no es necesario transformarlos.
Sin embargo, en contra de tu método, el hecho de realizar varias pasadas no se optimiza, porque el pipeline tendrá que calcular cada vez los vértices proyectados.
Pero voy a hacerte una reflexión..¿Para qué hacer varias pasadas si hoy en día TODAS las tarjetas soportan más de 4 texturas por ciclo y las buenas soportan 8?
Yo he decidido optimizar a lo que hay ahora, y no pensando en tarjetas antiguas. Piénsalo...
Pues yo creo que hoy día no se puede hacer nada sin tener en cuenta la gama MX de geforce (2MX y 4MX), y esas soportan 'solo' 2. Aparte de otras tarjetas de ATI que soportan 2 o 3. Ese mercado es inmenso.
Tarjetas que soporten 8 no conozco...
Lo mejor creo que es hacerse un sistema que trabaje independientemente del número de unidades de textura que tenga la tarjeta, usando más o menos pasadas o multitextura.
Siento este offtopic.
LordTrancos: No hagas NADA por hardware si puedes hacerlo por software, y muchísimo menos transformación. Aunque esa transformación puedas reutilizarla 3 o 4 veces, no te sale a cuenta.
La solución que yo propongo es la típica de programarte un sistema de shaders.
Saludos.
Dracula:
Citar
Sin embargo, en contra de tu método, el hecho de realizar varias pasadas no se optimiza, porque el pipeline tendrá que calcular cada vez los vértices proyectados.
No creo, :-? el vertex buffer que uso tiene este FVF: D3DFVF_XYZRHW | D3DFVF_TEX1
osea que los vertices que le envie al direct3d ya habran sido transformados previamente por ProcessVertices. No creo que el Direct3D sea tan estupido de intentar volver a transformarlos.... (si es que eso es posible)
Ademas, no me he inventado nada nuevo, me baso en un ejemplo que saque de una web (cuya URL he perdido...) En este ejemplo el autor hace esto:
const DWORD D3DFVF_CVertex=D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_DIFFUSE;
const DWORD D3DFVF_CProcessedVertex=D3DFVF_XYZRHW | D3DFVF_TEX1 | D3DFVF_DIFFUSE;
void DrawScene()
{
// Clear the screen
g_pDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0 );
// Make it so we can draw stuff
g_pDevice->BeginScene();
// Tell it the source vertex buffer is g_pVertexBuffer
g_pDevice->SetStreamSource(0, g_pVertexBuffer, sizeof(CVertex));
// Tell it to process the source vertex buffer using the CVertex FVF
g_pDevice->SetVertexShader(D3DFVF_CVertex);
// Tell it to process the vertices, starting at vertex 0 in both the source and destination
// Buffers, processing all four vertices, and putting them into the processed vertices buffer.
g_pDevice->ProcessVertices(0, 0, 4, g_pProcessedVertexBuffer, NULL);
// Tell it to use our texture
g_pDevice->SetTexture(0, g_pTexture);
// Set the source vertex buffer to our processed vertices
g_pDevice->SetStreamSource(0, g_pProcessedVertexBuffer, sizeof(CProcessedVertex));
// Tell it to process the source vertex buffer using the CProcessedVertex FVF
g_pDevice->SetVertexShader(D3DFVF_CProcessedVertex);
// Draw the source vertex buffer
g_pDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
// Make it so we can't draw stuff
g_pDevice->EndScene();
// Put the back buffer onto the screen
g_pDevice->Present(NULL, NULL, NULL, NULL);
}
Parece un poco estupido pq solo hace una pasada,... pero la segunda pasada usaria el vertex buffer con los vertices ya procesados... (El autor insistia en que era un buen truco para usar lightmaps).
Citar
Pero voy a hacerte una reflexión..¿Para qué hacer varias pasadas si hoy en día TODAS las tarjetas soportan más de 4 texturas por ciclo y las buenas soportan 8?
No he dicho que no vaya a usar multitextura en aquellas tarjetas que la soporten... simplemente que en tarjetas como la mia (Banshee) me vendra de perlas. (pq me ahorro la segunda transformacion de los poligonos)
------------------
Ithaqua:
Supongo que querias decir que no haga nada por software que pueda hacer por hardware, ¿no?
En cuanto a los shaders (supongo que te refieres a los vertex shaders) no tengo ni zorra idea acerca de ellos, pero les echare un vistazo a ver si me sirven para lo que quiero :ojo: Asias
[ Este Mensaje fue editado por: Lord Trancos el 2002-05-02 15:09 ]
Las trasformaciones de los vertices se hacen cuando llamas a DrawPrimitive() (alguien me demuestre lo contrario !!), con lo que cada vez que la llamas D3d te trasformara los vertices.Ahora bien... existe una manera para que esto no ocurra... quizas usando D3DUSAGE_SOFTWAREPROCESSING en el CreateVertexBuffer(),o ,con D3DCREATE_PUREDEVICE en el CreateDevice(), pero aki ya tendras que investigarlo tu, por que es toda una rareza.
Euh... sí, quería decir al revés O:)
En cuanto a los shaders, me refiero al concepto de shader como material mas o menos complejo, no vertex/pixel shader.
En él vienen definidas las capas de que consta, y si acaso los efectos de cada una de ellas. El motor se encargaría de procesarlo según los recursos de los que disponga la tarjeta (principalmente, número de unidades de textura).
Usar las rutinas de transformacion de d3d para uso propio es generalmente una mala idea a menos que sea para renderizar posteriormente el VB target. En cualquier caso, si lo haces, procura mandar batches muy grandes de vertices, y usar el vertice de menor tamanyo posible. En general no recomiendo esto.
A estas alturas, hacer cualquier cosa a nivel de poligono es gastar el tiempo, usa tus propias rutinas de transformacion contra bounding volumes de objetos (o subdivisiones del mismo).
La forma que utiliza Lord Trancos sacada de aqui:
http://nexe.gamedev.net/Me parece la optima, en vistas a utilizar multitexturing (algo que hoy por hoy, con tarjetas que soportan 6 texturas por polígono de una sola pasada es más que necesario de implementar).
Sobre este tema:
"...lo cual dejó más tranquilo al Sr. Carmack ya que no era posible que las GF3/GF4 fuesen más rápidas que la Radeon 8500 renderizando esta última las 6 texturas por polígono (las que utiliza Doom III normalmente) en una sola pasada mientras que las de nVidia lo hace en 2 o incluso 3 pasadas..."
En
http://www.planetquake.com/digitalys/frameset.htmPersonalmente, utilizo la forma de Lord Trancos.
Pues si, no me acordaba de donde, pero es cierto que lo saque de ahi (aunque aun tengo el octree a medio montar, jejeje).
Sin embargo, como bien dicen los colegas, nos quedamos sin soporte de T&L por hardware,... ¿no?
Pues es cierto, ya no me parece tan óptimo :sonriendo:
Mirar esto: (punto 7)
http://www.hejl.com/faq/GeForceGPUD3D.htmy esto otro:
Hardware TnL Principles II
Be clever in your use of Vertex Buffers
Correct use of flags are critical
The more you tell us the more we know
But don't get too clever. Implementing your own round-robin scheme is the wrong way to handle it
Tuning for H/W is mostly the same but...
Almost never use ProcessVertices to help out
Sparse VBs don't hurt hardware (but S/W dies...)
[ Este Mensaje fue editado por: Loover el 2002-05-20 12:02 ]
"Don't use it for anything that you're going to draw! The typical use for ProcessVertices is to transform data which is used for bounding box tests or other tests for which the CPU needs access to post-transform data. If you are using a HAL (and not a T&L HAL) you need to use this for multi-pass effects to avoid repeatedly transforming the vertices."
Osea, que pa multipass en mi miserable Voodoo Banshe me lo aconsejan, pero para las tarjetas modernas me lo desancosejan.... vaya putada xDDD
To be or not to be....
Creo que por ahora lo implementare pensando en mi Banshee y despues ya lo montare pensando en el resto. De todos modos, el octree ya lo tengo hecho, y es independiente del API grafico, del modo que despues elija para dibujarlo, del formato del mesh, de si es indexeado o no.... blah blah blah
Por cierto, muy interesante el documento.
_________________
SaludoteZ!,
Lord Trancos -
http://www.dxlab.tk[ Este Mensaje fue editado por: Lord Trancos el 2002-05-20 12:27 ]