Uses MIPs for terrain textures previews following e4455a8e8f
.
Comments By: Stan Differential Revision: https://code.wildfiregames.com/D4447 This was SVN commit r26239.
This commit is contained in:
parent
c114bab396
commit
4ce609bb1f
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2021 Wildfire Games.
|
||||
/* Copyright (C) 2022 Wildfire Games.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
@ -20,24 +20,19 @@
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* support routines for 2d texture access/writing.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "tex.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "lib/timer.h"
|
||||
#include "lib/bits.h"
|
||||
#include "lib/allocators/shared_ptr.h"
|
||||
#include "lib/bits.h"
|
||||
#include "lib/sysdep/cpu.h"
|
||||
#include "lib/tex/tex_codec.h"
|
||||
#include "lib/timer.h"
|
||||
|
||||
#include "tex_codec.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
|
||||
static const StatusDefinition texStatusDefinitions[] = {
|
||||
{ ERR::TEX_FMT_INVALID, L"Invalid/unsupported texture format" },
|
||||
@ -633,10 +628,35 @@ u8* Tex::get_data()
|
||||
|
||||
u8* p = m_Data.get();
|
||||
if(!p)
|
||||
return 0;
|
||||
return nullptr;
|
||||
return p + m_Ofs;
|
||||
}
|
||||
|
||||
u8* Tex::GetMipLevelData(const u32 level)
|
||||
{
|
||||
// (can't use normal CHECK_TEX due to u8* return value)
|
||||
WARN_IF_ERR(validate());
|
||||
|
||||
u8* levelData = m_Data.get();
|
||||
if (!levelData)
|
||||
return nullptr;
|
||||
levelData += m_Ofs;
|
||||
const size_t dataPadding = (m_Flags & TEX_DXT) != 0 ? 4 : 1;
|
||||
size_t levelWidth = m_Width, levelHeight = m_Height;
|
||||
for (u32 currentLevel = 0; levelWidth > 1 || levelHeight > 1; ++currentLevel)
|
||||
{
|
||||
if (currentLevel == level)
|
||||
return levelData;
|
||||
|
||||
const size_t levelDataSize = round_up(levelWidth, dataPadding) * round_up(levelHeight, dataPadding) * m_Bpp / 8;
|
||||
levelData += levelDataSize;
|
||||
|
||||
levelWidth = std::max<u32>(levelWidth / 2, 1);
|
||||
levelHeight = std::max<u32>(levelHeight / 2, 1);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// returns color of 1x1 mipmap level
|
||||
u32 Tex::get_average_color() const
|
||||
{
|
||||
|
@ -332,6 +332,14 @@ struct Tex
|
||||
**/
|
||||
u8* get_data();
|
||||
|
||||
/**
|
||||
* return a pointer to the mip level image data (pixels).
|
||||
*
|
||||
* @param level which level's data should be returned.
|
||||
* @return pointer to the data.
|
||||
**/
|
||||
u8* GetMipLevelData(const u32 level);
|
||||
|
||||
/**
|
||||
* return the ARGB value of the 1x1 mipmap level of the texture.
|
||||
*
|
||||
|
@ -86,7 +86,7 @@ sTerrainTexturePreview GetPreview(CTerrainTextureEntry* tex, size_t width, size_
|
||||
// Check that we can fit the texture into the preview size before any transform.
|
||||
texture.m_Width >= width && texture.m_Height >= height &&
|
||||
// Transform to a single format that we can process.
|
||||
texture.transform_to((texture.m_Flags) & ~(TEX_DXT | TEX_MIPMAPS | TEX_GREY | TEX_BGR)) == INFO::OK &&
|
||||
texture.transform_to((texture.m_Flags | TEX_MIPMAPS) & ~(TEX_DXT | TEX_GREY | TEX_BGR)) == INFO::OK &&
|
||||
(texture.m_Bpp == 24 || texture.m_Bpp == 32);
|
||||
if (canUsePreview)
|
||||
{
|
||||
@ -95,14 +95,17 @@ sTerrainTexturePreview GetPreview(CTerrainTextureEntry* tex, size_t width, size_
|
||||
++level;
|
||||
// Extract the middle section (as a representative preview),
|
||||
// and copy into buffer.
|
||||
u8* data = texture.get_data();
|
||||
const size_t dataShiftX = ((texture.m_Width - width) / 2) >> level;
|
||||
const size_t dataShiftY = ((texture.m_Height - height) / 2) >> level;
|
||||
u8* data = texture.GetMipLevelData(level);
|
||||
ENSURE(data);
|
||||
const size_t levelWidth = texture.m_Width >> level;
|
||||
const size_t levelHeight = texture.m_Height >> level;
|
||||
const size_t dataShiftX = (levelWidth - width) / 2;
|
||||
const size_t dataShiftY = (levelHeight - height) / 2;
|
||||
for (size_t y = 0; y < height; ++y)
|
||||
for (size_t x = 0; x < width; ++x)
|
||||
{
|
||||
const size_t bufferOffset = (y * width + x) * previewBPP;
|
||||
const size_t dataOffset = (((y << level) + dataShiftY) * texture.m_Width + (x << level) + dataShiftX) * texture.m_Bpp / 8;
|
||||
const size_t dataOffset = ((y + dataShiftY) * levelWidth + x + dataShiftX) * texture.m_Bpp / 8;
|
||||
buffer[bufferOffset + 0] = data[dataOffset + 0];
|
||||
buffer[bufferOffset + 1] = data[dataOffset + 1];
|
||||
buffer[bufferOffset + 2] = data[dataOffset + 2];
|
||||
|
Loading…
Reference in New Issue
Block a user