Estoy haciendo una rutina para crear terrenos usando mapas de altura. Hasta ahora llevo esto:
//-----------------------------------------------------------------------------
// ConstruyeTerrenoConMDA
// Lee un mapa de alturas (MDA), de dimensiones Filas x Columnas, y genera una
// superficie con los vértices calculados.
//-----------------------------------------------------------------------------
void ConstruyeTerrenoConMDA (char Mapa [], int Filas, int Columnas,
LPDIRECT3DVERTEXBUFFER8 EnSuperficie)
{
// Indican la posición de la altura actual en el mapa.
int Fila, Columna;
// Apunta a la altura actual en el mapa.
char *Altura;
// Inicia apuntando a la primera altura.
Altura = &Mapa [0];
for (Fila = 0; Fila < Filas; Fila++)
for (Columna = 0; Columna < Columnas; Columna++)
{
// Agrega el vértice a la superficie.
...
// Pasa a la siguiente altura.
Altura++;
}
}
Voy a seguir implementando, pero me gustaría escuchar sus sugerencias. Debe haber alguien aquí con experiencia en el tema.
Creo que estoy un poco perdido sobre la ruta que debo seguir para crear la superficie. En Delphi ya habia creado algunas superficies, pero siempre tuve la duda si lo estaba haciendo de la forma correcta. Segun la documentacion de DX, hay que hacer poligonos con forma de N. Lo que yo hacía era rastrear las filas haciendo N's de la siguiente manera:
+---+---+---+---+
hacia | 1 | 3 | 5 | 7 |
la +---+---+---+---+
derecha | 2 | 4 | 6 | 8 |
+---+---+---+---+
| 15| 13| 11| 9 | hacia
+---+---+---+---+ la
| 16| 14| 12| 10| izquierda
+---+---+---+---+
Esto tiene el problema de que hay que invertir las normales según la dirección. Esta bien o hay una forma mejor?
Je, jeé, ya logré hacerlo de una manera más sencilla que como tenía planeado, sólo tirando líneas verticales entre las alturas del mapa:
//-----------------------------------------------------------------------------
// ConstruyeTerrenoConMDA
// Lee un mapa de alturas (MDA), de dimensiones Filas x Columnas, y genera una
// superficie con los vértices calculados.
//-----------------------------------------------------------------------------
void ConstruyeTerrenoConMDA (char Mapa [], int Filas, int Columnas,
LPDIRECT3DVERTEXBUFFER8 EnSuperficie)
{
// Indican la posición de la altura actual en el mapa.
int Fila, Columna;
// Apuntan a las alturas que forman una línea vertical del polígono.
char *AlturaA, *AlturaB;
// Vértice calculado.
VerticeDeTerreno Vertice;
// Inicia apuntando a las primeras alturas, la de arriba y la de abajo.
AlturaA = &Mapa [0];
AlturaB = &Mapa [Columnas];
for (Fila = 0; Fila < Filas; Fila++)
for (Columna = 0; Columna < Columnas; Columna++)
{
// Calcula el vértice de arriba.
Vertice.X = Columna;
Vertice.Z = Fila;
Vertice.Y = *AlturaA;
// Agrega el vértice a la superficie.
...
// Calcula el vértice de abajo.
Vertice.X = Columna;
Vertice.Z = Fila + 1;
Vertice.Y = *AlturaB;
// Agrega el vértice a la superficie.
...
// Pasa a las siguientes alturas.
AlturaA++;
AlturaB++;
}
}
:riendo: Cómo les quedó el ojo?
Por cierto que Visualín me tira unos warnings por la conversión de char a float, hay forma de quitarmelos de encima??
Deberías utilizar un IndexBuffer, eso haría tu render mucho más rápido.
En qué consiste el Index Buffer?
dracula:
¿es para hacerlo más rápido o para ahorrar memoria?
Ahora que sale lo de los indexs buffers...
Son realmente utiles? Supongo que para lo unico que sirve es para no tener que multiplicar varias veces el mismo punto por una matriz.
Eso en teoria lo hace todo un poco mas rapido. Pero si el punto se multiplica por la matriz en el hardware (como supongo que hacen todas las tarjetas hoy en dia) entonces no implicara ninguna mejora de velocidad, no?
Aunque ahora que caigo, si usas animaciones con bones por ejemplo, los indices si que afectarian un poquillo a la velocidad, ya que se hace por software.
PD: para arreglar lo del warning al hacer conversion char a float, haz un Vertice.Y = float(*AlturaA);
Los IB son imprescindibles. Optimizan mucho el envio de datos a las tarjetas, eso es lo que yo he deducido por mis pruebas. Además te permiten utilizar Octrees modificando tan solo los IB, sin tocar para nada los VB.
Incluso hay optimizaciones muy importantes que permiten utilizar la caché de vértices de las tarjetas que obligan a utilizar los IB.
En tu caso, además si quieres que el terreno vaya creciendo, por ejemplo, hasta que cada y llegue a la altura que le corresponda(un efecto muy bonito), sólo deberás modificar la y de un vértice, en lugar de modificarla tantas veces como triángulos utilicen este vértice.
Ya perfeccioné mi rutina para que genere el terreno en cualquier buffer:
//-----------------------------------------------------------------------------
// ConstruyeTerrenoConMDA
// Lee un mapa de alturas (MDA) de dimensiones filas x columnas, calcula los
// vértices para cada altura y llena la primitiva del terreno.
//-----------------------------------------------------------------------------
void ConstruyeTerrenoConMDA (char* Mapa, int Filas, int Columnas,
VerticeDeTerreno* Terreno)
{
// Indican la posición actual en el mapa.
int Fila, Columna;
// Apuntan a las alturas que forman una línea vertical para cada polígono.
char* AlturaA;
char* AlturaB;
// Inicia apuntando a las primeras alturas.
AlturaA = &Mapa [0];
AlturaB = &Mapa [Columnas];
for (Fila = 0; Fila < Filas - 1; Fila++)
for (Columna = 0; Columna < Columnas; Columna++)
{
// Calcula el vértice de arriba.
Terreno->X = Columna;
Terreno->Z = Fila;
Terreno->Y = *AlturaA;
Terreno++;
// Calcula el vértice de abajo.
Terreno->X = Columna;
Terreno->Z = Fila + 1;
Terreno->Y = *AlturaB;
Terreno++;
// Continua con las siguientes alturas.
AlturaA++;
AlturaB++;
}
}
Ahora, alguien sabe como puedo calcular las normales para cada vértice?
Gracias sam por el tip de conversión. No sabía que se podía hacer float (algo), siempre había visto que usaban (float) algo. Quien sabe qué otras maravillas guardará este lenguaje en sus entrañas.
Acabo de agregar factores de escalamiento:
Terreno->X = Columna * EX;
Terreno->Z = Fila * EZ;
Terreno->Y = float (*AlturaA) * EY;
En C se hace (float)numerito_int y en C++ se puede hacer tanto la forma del C como float(numerito_int), a mi me gusta mas la forma del C++, queda mas nitida.
Citar
El 2002-09-05 16:37, Cronodragón escribió:
Ahora, alguien sabe como puedo calcular las normales para cada vértice?
En este enlace hay un tutorial sobre generacion de terrenos, incluyendo una parte de Heith Maps, tambien tecnicas de smoth, etc y por su puesto cubre lo de las normales :ojo:
http://www.lighthouse3d.com/opengl/terrain...p3?introduction
Creo que habia que sacar una media de las normales de las caras en las que participaba el vértice.