Advertisement
NightFox

Nintendo DS Dynamic Lighting

Aug 12th, 2013
371
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.04 KB | None | 0 0
  1. /*
  2. -------------------------------------------------
  3.  
  4.     Krystals DS
  5.  
  6.     Funciones de dibujado 3D
  7.  
  8.     Requiere DevkitARM
  9.     Requiere NightFox's Lib
  10.  
  11.     Codigo por Cesar Rincon "NightFox"
  12.     http://www.nightfoxandco.com
  13.     Inicio 08 de Septiembre del 2012
  14.  
  15.     (c) 2012 - 2013 NightFox & Co.
  16.  
  17. -------------------------------------------------
  18. */
  19.  
  20.  
  21.  
  22. /*
  23. -------------------------------------------------
  24.     Includes
  25. -------------------------------------------------
  26. */
  27.  
  28. // Includes C
  29. #include <stdio.h>
  30. // Includes propietarios NDS
  31. #include <nds.h>
  32. // Includes librerias propias
  33. #include <nf_lib.h>
  34. // Includes del juego
  35. #include "includes.h"
  36.  
  37.  
  38.  
  39. /*
  40. Metodos de la clase "CEngine3d"
  41. */
  42.  
  43. // Contructor clase CEngine3d
  44. CEngine3d::CEngine3d(void) {
  45.     // Debug
  46.     Engine3d->angle[0] = 0;
  47.     Engine3d->angle[1] = 0;
  48.     Engine3d->angle[2] = 0;
  49. }
  50.  
  51.  
  52.  
  53. // Destructor clase CEngine3d
  54. CEngine3d::~CEngine3d(void) {
  55. }
  56.  
  57.  
  58.  
  59. // Metodos globlales de la clase CEngine3d
  60. CEngine3d* Engine3d;
  61.  
  62.  
  63.  
  64. // Inicializa el Engine 3D
  65. void CEngine3d::Init3D(void) {
  66.  
  67.     // Habilita el 3D en la pantalla principal
  68.     videoSetMode(MODE_0_3D);
  69.  
  70.  
  71.     // *** Inicializa OpenGL ***
  72.  
  73.     // Inicializa el OpenGL de Libnds
  74.     glInit();
  75.  
  76.     // Define el tamaño de la ventana 3D (toda la pantalla)
  77.     glViewport(0, 0, 255, 191);
  78.  
  79.     // Configura la matriz de proyeccion
  80.     glMatrixMode(GL_PROJECTION);    // Selecciona la matriz
  81.     glLoadIdentity();
  82.  
  83.     // Configura la visual
  84.     gluPerspective(70, (256.0 / 192.0), 0.1, 40);       // Perspectiva
  85.  
  86.     // Posiciona la camara por defecto
  87.     gluLookAtf32(   0, 0, 0,                // Posicion de la camara
  88.                     0, 0, 0,                // Punto hacia el que miras
  89.                     0, (128 << 4), 0        // Normal
  90.                     );
  91.  
  92.     // Configura la matriz de visualizacion de modelos
  93.     glMatrixMode(GL_MODELVIEW);     // Selecciona la matriz
  94.     glLoadIdentity();               // Y reseteala
  95.  
  96.     // Configura el fondo
  97.     glClearColor(0, 0, 0, 0);       // Fondo transparente
  98.     glClearDepth(0x7FFF);           // Define la distancia de vision
  99.  
  100.     // Configura la iluminacion global mediante el color del poligono
  101.     glColor(RGB15(31, 31, 31));
  102.  
  103.     // Habilita la capa de dibujado
  104.     REG_DISPCNT |= (DISPLAY_BG0_ACTIVE);
  105.  
  106.     // *** Fin de la inicializacion OpenGL ***
  107.  
  108.  
  109.  
  110.     // Inicializa los fondos 2D en el main engine
  111.     NF_InitTiledBgSys(0);
  112.  
  113.     // Y habilita la capa de dibujado para el 3D en el main engine, poniendola al fondo
  114.     Engine3d->Layer3d(3);
  115.     NF_ShowBg(0, 0);
  116.  
  117. }
  118.  
  119.  
  120.  
  121. // Especifica en que capa se dibujara la escena 3d
  122. void CEngine3d::Layer3d(u8 layer) {
  123.  
  124.     // Resetea los BITS de control de prioridad en todos los fondos
  125.     REG_BG0CNT &= 0xfffc;       // Pon a 0 los bits 0 y 1 del registro
  126.     REG_BG1CNT &= 0xfffc;
  127.     REG_BG2CNT &= 0xfffc;
  128.     REG_BG3CNT &= 0xfffc;
  129.  
  130.     // Reordena todas las capas segun la solicitud
  131.     switch (layer) {
  132.         case 0:     // 3D en la capa 0
  133.             REG_BG0CNT += BG_PRIORITY_0;
  134.             REG_BG1CNT += BG_PRIORITY_1;
  135.             REG_BG2CNT += BG_PRIORITY_2;
  136.             REG_BG3CNT += BG_PRIORITY_3;
  137.             break;
  138.         case 1:     // 3D en la capa 1
  139.             REG_BG0CNT += BG_PRIORITY_1;
  140.             REG_BG1CNT += BG_PRIORITY_0;
  141.             REG_BG2CNT += BG_PRIORITY_2;
  142.             REG_BG3CNT += BG_PRIORITY_3;
  143.             break;
  144.         case 2:     // 3D en la capa 2
  145.             REG_BG0CNT += BG_PRIORITY_2;
  146.             REG_BG1CNT += BG_PRIORITY_0;
  147.             REG_BG2CNT += BG_PRIORITY_1;
  148.             REG_BG3CNT += BG_PRIORITY_3;
  149.             break;
  150.         case 3:     // 3D en la capa 3
  151.             REG_BG0CNT += BG_PRIORITY_3;
  152.             REG_BG1CNT += BG_PRIORITY_0;
  153.             REG_BG2CNT += BG_PRIORITY_1;
  154.             REG_BG3CNT += BG_PRIORITY_2;
  155.             break;
  156.         default:    // 3D en la capa 0
  157.             REG_BG0CNT += BG_PRIORITY_0;
  158.             REG_BG1CNT += BG_PRIORITY_1;
  159.             REG_BG2CNT += BG_PRIORITY_2;
  160.             REG_BG3CNT += BG_PRIORITY_3;
  161.             break;
  162.     }
  163.  
  164. }
  165.  
  166.  
  167.  
  168. // Prepara el mundo 3D
  169. void CEngine3d::Setup3dWorld(void) {
  170.  
  171.  
  172.     // Activas las opciones OpenGL de esta escena
  173.     // (Alpha blending, antialias, outline)
  174.     glEnable(GL_BLEND | GL_ANTIALIAS | GL_OUTLINE);
  175.  
  176.     // Habilita el OUTLINE
  177.      glClearPolyID(0);                          // Los poligonos con el ID 0, no tienen outline, usar el ID 1 para habilitarlo
  178.      glSetOutlineColor(0, RGB15(8, 8, 8));  //
  179.  
  180.     // Crea las luces
  181.     glLight(0, RGB15(31, 0, 0), floattov10(0.5), floattov10(-0.66), floattov10(-1.0));
  182.     glLight(1, RGB15(0, 24, 0), floattov10(-0.5), floattov10(-0.66), floattov10(-1.0));
  183.     glLight(2, RGB15(0, 0, 16), floattov10(0.66), floattov10(-0.5), floattov10(1.0));
  184.     glLight(3, RGB15(8, 8, 0), floattov10(-0.66), floattov10(0.5), floattov10(1.0));
  185.  
  186.  
  187.  
  188. }
  189.  
  190.  
  191.  
  192. // Renderiza la escena y mandala a la pantalla
  193. void CEngine3d::Render(void) {
  194.  
  195.     // Primero de todo, guarda la matriz de transformacion
  196.     glPushMatrix();
  197.  
  198.     // posiciona la camara
  199.     gluLookAtf32(   (128 << 4), (96 << 4), (128 << 4),      // Posicion
  200.                     (128 << 4), (96 << 4), 0,               // Look At
  201.                     0 , (128 << 4), 0);                     // Normal
  202.  
  203.     // Define el material a usar en el render
  204.     glMaterialf(GL_AMBIENT, RGB15(8, 8, 8));
  205.     glMaterialf(GL_DIFFUSE, RGB15(16, 16, 16));
  206.     glMaterialf(GL_SPECULAR, RGB15(24, 24, 24));
  207.     glMaterialf(GL_EMISSION, RGB15(0, 0, 0));
  208.  
  209.     // Define el formato de los poligonos a dibujar en esta fase
  210.     glPolyFmt(POLY_ALPHA(31) | POLY_CULL_BACK | POLY_FORMAT_LIGHT0 | POLY_FORMAT_LIGHT1 | POLY_FORMAT_LIGHT2 | POLY_FORMAT_LIGHT3 | POLY_ID(1));
  211.  
  212.  
  213.     /*
  214.         Ejecuta aqui todos los renders necesarios
  215.     */
  216.  
  217.     Engine3d->DrawGem(128, 96, 64, 64, 24, 8, Engine3d->angle[1], Engine3d->angle[2], 0);
  218.    
  219.     for (u8 i = 0; i < 3; i ++) {
  220.         Engine3d->angle[i] += i;
  221.         if (Engine3d->angle[i] > 511) Engine3d->angle[i] -= 512;
  222.     }
  223.  
  224.     // Recupera la matriz de transformacion original
  225.     glPopMatrix(1);
  226.  
  227.     // Manda la escena preparada para su renderizado al Engine 3D
  228.     glFlush(0);
  229.  
  230.     // Espera al sincronismo vertical
  231.     swiWaitForVBlank();
  232.  
  233. }
  234.  
  235.  
  236.  
  237. // Dibuja un cuadrado solido
  238. void CEngine3d::DrawSolidQuad(  s32 x1, s32 y1, s32 z1,         // Coordenadas Vertice 1 (arriba / izquierda)
  239.                                 s32 x2, s32 y2, s32 z2,         // Coordenadas Vertice 2 (abajo / izquierda)
  240.                                 s32 x3, s32 y3, s32 z3,         // Coordenadas Vertice 3 (abajo / derecha)
  241.                                 s32 x4, s32 y4, s32 z4,         // Coordenadas Vertice 4 (arriba / derecha)
  242.                                 float nx, float ny, float nz    // Normales de la cara
  243.                                 ) {
  244.     // Dibuja el cuadrado
  245.     glBegin(GL_QUAD);
  246.         // Normal de la cara
  247.         glNormal(NORMAL_PACK(floattov10(nx), floattov10(ny), floattov10(nz)));
  248.         // Vertice 1 - (superior izquierdo)
  249.         glVertex3v16(x1, y1, z1);
  250.         // Vertice 2 - (inferior izquierdo)
  251.         glVertex3v16(x2, y2, z2);
  252.         // Vertice 3 - (inferior derecho)
  253.         glVertex3v16(x3, y3, z3);
  254.         // Vertice 4 - (superior derecho)
  255.         glVertex3v16(x4, y4, z4);
  256.    
  257.    
  258. }
  259.  
  260.  
  261.  
  262. // Dibuja una Gema del color especificado
  263. void CEngine3d::DrawGem(s32 px, s32 py, s32 pz, s32 width, s32 height, s32 deep, s32 rx, s32 ry, s32 rz) {
  264.  
  265.     // Variables
  266.     u8 n = 0;
  267.  
  268.     // Crea el array de vectores para los vertices
  269.     Vector3* vertex[16];
  270.     for (n = 0; n < 16; n ++) {
  271.         vertex[n] = new Vector3();
  272.     }
  273.  
  274.     // Calcula el valor de cada vertice de la parte frontal del cuerto de la gema
  275.     vertex[0]->Set((px - (width >> 1)), (py + (height >> 1)), (pz + (deep >> 1)));
  276.     vertex[1]->Set((px - (width >> 1)), (py - (height >> 1)), (pz + (deep >> 1)));
  277.     vertex[2]->Set((px + (width >> 1)), (py - (height >> 1)), (pz + (deep >> 1)));
  278.     vertex[3]->Set((px + (width >> 1)), (py + (height >> 1)), (pz + (deep >> 1)));
  279.  
  280.     // Calcula el valor de cada vertice de la parte anterior del cuerto de la gema
  281.     vertex[4]->Set((px - (width >> 1)), (py + (height >> 1)), (pz - (deep >> 1)));
  282.     vertex[5]->Set((px - (width >> 1)), (py - (height >> 1)), (pz - (deep >> 1)));
  283.     vertex[6]->Set((px + (width >> 1)), (py - (height >> 1)), (pz - (deep >> 1)));
  284.     vertex[7]->Set((px + (width >> 1)), (py + (height >> 1)), (pz - (deep >> 1)));
  285.  
  286.     // Aplica si es necesario la transformacion de la matriz
  287.     // Muevete al centro
  288.     glTranslatef32((px << 4), (py << 4), (pz << 4));
  289.     // Aplica la rotacion
  290.     glRotateXi((rx << 6));
  291.     glRotateYi((ry << 6));
  292.     glRotateZi((rz << 6));
  293.     // Vuelve a la posicion original
  294.     glTranslatef32(-(px << 4), -(py << 4), -(pz << 4));
  295.  
  296.     // Dibuja el objeto
  297.     // Cara frontal
  298.     Engine3d->DrawSolidQuad(    vertex[0]->x, vertex[0]->y, vertex[0]->z,
  299.                                 vertex[1]->x, vertex[1]->y, vertex[1]->z,
  300.                                 vertex[2]->x, vertex[2]->y, vertex[2]->z,
  301.                                 vertex[3]->x, vertex[3]->y, vertex[3]->z,
  302.                                 0, 0, 1.0);
  303.  
  304.     // Cara derecha
  305.     Engine3d->DrawSolidQuad(    vertex[3]->x, vertex[3]->y, vertex[3]->z,
  306.                                 vertex[2]->x, vertex[2]->y, vertex[2]->z,
  307.                                 vertex[6]->x, vertex[6]->y, vertex[6]->z,
  308.                                 vertex[7]->x, vertex[7]->y, vertex[7]->z,
  309.                                 1.0, 0, 0);
  310.  
  311.     // Cara posterior
  312.     Engine3d->DrawSolidQuad(    vertex[7]->x, vertex[7]->y, vertex[7]->z,
  313.                                 vertex[6]->x, vertex[6]->y, vertex[6]->z,
  314.                                 vertex[5]->x, vertex[5]->y, vertex[5]->z,
  315.                                 vertex[4]->x, vertex[4]->y, vertex[4]->z,
  316.                                 0, 0, -1.0);
  317.  
  318.     // Cara izquierda
  319.     Engine3d->DrawSolidQuad(    vertex[4]->x, vertex[4]->y, vertex[4]->z,
  320.                                 vertex[5]->x, vertex[5]->y, vertex[5]->z,
  321.                                 vertex[1]->x, vertex[1]->y, vertex[1]->z,
  322.                                 vertex[0]->x, vertex[0]->y, vertex[0]->z,
  323.                                 -1.0, 0, 0);
  324.  
  325.     // Cara Superior
  326.     Engine3d->DrawSolidQuad(    vertex[4]->x, vertex[4]->y, vertex[4]->z,
  327.                                 vertex[0]->x, vertex[0]->y, vertex[0]->z,
  328.                                 vertex[3]->x, vertex[3]->y, vertex[3]->z,
  329.                                 vertex[7]->x, vertex[7]->y, vertex[7]->z,
  330.                                 0, 1.0, 0);
  331.  
  332.     // Cara Inferior
  333.     Engine3d->DrawSolidQuad(    vertex[1]->x, vertex[1]->y, vertex[1]->z,
  334.                                 vertex[5]->x, vertex[5]->y, vertex[5]->z,
  335.                                 vertex[6]->x, vertex[6]->y, vertex[6]->z,
  336.                                 vertex[2]->x, vertex[2]->y, vertex[2]->z,
  337.                                 0, -1.0, 0);
  338.  
  339.     // Elimina los objetos creados
  340.     for (n = 0; n < 16; n ++) {
  341.         delete vertex[n];
  342.         vertex[n] = NULL;
  343.     }
  344.  
  345. }
  346.  
  347.  
  348.  
  349. // Conversion de color a RGB32
  350. u32 CEngine3d::RGB32(u8 r, u8 g, u8 b) {
  351.  
  352.     return ((r << 16) | (g << 8) | (b));
  353.  
  354. }
  355.  
  356.  
  357.  
  358.  
  359. /*
  360. Metodos de la clase "Vector3"
  361. */
  362.  
  363. // Contructor
  364. Vector3::Vector3(void) {
  365.  
  366.     // Inicializa los componentes del Vector3 a 0
  367.     x = 0;
  368.     y = 0;
  369.     z = 0;
  370.  
  371. }
  372.  
  373. // Destructor
  374. Vector3::~Vector3(void) {
  375. }
  376.  
  377.  
  378. // Asigna las coordenadas al Vector3 (Ya convertidas en coordenadas de pantalla)
  379. void Vector3::Set(s32 px, s32 py, s32 pz) {
  380.  
  381.     x = (px << 4);
  382.     y = (py << 4);
  383.     z = (pz << 4);
  384.  
  385. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement