From 68eb9c10c823de83a230ca60f19818b783035bbe Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Tue, 14 Feb 2023 14:02:47 +0100 Subject: [PATCH] Tessellate faces into bigger chunks when texture repeating is an option. This is kept conservative at just 2x2 cell sizes, because bigger polygons with more repeats will cause more texture warping and geometry glitching. This is already the biggest gain. --- tesselate.cpp | 14 +++++++++----- texture.cpp | 7 +++++-- texture.h | 2 +- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/tesselate.cpp b/tesselate.cpp index 1c7ed28..bb9c4c1 100644 --- a/tesselate.cpp +++ b/tesselate.cpp @@ -4,6 +4,8 @@ #include "gpc.h" #include "matrix.h" +bool texture_isRepeatable(const miptex_t* miptex); + std::vector Tesselator::tesselateFace(const face_t* face) { std::vector polygons; @@ -56,9 +58,11 @@ std::vector Tesselator::tesselateFace(const face_t* face) } // Create a virtual grid at the texture bounds and iterate over each cell to break up the face into repeating tiles - for (double y = floor(minT); y <= ceil(maxT); y += 1.0) + double cellSize = texture_isRepeatable(miptex) ? 2.0 : 1.0; + + for (double y = floor(minT); y <= ceil(maxT); y += cellSize) { - for (double x = floor(minS); x <= ceil(maxS); x += 1.0) + for (double x = floor(minS); x <= ceil(maxS); x += cellSize) { // Create a square polygon that covers the entire cell gpc_polygon cell = { 0 }; @@ -66,9 +70,9 @@ std::vector Tesselator::tesselateFace(const face_t* face) cell_bounds.num_vertices = 4; cell_bounds.vertex = (gpc_vertex*)malloc(4 * sizeof(gpc_vertex)); cell_bounds.vertex[0] = gpc_vertex{ x, y }; - cell_bounds.vertex[1] = gpc_vertex{ x, y + 1.0 }; - cell_bounds.vertex[2] = gpc_vertex{ x + 1.0, y + 1.0 }; - cell_bounds.vertex[3] = gpc_vertex{ x + 1.0, y }; + cell_bounds.vertex[1] = gpc_vertex{ x, y + cellSize }; + cell_bounds.vertex[2] = gpc_vertex{ x + cellSize, y + cellSize }; + cell_bounds.vertex[3] = gpc_vertex{ x + cellSize, y }; gpc_add_contour(&cell, &cell_bounds, 0); // Take the intersection to get the chunk of the face that's inside this cell diff --git a/texture.cpp b/texture.cpp index d0fe71b..cd2d694 100644 --- a/texture.cpp +++ b/texture.cpp @@ -350,7 +350,10 @@ bool process_textures(const world_t* world, TextureList& outTextures) tex.ps1tex.tpage = getTPage(outTim.format, 0, x, y); tex.uoffs = (u_char)((x % 64) << (2 - outTim.format)); tex.voffs = (u_char)(y & 0xFF); - tex.ps1tex.twin = getTexWindow(tex.uoffs, tex.voffs, tex.w, tex.h); // TODO: figure out the right offsets that are multiples of w and h; NOTE: if uoffs has to >> 1, then w probably has to as well + if (texture_isRepeatable(miptex)) + tex.ps1tex.twin = getTexWindow(tex.uoffs, tex.voffs, tex.w, tex.h); // TODO: figure out the right offsets that are multiples of w and h; NOTE: if uoffs has to >> 1, then w probably has to as well + else + tex.ps1tex.twin = getTexWindow(0, 0, 0, 0); } } @@ -412,7 +415,7 @@ bool process_textures(const world_t* world, TextureList& outTextures) return true; } -bool texture_isRepeatable(miptex_t* miptex) +bool texture_isRepeatable(const miptex_t* miptex) { // Check if the texture is square if (miptex->width != miptex->height) diff --git a/texture.h b/texture.h index 809b28a..340ed4c 100644 --- a/texture.h +++ b/texture.h @@ -25,4 +25,4 @@ struct TextureDescriptor typedef std::vector TextureList; bool process_textures(const world_t* world, TextureList& outTextures); -bool texture_isRepeatable(miptex_t* miptex); +bool texture_isRepeatable(const miptex_t* miptex);