Advertisement
NightFox

New render ngine

Jun 24th, 2025
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.18 KB | None | 0 0
  1. void NGN_Render::TiledBgGeometry(NGN_TiledBg* bg) {
  2.  
  3.     // Rotacion y FLIP
  4.     _rotation = 0.0f;
  5.     _flip = SDL_FLIP_NONE;
  6.  
  7.     // Define las areas de origen y destino
  8.     _source = {0, 0, 0, 0};
  9.     _destination = {0, 0, 0, 0};
  10.  
  11.     // Area del render
  12.     Size2I32 render_area;
  13.     if (ngn->graphics->current_viewport < 0) {
  14.         render_area.width = bg->bb_size.width;
  15.         render_area.height = bg->bb_size.height;
  16.     } else {
  17.         render_area.width = (ngn->graphics->render_resolution.width + (bg->tile_size << 1));
  18.         render_area.height = (ngn->graphics->render_resolution.height  + (bg->tile_size << 1));
  19.     }
  20.  
  21.     // Analiza si es necesario redibujar la textura
  22.     int32_t current_tile_x = std::floor(bg->position.x / (float)bg->tile_size);
  23.     int32_t current_tile_y = std::floor(bg->position.y / (float)bg->tile_size);
  24.     int32_t last_tile_x = std::floor(bg->last_position.x / (float)bg->tile_size);
  25.     int32_t last_tile_y = std::floor(bg->last_position.y / (float)bg->tile_size);
  26.  
  27.     // Si hay desplazamiento o se ha forzado, redibuja la textura en el backbuffer
  28.     if ((current_tile_x != last_tile_x) || (current_tile_y != last_tile_y) || (ngn->graphics->current_viewport != bg->last_viewport) || !bg->tile_mode || ngn->graphics->force_redraw) {
  29.  
  30.         // Calcula el centro del tile
  31.         _center->x = _center->y = ((float)bg->tile_size / 2.0f);
  32.  
  33.         // Parametros del mapa
  34.         int32_t map_x = 0;
  35.         int32_t map_y = 0;
  36.         int32_t map_w = std::floor(bg->map_size.width / bg->tile_size);
  37.         int32_t map_h = std::floor(bg->map_size.height / bg->tile_size);
  38.  
  39.         // Tileset
  40.         uint32_t id, tile, flip;      // Informacion
  41.  
  42.         // Parametros de lectura del tile
  43.         _source.w = _source.h = bg->tile_size;
  44.         // Parametros de escritura del tile
  45.         _destination.w = _destination.h = bg->tile_size;
  46.  
  47.         // Informa al renderer que la textura "backbuffer" es su destino
  48.         SDL_SetRenderTarget(ngn->graphics->renderer, bg->backbuffer);
  49.  
  50.         // Borra el contenido de la textura actual
  51.         SDL_SetRenderDrawColor(ngn->graphics->renderer, 0x00, 0x00, 0x00, 0x00);
  52.         SDL_SetTextureBlendMode(bg->backbuffer, SDL_BLENDMODE_BLEND);
  53.         SDL_SetTextureAlphaMod(bg->backbuffer, 0x00);
  54.         SDL_RenderFillRect(ngn->graphics->renderer, nullptr);
  55.  
  56.         // Tamaño del area de dibujado
  57.         int32_t tile_last_x = (std::floor(render_area.width / bg->tile_size) + 2);      // +2 soluciona el encage en resoluciones anamorficas
  58.         int32_t tile_last_y = (std::floor(render_area.height / bg->tile_size) + 2);
  59.  
  60.         // Calcula el offset del dibujado de los tiles
  61.         int32_t get_tile_x = 0, get_tile_y = 0;
  62.  
  63.         // Prepara el vector para almacenar los vertices
  64.         std::vector<SDL_Vertex> vertex;
  65.         vertex.reserve((tile_last_x * tile_last_y * 6));
  66.  
  67.         // Tamaño del atlas
  68.         int32_t atlas_width = 0, atlas_height = 0;
  69.         SDL_QueryTexture(bg->bgdata->tiles_atlas, NULL, NULL, &atlas_width, &atlas_height);
  70.         uint32_t tiles_per_row = (atlas_width / bg->tile_size);
  71.  
  72.         // Recorre la pantalla para dibujar el fondo
  73.         for (map_y = 0; map_y < tile_last_y; map_y ++) {
  74.  
  75.             // Tile Y
  76.             get_tile_y = (map_y + current_tile_y);
  77.             // Si estas fuera del rango...
  78.             if ((get_tile_y < 0) || (get_tile_y >= map_h)) continue;
  79.  
  80.             for (map_x = 0; map_x < tile_last_x; map_x ++) {
  81.  
  82.                 // Tile X
  83.                 get_tile_x = (map_x + current_tile_x);
  84.                 // Si estas fuera del rango...
  85.                 if ((get_tile_x < 0) || (get_tile_x >= map_w)) continue;
  86.  
  87.                 // ID de tile
  88.                 id = (((get_tile_y * map_w) + get_tile_x) << 2);      // * 4 bytes
  89.  
  90.                 // Numero de Tile
  91.                 tile = bg->bgdata->tmap[id];
  92.                 tile |= (bg->bgdata->tmap[(id + 1)] << 8);
  93.                 tile |= (bg->bgdata->tmap[(id + 2)] << 16);
  94.  
  95.                 // Si el tile ES TRANSPARENTE (no es el primero del mapa), ignora el dibujado
  96.                 if (tile == 0) continue;
  97.  
  98.                 // Orientacion del tile
  99.                 flip = bg->bgdata->tmap[(id + 3)];
  100.  
  101.                 // Coordenadas de origen del tile DENTRO del atlas
  102.                 // Esto es un ejemplo, necesitarás tu propia lógica para buscar el tile
  103.                 float src_x = (float)((tile % tiles_per_row) * bg->tile_size);
  104.                 float src_y = (float)((tile / tiles_per_row) * bg->tile_size);
  105.  
  106.                 // Coordenadas normalizadas (0.0 a 1.0) para los vértices
  107.                 float u1 = (src_x / (float)atlas_width);
  108.                 float v1 = (src_y / (float)atlas_height);
  109.                 float u2 = ((src_x + bg->tile_size) / (float)atlas_width);
  110.                 float v2 = ((src_y + bg->tile_size) / (float)atlas_height);
  111.  
  112.                 // Coordenadas de destino en el backbuffer
  113.                 float dest_x = (float)(map_x * bg->tile_size);
  114.                 float dest_y = (float)(map_y * bg->tile_size);
  115.  
  116.                 // Definimos las 4 esquinas de las coordenadas UV del tile original
  117.                 SDL_FPoint uv_tl = {u1, v1};    // Top-Left
  118.                 SDL_FPoint uv_tr = {u2, v1};    // Top-Right
  119.                 SDL_FPoint uv_bl = {u1, v2};    // Bottom-Left
  120.                 SDL_FPoint uv_br = {u2, v2};    // Bottom-Right
  121.  
  122.                 // Parametros del FLIP del tile
  123.                 switch (flip) {
  124.                     case 1: // Normal
  125.                         // No hacer nada
  126.                         break;
  127.                     case 2: // Flip H
  128.                         std::swap(uv_tl, uv_tr);
  129.                         std::swap(uv_bl, uv_br);
  130.                         break;
  131.                     case 4: // Flip V
  132.                         std::swap(uv_tl, uv_bl);
  133.                         std::swap(uv_tr, uv_br);
  134.                         break;
  135.                     case 8: // 180º (Flip H + Flip V)
  136.                         std::swap(uv_tl, uv_br);
  137.                         std::swap(uv_tr, uv_bl);
  138.                         break;
  139.                     case 16: // 90º CW (Rotar a la derecha)
  140.                         {
  141.                             SDL_FPoint temp = uv_tl;
  142.                             uv_tl = uv_bl;
  143.                             uv_bl = uv_br;
  144.                             uv_br = uv_tr;
  145.                             uv_tr = temp;
  146.                         }
  147.                         break;
  148.                     case 32: // 90º CCW (Rotar a la izquierda)
  149.                         {
  150.                             SDL_FPoint temp = uv_tl;
  151.                             uv_tl = uv_tr;
  152.                             uv_tr = uv_br;
  153.                             uv_br = uv_bl;
  154.                             uv_bl = temp;
  155.                         }
  156.                         break;
  157.                 }
  158.  
  159.                 // Crear los 6 vertices para el quad con las UVs ya transformadas
  160.                 // Triangulo 1
  161.                 vertex.push_back({{dest_x, dest_y}, {255,255,255,255}, uv_tl });
  162.                 vertex.push_back({{(dest_x + bg->tile_size), dest_y}, {255,255,255,255}, uv_tr});
  163.                 vertex.push_back({{dest_x, (dest_y + bg->tile_size)}, {255,255,255,255}, uv_bl});
  164.                 // Triangulo 2
  165.                 vertex.push_back({{(dest_x + bg->tile_size), dest_y}, {255,255,255,255}, uv_tr});
  166.                 vertex.push_back({{(dest_x + bg->tile_size), (dest_y + bg->tile_size)}, {255,255,255,255}, uv_br});
  167.                 vertex.push_back({{dest_x, (dest_y + bg->tile_size)}, {255,255,255,255}, uv_bl});
  168.  
  169.             }
  170.         }
  171.  
  172.         // Render de los tiles del atlas en una textura
  173.         if (!vertex.empty()) {
  174.             SDL_RenderGeometry(
  175.                 ngn->graphics->renderer,
  176.                 bg->bgdata->tiles_atlas,
  177.                 vertex.data(),
  178.                 vertex.size(),
  179.                 nullptr,
  180.                 0
  181.             );
  182.         }
  183.  
  184.         // Restaura el render al seleccionado
  185.         ngn->graphics->RenderToSelected();
  186.  
  187.     }
  188.  
  189.     // Calculo del alpha del fondo
  190.     _alpha = bg->alpha;
  191.     if (_alpha < 0) {
  192.         _alpha = 0;
  193.     } else if (_alpha > 0xFF) {
  194.         _alpha = 0xFF;
  195.     }
  196.     SDL_SetTextureBlendMode(bg->backbuffer, bg->blend_mode);
  197.     SDL_SetTextureAlphaMod(bg->backbuffer, (uint8_t)_alpha);
  198.  
  199.     // Color mod
  200.     if (bg->NewTint()) SDL_SetTextureColorMod(bg->backbuffer, bg->tint_color.r, bg->tint_color.g, bg->tint_color.b);
  201.  
  202.     // Define los puntos de entrada y salida de la textura
  203.     _source.x = 0; _source.y = 0; _source.w = render_area.width; _source.h = render_area.height;
  204.     _destination.w = render_area.width;
  205.     _destination.h = render_area.height;
  206.     _destination.x = -((int32_t)bg->position.x % bg->tile_size);
  207.     _destination.y = -((int32_t)bg->position.y % bg->tile_size);
  208.  
  209.     // Envia el backbuffer al renderer
  210.     SDL_RenderCopy(ngn->graphics->renderer, bg->backbuffer, &_source, &_destination);
  211.  
  212.     // Guarda la ubicacion del fondo para el siguiente frame
  213.     bg->last_position.x = bg->position.x;
  214.     bg->last_position.y = bg->position.y;
  215.     bg->last_viewport = ngn->graphics->current_viewport;
  216.     bg->tile_mode = true;
  217.  
  218. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement