Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- void NGN_Render::TiledBgGeometry(NGN_TiledBg* bg) {
- // Rotacion y FLIP
- _rotation = 0.0f;
- _flip = SDL_FLIP_NONE;
- // Define las areas de origen y destino
- _source = {0, 0, 0, 0};
- _destination = {0, 0, 0, 0};
- // Area del render
- Size2I32 render_area;
- if (ngn->graphics->current_viewport < 0) {
- render_area.width = bg->bb_size.width;
- render_area.height = bg->bb_size.height;
- } else {
- render_area.width = (ngn->graphics->render_resolution.width + (bg->tile_size << 1));
- render_area.height = (ngn->graphics->render_resolution.height + (bg->tile_size << 1));
- }
- // Analiza si es necesario redibujar la textura
- int32_t current_tile_x = std::floor(bg->position.x / (float)bg->tile_size);
- int32_t current_tile_y = std::floor(bg->position.y / (float)bg->tile_size);
- int32_t last_tile_x = std::floor(bg->last_position.x / (float)bg->tile_size);
- int32_t last_tile_y = std::floor(bg->last_position.y / (float)bg->tile_size);
- // Si hay desplazamiento o se ha forzado, redibuja la textura en el backbuffer
- 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) {
- // Calcula el centro del tile
- _center->x = _center->y = ((float)bg->tile_size / 2.0f);
- // Parametros del mapa
- int32_t map_x = 0;
- int32_t map_y = 0;
- int32_t map_w = std::floor(bg->map_size.width / bg->tile_size);
- int32_t map_h = std::floor(bg->map_size.height / bg->tile_size);
- // Tileset
- uint32_t id, tile, flip; // Informacion
- // Parametros de lectura del tile
- _source.w = _source.h = bg->tile_size;
- // Parametros de escritura del tile
- _destination.w = _destination.h = bg->tile_size;
- // Informa al renderer que la textura "backbuffer" es su destino
- SDL_SetRenderTarget(ngn->graphics->renderer, bg->backbuffer);
- // Borra el contenido de la textura actual
- SDL_SetRenderDrawColor(ngn->graphics->renderer, 0x00, 0x00, 0x00, 0x00);
- SDL_SetTextureBlendMode(bg->backbuffer, SDL_BLENDMODE_BLEND);
- SDL_SetTextureAlphaMod(bg->backbuffer, 0x00);
- SDL_RenderFillRect(ngn->graphics->renderer, nullptr);
- // Tamaño del area de dibujado
- int32_t tile_last_x = (std::floor(render_area.width / bg->tile_size) + 2); // +2 soluciona el encage en resoluciones anamorficas
- int32_t tile_last_y = (std::floor(render_area.height / bg->tile_size) + 2);
- // Calcula el offset del dibujado de los tiles
- int32_t get_tile_x = 0, get_tile_y = 0;
- // Prepara el vector para almacenar los vertices
- std::vector<SDL_Vertex> vertex;
- vertex.reserve((tile_last_x * tile_last_y * 6));
- // Tamaño del atlas
- int32_t atlas_width = 0, atlas_height = 0;
- SDL_QueryTexture(bg->bgdata->tiles_atlas, NULL, NULL, &atlas_width, &atlas_height);
- uint32_t tiles_per_row = (atlas_width / bg->tile_size);
- // Recorre la pantalla para dibujar el fondo
- for (map_y = 0; map_y < tile_last_y; map_y ++) {
- // Tile Y
- get_tile_y = (map_y + current_tile_y);
- // Si estas fuera del rango...
- if ((get_tile_y < 0) || (get_tile_y >= map_h)) continue;
- for (map_x = 0; map_x < tile_last_x; map_x ++) {
- // Tile X
- get_tile_x = (map_x + current_tile_x);
- // Si estas fuera del rango...
- if ((get_tile_x < 0) || (get_tile_x >= map_w)) continue;
- // ID de tile
- id = (((get_tile_y * map_w) + get_tile_x) << 2); // * 4 bytes
- // Numero de Tile
- tile = bg->bgdata->tmap[id];
- tile |= (bg->bgdata->tmap[(id + 1)] << 8);
- tile |= (bg->bgdata->tmap[(id + 2)] << 16);
- // Si el tile ES TRANSPARENTE (no es el primero del mapa), ignora el dibujado
- if (tile == 0) continue;
- // Orientacion del tile
- flip = bg->bgdata->tmap[(id + 3)];
- // Coordenadas de origen del tile DENTRO del atlas
- // Esto es un ejemplo, necesitarás tu propia lógica para buscar el tile
- float src_x = (float)((tile % tiles_per_row) * bg->tile_size);
- float src_y = (float)((tile / tiles_per_row) * bg->tile_size);
- // Coordenadas normalizadas (0.0 a 1.0) para los vértices
- float u1 = (src_x / (float)atlas_width);
- float v1 = (src_y / (float)atlas_height);
- float u2 = ((src_x + bg->tile_size) / (float)atlas_width);
- float v2 = ((src_y + bg->tile_size) / (float)atlas_height);
- // Coordenadas de destino en el backbuffer
- float dest_x = (float)(map_x * bg->tile_size);
- float dest_y = (float)(map_y * bg->tile_size);
- // Definimos las 4 esquinas de las coordenadas UV del tile original
- SDL_FPoint uv_tl = {u1, v1}; // Top-Left
- SDL_FPoint uv_tr = {u2, v1}; // Top-Right
- SDL_FPoint uv_bl = {u1, v2}; // Bottom-Left
- SDL_FPoint uv_br = {u2, v2}; // Bottom-Right
- // Parametros del FLIP del tile
- switch (flip) {
- case 1: // Normal
- // No hacer nada
- break;
- case 2: // Flip H
- std::swap(uv_tl, uv_tr);
- std::swap(uv_bl, uv_br);
- break;
- case 4: // Flip V
- std::swap(uv_tl, uv_bl);
- std::swap(uv_tr, uv_br);
- break;
- case 8: // 180º (Flip H + Flip V)
- std::swap(uv_tl, uv_br);
- std::swap(uv_tr, uv_bl);
- break;
- case 16: // 90º CW (Rotar a la derecha)
- {
- SDL_FPoint temp = uv_tl;
- uv_tl = uv_bl;
- uv_bl = uv_br;
- uv_br = uv_tr;
- uv_tr = temp;
- }
- break;
- case 32: // 90º CCW (Rotar a la izquierda)
- {
- SDL_FPoint temp = uv_tl;
- uv_tl = uv_tr;
- uv_tr = uv_br;
- uv_br = uv_bl;
- uv_bl = temp;
- }
- break;
- }
- // Crear los 6 vertices para el quad con las UVs ya transformadas
- // Triangulo 1
- vertex.push_back({{dest_x, dest_y}, {255,255,255,255}, uv_tl });
- vertex.push_back({{(dest_x + bg->tile_size), dest_y}, {255,255,255,255}, uv_tr});
- vertex.push_back({{dest_x, (dest_y + bg->tile_size)}, {255,255,255,255}, uv_bl});
- // Triangulo 2
- vertex.push_back({{(dest_x + bg->tile_size), dest_y}, {255,255,255,255}, uv_tr});
- vertex.push_back({{(dest_x + bg->tile_size), (dest_y + bg->tile_size)}, {255,255,255,255}, uv_br});
- vertex.push_back({{dest_x, (dest_y + bg->tile_size)}, {255,255,255,255}, uv_bl});
- }
- }
- // Render de los tiles del atlas en una textura
- if (!vertex.empty()) {
- SDL_RenderGeometry(
- ngn->graphics->renderer,
- bg->bgdata->tiles_atlas,
- vertex.data(),
- vertex.size(),
- nullptr,
- 0
- );
- }
- // Restaura el render al seleccionado
- ngn->graphics->RenderToSelected();
- }
- // Calculo del alpha del fondo
- _alpha = bg->alpha;
- if (_alpha < 0) {
- _alpha = 0;
- } else if (_alpha > 0xFF) {
- _alpha = 0xFF;
- }
- SDL_SetTextureBlendMode(bg->backbuffer, bg->blend_mode);
- SDL_SetTextureAlphaMod(bg->backbuffer, (uint8_t)_alpha);
- // Color mod
- if (bg->NewTint()) SDL_SetTextureColorMod(bg->backbuffer, bg->tint_color.r, bg->tint_color.g, bg->tint_color.b);
- // Define los puntos de entrada y salida de la textura
- _source.x = 0; _source.y = 0; _source.w = render_area.width; _source.h = render_area.height;
- _destination.w = render_area.width;
- _destination.h = render_area.height;
- _destination.x = -((int32_t)bg->position.x % bg->tile_size);
- _destination.y = -((int32_t)bg->position.y % bg->tile_size);
- // Envia el backbuffer al renderer
- SDL_RenderCopy(ngn->graphics->renderer, bg->backbuffer, &_source, &_destination);
- // Guarda la ubicacion del fondo para el siguiente frame
- bg->last_position.x = bg->position.x;
- bg->last_position.y = bg->position.y;
- bg->last_viewport = ngn->graphics->current_viewport;
- bg->tile_mode = true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement