* 40-svt: Added to project. Added screenshot. Built shaders.

This commit is contained in:
Aleš Mlakar 2019-01-03 11:34:30 +01:00
parent 3a961e6ab7
commit 1c6c7378e8
18 changed files with 2185 additions and 0 deletions

View File

@ -0,0 +1,18 @@
$input v_texcoord0
/*
* Copyright 2011-2018 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
#include "../common/common.sh"
#include "virtualtexture.sh"
void main()
{
float mipCount = log2(PageTableSize);
float mip = floor(MipLevel(v_texcoord0.xy, VirtualTextureSize) - MipBias);
mip = clamp(mip, 0, mipCount);
vec2 offset = floor(v_texcoord0.xy * PageTableSize);
gl_FragColor = vec4(floor(vec3(offset / exp2(mip), mip)) / 255.0, 1.0);
}

View File

@ -0,0 +1,15 @@
$input v_texcoord0
/*
* Copyright 2011-2018 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
#include "../common/common.sh"
#include "virtualtexture.sh"
void main()
{
gl_FragColor = VirtualTexture(v_texcoord0.xy);
}

10
examples/40-svt/makefile Normal file
View File

@ -0,0 +1,10 @@
#
# Copyright 2011-2018 Branimir Karadzic. All rights reserved.
# License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
#
BGFX_DIR=../..
RUNTIME_DIR=$(BGFX_DIR)/examples/runtime
BUILD_DIR=../../.build
include $(BGFX_DIR)/scripts/shader.mk

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

371
examples/40-svt/svt.cpp Normal file
View File

@ -0,0 +1,371 @@
/*
* Copyright 2018 Aleš Mlakar. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
/*
* Reference(s):
* - Sparse Virtual Textures by Sean Barrett
* http://silverspaceship.com/src/svt/
* - Virtual Texture Demo by Brad Blanchard
* http://linedef.com/virtual-texture-demo.html
* - Mars texture
* http://www.celestiamotherlode.net/catalog/mars.php
*/
#include "common.h"
#include "bgfx_utils.h"
#include "imgui/imgui.h"
#include "camera.h"
#include "bounds.h"
#include "vt.h"
namespace
{
struct PosTexcoordVertex
{
float m_x;
float m_y;
float m_z;
float m_u;
float m_v;
static void init()
{
ms_decl
.begin()
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
.end();
};
static bgfx::VertexDecl ms_decl;
};
bgfx::VertexDecl PosTexcoordVertex::ms_decl;
static const float s_planeScale = 50.0f;
static PosTexcoordVertex s_vplaneVertices[] =
{
{ -s_planeScale, 0.0f, s_planeScale, 1.0f, 1.0f },
{ s_planeScale, 0.0f, s_planeScale, 1.0f, 0.0f },
{ -s_planeScale, 0.0f, -s_planeScale, 0.0f, 1.0f },
{ s_planeScale, 0.0f, -s_planeScale, 0.0f, 0.0f },
};
static const uint16_t s_planeIndices[] =
{
0, 1, 2,
1, 3, 2,
};
class ExampleSVT : public entry::AppI
{
public:
ExampleSVT(const char* _name, const char* _description)
: entry::AppI(_name, _description)
{
}
void init(int32_t _argc, const char* const* _argv, uint32_t _width, uint32_t _height) override
{
Args args(_argc, _argv);
m_width = _width;
m_height = _height;
m_debug = BGFX_DEBUG_TEXT;
m_reset = BGFX_RESET_VSYNC;
bgfx::Init init;
init.type = args.m_type;
init.vendorId = args.m_pciId;
init.resolution.width = m_width;
init.resolution.height = m_height;
init.resolution.reset = m_reset;
bgfx::init(init);
// Enable m_debug text.
bgfx::setDebug(m_debug);
// Set views clear state (first pass to 0, second pass to some background color)
for (uint16_t i = 0; i < 2; ++i)
{
bgfx::setViewClear(i
, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
, i == 0 ? 0 : 0x101050ff
, 1.0f
, 0
);
}
// Create vertex stream declaration.
PosTexcoordVertex::init();
// Create static vertex buffer.
m_vbh = bgfx::createVertexBuffer(
bgfx::makeRef(s_vplaneVertices, sizeof(s_vplaneVertices))
, PosTexcoordVertex::ms_decl
);
m_ibh = bgfx::createIndexBuffer(
bgfx::makeRef(s_planeIndices, sizeof(s_planeIndices))
);
// Create program from shaders.
m_vt_unlit = loadProgram("vs_vt_generic", "fs_vt_unlit");
m_vt_mip = loadProgram("vs_vt_generic", "fs_vt_mip");
// Imgui.
imguiCreate();
m_timeOffset = bx::getHPCounter();
// Get renderer capabilities info.
m_caps = bgfx::getCaps();
m_scrollArea = 0;
// Create and setup camera
cameraCreate();
cameraSetPosition({ 0.0f, 5.0f, 0.0f });
cameraSetVerticalAngle(0.0f);
// Create Virtual texture info
m_vti = new vt::VirtualTextureInfo();
m_vti->m_virtualTextureSize = 8192; // The actual size will be read from the tile data file
m_vti->m_tileSize = 128;
m_vti->m_borderSize = 1;
// Generate tile data file (if not yet created)
{
vt::TileGenerator tileGenerator(m_vti);
tileGenerator.generate("textures/8k_mars.jpg");
}
// Load tile data file
auto tileDataFile = new vt::TileDataFile("textures/8k_mars.jpg.cache", m_vti);
tileDataFile->readInfo();
// Create virtual texture and feedback buffer
m_vt = new vt::VirtualTexture(tileDataFile, m_vti, 2048, 1);
m_feedbackBuffer = new vt::FeedbackBuffer(m_vti, 64, 64);
}
virtual int shutdown() override
{
// Cleanup.
bgfx::frame();
cameraDestroy();
imguiDestroy();
bgfx::destroy(m_ibh);
bgfx::destroy(m_vbh);
bgfx::destroy(m_vt_unlit);
bgfx::destroy(m_vt_mip);
delete m_vti;
delete m_vt;
delete m_feedbackBuffer;
// Shutdown bgfx.
bgfx::shutdown();
return 0;
}
bool update() override
{
if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState))
{
imguiBeginFrame(
m_mouseState.m_mx
, m_mouseState.m_my
, (m_mouseState.m_buttons[entry::MouseButton::Left] ? IMGUI_MBUT_LEFT : 0)
| (m_mouseState.m_buttons[entry::MouseButton::Right] ? IMGUI_MBUT_RIGHT : 0)
| (m_mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
, m_mouseState.m_mz
, uint16_t(m_width)
, uint16_t(m_height)
);
showExampleDialog(this);
int64_t now = bx::getHPCounter();
static int64_t last = now;
const int64_t frameTime = now - last;
last = now;
const double freq = double(bx::getHPFrequency());
const float deltaTime = float(frameTime / freq);
float time = (float)((now - m_timeOffset) / freq);
if ((BGFX_CAPS_TEXTURE_BLIT | BGFX_CAPS_TEXTURE_READ_BACK) != (bgfx::getCaps()->supported & (BGFX_CAPS_TEXTURE_BLIT | BGFX_CAPS_TEXTURE_READ_BACK)))
{
// When texture read-back or blit is not supported by GPU blink!
bool blink = uint32_t(time*3.0f) & 1;
bgfx::dbgTextPrintf(0, 0, blink ? 0x4f : 0x04, " Texture read-back and/or blit not supported by GPU. ");
// Set view 0 default viewport.
bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height));
// This dummy draw call is here to make sure that view 0 is cleared
// if no other draw calls are submitted to view 0.
bgfx::touch(0);
}
else
{
ImGui::SetNextWindowPos(
ImVec2(m_width - m_width / 5.0f - 10.0f, 10.0f)
, ImGuiCond_FirstUseEver
);
ImGui::SetNextWindowSize(
ImVec2(m_width / 5.0f, m_height - 10.0f)
, ImGuiCond_FirstUseEver
);
ImGui::Begin("Settings"
, NULL
, 0
);
//ImGui::SliderFloat("intensity", &m_intensity, 0.0f, 3.0f);
auto showBorders = m_vt->isShowBoardersEnabled();
if (ImGui::Checkbox("Show borders", &showBorders))
{
m_vt->enableShowBoarders(showBorders);
}
auto colorMipLevels = m_vt->isColorMipLevelsEnabled();
if (ImGui::Checkbox("Color mip levels", &colorMipLevels))
{
m_vt->enableColorMipLevels(colorMipLevels);
}
auto uploadsperframe = m_vt->getUploadsPerFrame();
if (ImGui::InputInt("Updates per frame", &uploadsperframe, 1, 2))
{
uploadsperframe = bx::clamp(uploadsperframe, 1, 100);
m_vt->setUploadsPerFrame(uploadsperframe);
}
ImGui::ImageButton(m_vt->getAtlastTexture(), ImVec2(m_width / 5.0f - 16.0f, m_width / 5.0f - 16.0f));
ImGui::ImageButton(bgfx::getTexture(m_feedbackBuffer->getFrameBuffer()), ImVec2(m_width / 5.0f - 16.0f, m_width / 5.0f - 16.0f));
ImGui::End();
// Update camera.
cameraUpdate(deltaTime, m_mouseState);
float view[16];
cameraGetViewMtx(view);
float proj[16];
bx::mtxProj(proj, 60.0f, float(m_width) / float(m_height), 0.1f, 1000.0f, m_caps->homogeneousDepth);
// Setup views
for (uint16_t i = 0; i < 2; ++i)
{
uint16_t viewWidth = 0;
uint16_t viewHeight = 0;
// Setup pass, first pass is into mip-map feedback buffer, second pass is on screen
if (i == 0)
{
bgfx::setViewFrameBuffer(i, m_feedbackBuffer->getFrameBuffer());
viewWidth = uint16_t(m_feedbackBuffer->getWidth());
viewHeight = uint16_t(m_feedbackBuffer->getHeight());
}
else
{
bgfx::FrameBufferHandle invalid = BGFX_INVALID_HANDLE;
bgfx::setViewFrameBuffer(i, invalid);
viewWidth = uint16_t(m_width);
viewHeight = uint16_t(m_height);
}
bgfx::setViewRect(i, 0, 0, viewWidth, viewHeight);
bgfx::setViewTransform(i, view, proj);
float mtx[16];
bx::mtxIdentity(mtx);
// Set identity transform for draw call.
bgfx::setTransform(mtx);
// Set vertex and index buffer.
bgfx::setVertexBuffer(0, m_vbh);
bgfx::setIndexBuffer(m_ibh);
// Set render states.
bgfx::setState(0
| BGFX_STATE_WRITE_RGB
| BGFX_STATE_WRITE_A
| BGFX_STATE_WRITE_Z
| BGFX_STATE_DEPTH_TEST_LESS
);
// Set virtual texture uniforms
m_vt->setUniforms();
// Submit primitive for rendering to first pass (to feedback buffer, where mip levels and tile x/y will be rendered
if (i == 0)
{
bgfx::submit(i, m_vt_mip);
// Download previous frame feedback info
m_feedbackBuffer->download();
// Update and upload new requests
m_vt->update(m_feedbackBuffer->getRequests(), 4);
// Clear feedback
m_feedbackBuffer->clear();
// Copy new frame feedback buffer
m_feedbackBuffer->copy(3);
}
else
{
// Submit primitive for rendering to second pass (to back buffer, where virtual texture page table and atlas will be used)
bgfx::submit(i, m_vt_unlit);
}
}
}
imguiEndFrame();
// Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives.
bgfx::frame();
return true;
}
return false;
}
bgfx::VertexBufferHandle m_vbh;
bgfx::IndexBufferHandle m_ibh;
bgfx::ProgramHandle m_vt_unlit;
bgfx::ProgramHandle m_vt_mip;
uint32_t m_width;
uint32_t m_height;
uint32_t m_debug;
uint32_t m_reset;
int32_t m_scrollArea;
entry::MouseState m_mouseState;
const bgfx::Caps* m_caps;
int64_t m_timeOffset;
vt::VirtualTextureInfo* m_vti;
vt::VirtualTexture* m_vt;
vt::FeedbackBuffer* m_feedbackBuffer;
};
} // namespace
ENTRY_IMPLEMENT_MAIN(ExampleSVT, "40-svt", "Sparse Virtual Textures.");

View File

@ -0,0 +1,4 @@
vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
vec3 a_position : POSITION;
vec2 a_texcoord0 : TEXCOORD0;

View File

@ -0,0 +1,80 @@
/*
* Copyright 2011-2018 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
uniform vec4 u_vt_settings_1;
uniform vec4 u_vt_settings_2;
#define VirtualTextureSize u_vt_settings_1.x
#define AtlasScale u_vt_settings_1.y
#define BorderScale u_vt_settings_1.z
#define BorderOffset u_vt_settings_1.w
#define MipBias u_vt_settings_2.x
#define PageTableSize u_vt_settings_2.y
SAMPLER2D(s_vt_page_table, 0);
SAMPLER2D(s_vt_texture_atlas, 1);
// This function estimates mipmap levels
float MipLevel( vec2 uv, float size )
{
vec2 dx = dFdx( uv * size );
vec2 dy = dFdy( uv * size );
float d = max( dot( dx, dx ), dot( dy, dy ) );
return max( 0.5 * log2( d ), 0 );
}
// This function samples the page table and returns the page's
// position and mip level.
vec3 SampleTable( vec2 uv, float mip )
{
vec2 offset = fract( uv * PageTableSize ) / PageTableSize;
return texture2DLod( s_vt_page_table, uv - offset, mip ).xyz;
}
// This functions samples from the texture atlas and returns the final color
vec4 SampleAtlas( vec3 page, vec2 uv )
{
float mipsize = exp2( floor( page.z * 255.0 + 0.5 ) );
uv = fract( uv * PageTableSize / mipsize );
uv *= BorderScale;
uv += BorderOffset;
vec2 offset = floor( page.xy * 255 + 0.5 );
return texture2D( s_vt_texture_atlas, ( offset + uv ) * AtlasScale );
}
// Ugly brute force trilinear, look up twice and mix
vec4 VirtualTextureTrilinear( vec2 uv )
{
float miplevel = MipLevel( uv, VirtualTextureSize );
miplevel = clamp( miplevel, 0, log2( PageTableSize )-1 );
float mip1 = floor( miplevel );
float mip2 = mip1 + 1;
float mipfrac = miplevel - mip1;
vec3 page1 = SampleTable( uv, mip1 );
vec3 page2 = SampleTable( uv, mip2 );
vec4 sample1 = SampleAtlas( page1, uv );
vec4 sample2 = SampleAtlas( page2, uv );
return mix( sample1, sample2, mipfrac );
}
// Simple bilinear
vec4 VirtualTexture( vec2 uv )
{
float mip = floor( MipLevel( uv, VirtualTextureSize ) );
mip = clamp( mip, 0, log2( PageTableSize ) );
vec3 page = SampleTable( uv, mip );
return SampleAtlas( page, uv );
}

View File

@ -0,0 +1,16 @@
$input a_position, a_texcoord0
$output v_texcoord0
/*
* Copyright 2011-2018 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
#include "../common/common.sh"
void main()
{
vec3 wpos = mul(u_model[0], vec4(a_position, 1.0) ).xyz;
gl_Position = mul(u_viewProj, vec4(wpos, 1.0) );
v_texcoord0 = a_texcoord0;
}

1248
examples/40-svt/vt.cpp Normal file

File diff suppressed because it is too large Load Diff

422
examples/40-svt/vt.h Normal file
View File

@ -0,0 +1,422 @@
#pragma once
#include "common.h"
#include "bgfx_utils.h"
#include "bimg/decode.h"
#include <vector>
#include <set>
#include <functional>
namespace vt
{
// Forward declarations
class PageCache;
class TextureAtlas;
class TileDataFile;
// Point
struct Point
{
int m_x, m_y;
};
// Rect
struct Rect
{
int minX() const
{
return m_x;
}
int minY() const
{
return m_y;
}
int maxX() const
{
return m_x + m_width;
}
int maxY() const
{
return m_y + m_height;
}
bool contains(const Point& p) const
{
return p.m_x >= minX() && p.m_y >= minY() && p.m_x < maxX() && p.m_y < maxY();
}
int m_x, m_y, m_width, m_height;
};
// Color
struct Color
{
uint8_t m_r, m_g, m_b, m_a;
};
// Page
struct Page
{
uint64_t hash() const;
bool operator==(const Page& page) const;
bool operator<(const Page& page) const;
int m_x;
int m_y;
int m_mip;
};
// PageCount
struct PageCount
{
Page m_page;
int m_count;
PageCount(Page _page = Page(), int _count = 0);
int compareTo(const PageCount& other) const;
bool operator==(const PageCount& other) const;
bool operator<(const PageCount& other) const;
};
// VirtualTextureInfo
struct VirtualTextureInfo
{
VirtualTextureInfo();
int GetPageSize() const;
int GetPageTableSize() const;
int m_virtualTextureSize = 0;
int m_tileSize = 0;
int m_borderSize = 0;
};
// StagingPool
class StagingPool
{
public:
StagingPool(int _width, int _height, int _count, bool _readBack);
~StagingPool();
void grow(int count);
bgfx::TextureHandle getTexture();
void next();
private:
std::vector<bgfx::TextureHandle> m_stagingTextures;
int m_stagingTextureIndex;
int m_width;
int m_height;
uint64_t m_flags;
};
// PageIndexer
struct PageIndexer
{
public:
PageIndexer(VirtualTextureInfo* _info);
int getIndexFromPage(Page page);
Page getPageFromIndex(int index);
bool isValid(Page page);
int getCount() const;
private:
VirtualTextureInfo* m_info;
int m_mipcount;
std::vector<int> m_offsets; // This stores the offsets to the first page of the start of a mipmap level
std::vector<int> m_sizes; // This stores the sizes of various mip levels
std::vector<Page> m_reverse;
int m_count;
};
// SimpleImage
struct SimpleImage
{
SimpleImage(int _width, int _height, int _channelCount, uint8_t _clearValue = 0);
SimpleImage(int _width, int _height, int _channelCount, std::vector<uint8_t>& _data);
void copy(Point dest_offset, SimpleImage& src, Rect src_rect);
void clear(uint8_t clearValue = 0);
void fill(Rect rect, uint8_t r, uint8_t g, uint8_t b, uint8_t a);
static void mipmap(uint8_t* source, int size, int channels, uint8_t* dest);
int m_width = 0;
int m_height = 0;
int m_channelCount = 0;
std::vector<uint8_t> m_data;
};
// Quadtree
struct Quadtree
{
Quadtree(Rect _rect, int _level);
~Quadtree();
void add(Page request, Point mapping);
void remove(Page request);
void write(SimpleImage& image, int miplevel);
Rect getRectangle(int index);
void write(Quadtree* node, SimpleImage& image, int miplevel);
static Quadtree* findPage(Quadtree* node, Page request, int* index);
int m_level;
Rect m_rectangle;
Point m_mapping;
Quadtree* m_children[4];
};
// PageTable
class PageTable
{
public:
PageTable(PageCache* _cache, VirtualTextureInfo* _info, PageIndexer* _indexer);
~PageTable();
void update(bgfx::ViewId blitViewId);
bgfx::TextureHandle getTexture();
private:
VirtualTextureInfo* m_info;
bgfx::TextureHandle m_texture;
PageIndexer* m_indexer;
Quadtree* m_quadtree;
bool m_quadtreeDirty;
std::vector<SimpleImage*> m_images;
std::vector<bgfx::TextureHandle> m_stagingTextures;
};
// PageLoader
class PageLoader
{
public:
struct ReadState
{
Page m_page;
std::vector<uint8_t> m_data;
};
PageLoader(TileDataFile* _tileDataFile, PageIndexer* _indexer, VirtualTextureInfo* _info);
void submit(Page request);
void loadPage(ReadState& state);
void onPageLoadComplete(ReadState& state);
void copyBorder(uint8_t* image);
void copyColor(uint8_t* image, Page request);
std::function<void(Page, uint8_t*)> loadComplete;
bool m_colorMipLevels;
bool m_showBorders;
private:
TileDataFile* m_tileDataFile;
PageIndexer* m_indexer;
VirtualTextureInfo* m_info;
};
// PageCache
class PageCache
{
public:
PageCache(VirtualTextureInfo* _info, TextureAtlas* _atlas, PageLoader* _loader, PageIndexer* _indexer, int _count);
bool touch(Page page);
bool request(Page request, bgfx::ViewId blitViewId);
void clear();
void loadComplete(Page page, uint8_t* data);
// These callbacks are used to notify the other systems
std::function<void(Page, Point)> removed;
std::function<void(Page, Point)> added;
private:
VirtualTextureInfo* m_info;
TextureAtlas* m_atlas;
PageLoader* m_loader;
PageIndexer* m_indexer;
int m_count;
struct LruPage
{
Page m_page;
Point m_point;
bool operator==(const Page& other) const
{
return m_page == other;
}
};
int m_current; // This is used for generating the texture atlas indices before the lru is full
std::set<Page> m_lru_used;
std::vector<LruPage> m_lru;
std::set<Page> m_loading;
bgfx::ViewId m_blitViewId;
};
// TextureAtlas
class TextureAtlas
{
public:
TextureAtlas(VirtualTextureInfo* _info, int count, int uploadsperframe);
~TextureAtlas();
void setUploadsPerFrame(int count);
void uploadPage(Point pt, uint8_t* data, bgfx::ViewId blitViewId);
bgfx::TextureHandle getTexture();
private:
VirtualTextureInfo* m_info;
bgfx::TextureHandle m_texture;
StagingPool m_stagingPool;
};
// FeedbackBuffer
class FeedbackBuffer
{
public:
FeedbackBuffer(VirtualTextureInfo* _info, int _width, int _height);
~FeedbackBuffer();
void clear();
void copy(bgfx::ViewId viewId);
void download();
// This function validates the pages and adds the page's parents
// We do this so that we can fall back to them if we run out of memory
void addRequestAndParents(Page request);
const std::vector<int>& getRequests() const;
bgfx::FrameBufferHandle getFrameBuffer();
int getWidth() const;
int getHeight() const;
private:
VirtualTextureInfo* m_info;
PageIndexer* m_indexer;
int m_width = 0;
int m_height = 0;
StagingPool m_stagingPool;
bgfx::TextureHandle m_lastStagingTexture;
bgfx::FrameBufferHandle m_feedbackFrameBuffer;
// This stores the pages by index. The int value is number of requests.
std::vector<int> m_requests;
std::vector<uint8_t> m_downloadBuffer;
};
// VirtualTexture
class VirtualTexture
{
public:
VirtualTexture(TileDataFile* _tileDataFile, VirtualTextureInfo* _info, int _atlassize, int _uploadsperframe, int _mipBias = 4);
~VirtualTexture();
int getMipBias() const;
void setMipBias(int value);
void setUploadsPerFrame(int count);
int getUploadsPerFrame() const;
void enableShowBoarders(bool enable);
bool isShowBoardersEnabled() const;
void enableColorMipLevels(bool enable);
bool isColorMipLevelsEnabled() const;
bgfx::TextureHandle getAtlastTexture();
bgfx::TextureHandle getPageTableTexture();
void clear();
void update(const std::vector<int>& requests, bgfx::ViewId blitViewId);
void setUniforms();
private:
TileDataFile* m_tileDataFile;
VirtualTextureInfo* m_info;
PageIndexer* m_indexer;
PageTable* m_pageTable;
TextureAtlas* m_atlas;
PageLoader* m_loader;
PageCache* m_cache;
int m_atlasCount;
int m_uploadsPerFrame;
std::vector<PageCount> m_pagesToLoad;
int m_mipBias;
bgfx::UniformHandle u_vt_settings_1;
bgfx::UniformHandle u_vt_settings_2;
bgfx::UniformHandle s_vt_page_table;
bgfx::UniformHandle s_vt_texture_atlas;
};
// TileDataFile
class TileDataFile
{
public:
TileDataFile(const std::string& filename, VirtualTextureInfo* _info, bool _readWrite = false);
~TileDataFile();
void readInfo();
void writeInfo();
void readPage(int index, uint8_t* data);
void writePage(int index, uint8_t* data);
private:
VirtualTextureInfo* m_info;
int m_size;
FILE* m_file;
};
// TileGenerator
class TileGenerator
{
public:
TileGenerator(VirtualTextureInfo* _info);
~TileGenerator();
bool generate(const std::string& filename);
private:
void CopyTile(SimpleImage& image, Page request);
private:
VirtualTextureInfo* m_info;
PageIndexer* m_indexer;
TileDataFile* m_tileDataFile;
int m_tilesize;
int m_pagesize;
bx::DefaultAllocator m_allocator;
bimg::ImageContainer* m_sourceImage;
SimpleImage* m_page1Image;
SimpleImage* m_page2Image;
SimpleImage* m_2xtileImage;
SimpleImage* m_4xtileImage;
SimpleImage* m_tileImage;
};
} // namespace vt

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 MiB

View File

@ -449,6 +449,7 @@ or _OPTIONS["with-combined-examples"] then
, "37-gpudrivenrendering"
, "38-bloom"
, "39-assao"
, "40-svt"
)
-- C99 source doesn't compile under WinRT settings