Browse Source

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.
master
Nico de Poel 3 years ago
parent
commit
68eb9c10c8
  1. 14
      tesselate.cpp
  2. 5
      texture.cpp
  3. 2
      texture.h

14
tesselate.cpp

@ -4,6 +4,8 @@
#include "gpc.h"
#include "matrix.h"
bool texture_isRepeatable(const miptex_t* miptex);
std::vector<Tesselator::Polygon> Tesselator::tesselateFace(const face_t* face)
{
std::vector<Polygon> polygons;
@ -56,9 +58,11 @@ std::vector<Tesselator::Polygon> 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::Polygon> 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

5
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);
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)

2
texture.h

@ -25,4 +25,4 @@ struct TextureDescriptor
typedef std::vector<TextureDescriptor> TextureList;
bool process_textures(const world_t* world, TextureList& outTextures);
bool texture_isRepeatable(miptex_t* miptex);
bool texture_isRepeatable(const miptex_t* miptex);
Loading…
Cancel
Save