texturev: Added cubemap view modes.

This commit is contained in:
Branimir Karadžić 2017-07-09 11:47:13 -07:00
parent c6e9ba71cf
commit 08ba314532
8 changed files with 298 additions and 123 deletions

View File

@ -14,6 +14,6 @@ uniform vec4 u_params;
void main()
{
vec4 color = texture2DLod(s_texColor, v_texcoord0, u_textureLod);
vec4 color = texture2DLod(s_texColor, v_texcoord0.xy, u_textureLod);
gl_FragColor = color * v_color0;
}

View File

@ -15,6 +15,6 @@ uniform vec4 u_params;
void main()
{
vec4 color = texture3DLod(s_texColor, vec3(v_texcoord0, u_textureLayer), u_textureLod);
vec4 color = texture3DLod(s_texColor, vec3(v_texcoord0.xy, u_textureLayer), u_textureLod);
gl_FragColor = color * v_color0;
}

View File

@ -15,6 +15,6 @@ uniform vec4 u_params;
void main()
{
vec4 color = texture2DArrayLod(s_texColor, vec3(v_texcoord0, u_textureLayer), u_textureLod);
vec4 color = texture2DArrayLod(s_texColor, vec3(v_texcoord0.xy, u_textureLayer), u_textureLod);
gl_FragColor = color * v_color0;
}

View File

@ -15,7 +15,7 @@ uniform vec4 u_params;
void main()
{
vec3 dir = vec3( (v_texcoord0*2.0 - 1.0) * vec2(1.0, -1.0), 1.0);
vec3 dir = vec3( (v_texcoord0.xy*2.0 - 1.0) * vec2(1.0, -1.0), 1.0);
dir = normalize(mul(u_mtx, vec4(dir, 0.0) ).xyz);
gl_FragColor = textureCubeLod(s_texColor, dir, u_textureLod) * v_color0;
}

View File

@ -0,0 +1,19 @@
$input v_texcoord0, v_color0
/*
* Copyright 2011-2017 Branimir Karadzic. All rights reserved.
* License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause
*/
#include <bgfx_shader.sh>
SAMPLERCUBE(s_texColor, 0);
uniform vec4 u_params;
#define u_textureLod u_params.x
void main()
{
vec4 color = textureCubeLod(s_texColor, v_texcoord0, u_textureLod);
gl_FragColor = color * v_color0;
}

View File

@ -12,7 +12,8 @@ SAMPLER2D(s_texColor, 0);
uniform vec4 u_params;
#define u_textureLod u_params.x
float median(float r, float g, float b) {
float median(float r, float g, float b)
{
return max(min(r, g), min(max(r, g), b) );
}
@ -20,7 +21,7 @@ void main() {
vec4 bgColor = vec4(1.0, 1.0, 1.0, 1.0);
vec4 fgColor = vec4(0.0, 0.0, 0.0, 1.0);
vec3 sample = texture2DLod(s_texColor, v_texcoord0, u_textureLod).rgb;
vec3 sample = texture2DLod(s_texColor, v_texcoord0.xy, u_textureLod).rgb;
float sigDist = median(sample.r, sample.g, sample.b) - 0.5;
float opacity = clamp(sigDist/fwidth(sigDist) + 0.5, 0.0, 1.0);
gl_FragColor = mix(bgColor, fgColor, opacity);

View File

@ -36,6 +36,7 @@ namespace stl = tinystl;
#include "fs_texture.bin.h"
#include "fs_texture_array.bin.h"
#include "fs_texture_cube.bin.h"
#include "fs_texture_cube2.bin.h"
#include "fs_texture_sdf.bin.h"
#include "fs_texture_3d.bin.h"
@ -52,6 +53,7 @@ static const bgfx::EmbeddedShader s_embeddedShaders[] =
BGFX_EMBEDDED_SHADER(fs_texture_array),
BGFX_EMBEDDED_SHADER(vs_texture_cube),
BGFX_EMBEDDED_SHADER(fs_texture_cube),
BGFX_EMBEDDED_SHADER(fs_texture_cube2),
BGFX_EMBEDDED_SHADER(fs_texture_sdf),
BGFX_EMBEDDED_SHADER(fs_texture_3d),
@ -85,6 +87,18 @@ struct Binding
};
};
struct Geometry
{
enum Enum
{
Quad,
Cross,
Hexagon,
Count
};
};
static const InputBinding s_bindingApp[] =
{
{ entry::Key::Esc, entry::Modifier::None, 1, NULL, "exit" },
@ -137,6 +151,9 @@ static const InputBinding s_bindingView[] =
{ entry::Key::KeyS, entry::Modifier::None, 1, NULL, "view sdf" },
{ entry::Key::Space, entry::Modifier::None, 1, NULL, "view geo\n"
"view pan\n" },
INPUT_BINDING_END
};
@ -157,7 +174,8 @@ BX_STATIC_ASSERT(Binding::Count == BX_COUNTOF(s_binding) );
struct View
{
View()
: m_fileIndex(0)
: m_cubeMapGeo(Geometry::Quad)
, m_fileIndex(0)
, m_scaleFn(0)
, m_mip(0)
, m_layer(0)
@ -426,6 +444,10 @@ struct View
{
m_sdf ^= true;
}
else if (0 == bx::strCmp(_argv[1], "geo") )
{
m_cubeMapGeo = Geometry::Enum( (m_cubeMapGeo + 1) % Geometry::Count);
}
else if (0 == bx::strCmp(_argv[1], "help") )
{
m_help ^= true;
@ -492,6 +514,7 @@ struct View
FileList m_fileList;
bgfx::TextureInfo m_info;
Geometry::Enum m_cubeMapGeo;
uint32_t m_fileIndex;
uint32_t m_scaleFn;
uint32_t m_mip;
@ -516,12 +539,13 @@ int cmdView(CmdContext* /*_context*/, void* _userData, int _argc, char const* co
return view->cmd(_argc, _argv);
}
struct PosUvColorVertex
struct PosUvwColorVertex
{
float m_x;
float m_y;
float m_u;
float m_v;
float m_w;
uint32_t m_abgr;
static void init()
@ -529,23 +553,57 @@ struct PosUvColorVertex
ms_decl
.begin()
.add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float)
.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
.add(bgfx::Attrib::TexCoord0, 3, bgfx::AttribType::Float)
.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
.end();
}
void set(float _x, float _y, float _u, float _v, float _w, uint32_t _abgr)
{
m_x = _x;
m_y = _y;
m_u = _u;
m_v = _v;
m_w = _w;
m_abgr = _abgr;
}
static bgfx::VertexDecl ms_decl;
};
bgfx::VertexDecl PosUvColorVertex::ms_decl;
bgfx::VertexDecl PosUvwColorVertex::ms_decl;
bool screenQuad(int32_t _x, int32_t _y, int32_t _width, uint32_t _height, uint32_t _abgr, float _maxu = 1.0f, float _maxv = 1.0f)
static uint32_t addQuad(uint16_t* _indices, uint16_t _idx0, uint16_t _idx1, uint16_t _idx2, uint16_t _idx3)
{
if (6 == bgfx::getAvailTransientVertexBuffer(6, PosUvColorVertex::ms_decl) )
_indices[0] = _idx0;
_indices[1] = _idx3;
_indices[2] = _idx1;
_indices[3] = _idx1;
_indices[4] = _idx3;
_indices[5] = _idx2;
return 6;
}
void setGeometry(
Geometry::Enum _type
, int32_t _x
, int32_t _y
, int32_t _width
, uint32_t _height
, uint32_t _abgr
, float _maxu = 1.0f
, float _maxv = 1.0f
)
{
if (Geometry::Quad == _type)
{
if (6 == bgfx::getAvailTransientVertexBuffer(6, PosUvwColorVertex::ms_decl) )
{
bgfx::TransientVertexBuffer vb;
bgfx::allocTransientVertexBuffer(&vb, 6, PosUvColorVertex::ms_decl);
PosUvColorVertex* vertex = (PosUvColorVertex*)vb.data;
bgfx::allocTransientVertexBuffer(&vb, 6, PosUvwColorVertex::ms_decl);
PosUvwColorVertex* vertex = (PosUvwColorVertex*)vb.data;
const float widthf = float(_width);
const float heightf = float(_height);
@ -560,49 +618,104 @@ bool screenQuad(int32_t _x, int32_t _y, int32_t _width, uint32_t _height, uint32
const float minv = 0.0f;
const float maxv = _maxv;
vertex[0].m_x = minx;
vertex[0].m_y = miny;
vertex[0].m_u = minu;
vertex[0].m_v = minv;
vertex->set(minx, miny, minu, minv, 0.0f, _abgr); ++vertex;
vertex->set(maxx, miny, maxu, minv, 0.0f, _abgr); ++vertex;
vertex->set(maxx, maxy, maxu, maxv, 0.0f, _abgr); ++vertex;
vertex[1].m_x = maxx;
vertex[1].m_y = miny;
vertex[1].m_u = maxu;
vertex[1].m_v = minv;
vertex[2].m_x = maxx;
vertex[2].m_y = maxy;
vertex[2].m_u = maxu;
vertex[2].m_v = maxv;
vertex[3].m_x = maxx;
vertex[3].m_y = maxy;
vertex[3].m_u = maxu;
vertex[3].m_v = maxv;
vertex[4].m_x = minx;
vertex[4].m_y = maxy;
vertex[4].m_u = minu;
vertex[4].m_v = maxv;
vertex[5].m_x = minx;
vertex[5].m_y = miny;
vertex[5].m_u = minu;
vertex[5].m_v = minv;
vertex[0].m_abgr = _abgr;
vertex[1].m_abgr = _abgr;
vertex[2].m_abgr = _abgr;
vertex[3].m_abgr = _abgr;
vertex[4].m_abgr = _abgr;
vertex[5].m_abgr = _abgr;
vertex->set(maxx, maxy, maxu, maxv, 0.0f, _abgr); ++vertex;
vertex->set(minx, maxy, minu, maxv, 0.0f, _abgr); ++vertex;
vertex->set(minx, miny, minu, minv, 0.0f, _abgr); ++vertex;
bgfx::setVertexBuffer(0, &vb);
}
}
else
{
const uint32_t numVertices = 14;
const uint32_t numIndices = 36;
if (checkAvailTransientBuffers(numVertices, PosUvwColorVertex::ms_decl, numIndices) )
{
bgfx::TransientVertexBuffer tvb;
bgfx::allocTransientVertexBuffer(&tvb, numVertices, PosUvwColorVertex::ms_decl);
return true;
bgfx::TransientIndexBuffer tib;
bgfx::allocTransientIndexBuffer(&tib, numIndices);
PosUvwColorVertex* vertex = (PosUvwColorVertex*)tvb.data;
uint16_t* indices = (uint16_t*)tib.data;
if (Geometry::Cross == _type)
{
const float sx = _width /1.5f;
const float sy = _height/1.5f;
const float px = float(_x)-sx/4.0f;
const float py = float(_y);
vertex->set(0.0f*sx+px, 0.5f*sy+py, -1.0f, 1.0f, -1.0f, _abgr); ++vertex;
vertex->set(0.0f*sx+px, 1.0f*sy+py, -1.0f, -1.0f, -1.0f, _abgr); ++vertex;
vertex->set(0.5f*sx+px, 0.0f*sy+py, -1.0f, 1.0f, -1.0f, _abgr); ++vertex;
vertex->set(0.5f*sx+px, 0.5f*sy+py, -1.0f, 1.0f, 1.0f, _abgr); ++vertex;
vertex->set(0.5f*sx+px, 1.0f*sy+py, -1.0f, -1.0f, 1.0f, _abgr); ++vertex;
vertex->set(0.5f*sx+px, 1.5f*sy+py, -1.0f, -1.0f, -1.0f, _abgr); ++vertex;
vertex->set(1.0f*sx+px, 0.0f*sy+py, 1.0f, 1.0f, -1.0f, _abgr); ++vertex;
vertex->set(1.0f*sx+px, 0.5f*sy+py, 1.0f, 1.0f, 1.0f, _abgr); ++vertex;
vertex->set(1.0f*sx+px, 1.0f*sy+py, 1.0f, -1.0f, 1.0f, _abgr); ++vertex;
vertex->set(1.0f*sx+px, 1.5f*sy+py, 1.0f, -1.0f, -1.0f, _abgr); ++vertex;
vertex->set(1.5f*sx+px, 0.5f*sy+py, 1.0f, 1.0f, -1.0f, _abgr); ++vertex;
vertex->set(1.5f*sx+px, 1.0f*sy+py, 1.0f, -1.0f, -1.0f, _abgr); ++vertex;
vertex->set(2.0f*sx+px, 0.5f*sy+py, -1.0f, 1.0f, -1.0f, _abgr); ++vertex;
vertex->set(2.0f*sx+px, 1.0f*sy+py, -1.0f, -1.0f, -1.0f, _abgr); ++vertex;
indices += addQuad(indices, 0, 3, 4, 1);
indices += addQuad(indices, 2, 6, 7, 3);
indices += addQuad(indices, 3, 7, 8, 4);
indices += addQuad(indices, 4, 8, 9, 5);
indices += addQuad(indices, 7, 10, 11, 8);
indices += addQuad(indices, 10, 12, 13, 11);
}
else
{
const float sx = _width;
const float sy = _height;
const float px = float(_x) - sx/2.0f;
const float py = float(_y);
vertex->set(0.0f*sx+px, 0.25f*sy+py, -1.0f, 1.0f, -1.0f, _abgr); ++vertex;
vertex->set(0.0f*sx+px, 0.75f*sy+py, -1.0f, -1.0f, -1.0f, _abgr); ++vertex;
vertex->set(0.5f*sx+px, 0.00f*sy+py, -1.0f, 1.0f, 1.0f, _abgr); ++vertex;
vertex->set(0.5f*sx+px, 0.50f*sy+py, -1.0f, -1.0f, 1.0f, _abgr); ++vertex;
vertex->set(0.5f*sx+px, 1.00f*sy+py, 1.0f, -1.0f, -1.0f, _abgr); ++vertex;
vertex->set(1.0f*sx+px, 0.25f*sy+py, 1.0f, 1.0f, 1.0f, _abgr); ++vertex;
vertex->set(1.0f*sx+px, 0.75f*sy+py, 1.0f, -1.0f, 1.0f, _abgr); ++vertex;
vertex->set(1.0f*sx+px, 0.25f*sy+py, 1.0f, 1.0f, 1.0f, _abgr); ++vertex;
vertex->set(1.0f*sx+px, 0.75f*sy+py, 1.0f, -1.0f, 1.0f, _abgr); ++vertex;
vertex->set(1.5f*sx+px, 0.00f*sy+py, -1.0f, 1.0f, 1.0f, _abgr); ++vertex;
vertex->set(1.5f*sx+px, 0.50f*sy+py, 1.0f, 1.0f, -1.0f, _abgr); ++vertex;
vertex->set(1.5f*sx+px, 1.00f*sy+py, 1.0f, -1.0f, -1.0f, _abgr); ++vertex;
vertex->set(2.0f*sx+px, 0.25f*sy+py, -1.0f, 1.0f, -1.0f, _abgr); ++vertex;
vertex->set(2.0f*sx+px, 0.75f*sy+py, -1.0f, -1.0f, -1.0f, _abgr); ++vertex;
indices += addQuad(indices, 0, 2, 3, 1);
indices += addQuad(indices, 1, 3, 6, 4);
indices += addQuad(indices, 2, 5, 6, 3);
indices += addQuad(indices, 7, 9, 12, 10);
indices += addQuad(indices, 7, 10, 11, 8);
indices += addQuad(indices, 10, 12, 13, 11);
}
return false;
bgfx::setVertexBuffer(0, &tvb);
bgfx::setIndexBuffer(&tib);
}
}
}
template<bx::LerpFn lerpT, bx::EaseFn easeT>
@ -837,11 +950,15 @@ int _main_(int _argc, char** _argv)
imguiCreate();
PosUvColorVertex::init();
PosUvwColorVertex::init();
const bgfx::Caps* caps = bgfx::getCaps();
bgfx::RendererType::Enum type = caps->rendererType;
bgfx::UniformHandle s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1);
bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Mat4);
bgfx::UniformHandle u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4);
bgfx::ShaderHandle vsTexture = bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_texture");
bgfx::ShaderHandle fsTexture = bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_texture");
bgfx::ShaderHandle fsTextureArray = bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_texture_array");
@ -851,6 +968,7 @@ int _main_(int _argc, char** _argv)
, fsTexture
, true
);
bgfx::ProgramHandle textureArrayProgram = bgfx::createProgram(
vsTexture
, bgfx::isValid(fsTextureArray)
@ -865,19 +983,23 @@ int _main_(int _argc, char** _argv)
, true
);
bgfx::ProgramHandle textureCube2Program = bgfx::createProgram(
vsTexture
, bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_texture_cube2")
, true
);
bgfx::ProgramHandle textureSdfProgram = bgfx::createProgram(
vsTexture
, bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_texture_sdf")
, true);
, true
);
bgfx::ProgramHandle texture3DProgram = bgfx::createProgram(
vsTexture
, bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_texture_3d")
, true);
bgfx::UniformHandle s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1);
bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Mat4);
bgfx::UniformHandle u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4);
, true
);
const uint32_t checkerBoardSize = 64;
bgfx::TextureHandle checkerBoard;
@ -988,7 +1110,8 @@ int _main_(int _argc, char** _argv)
if (dragging)
{
if (view.m_info.cubeMap)
if (view.m_info.cubeMap
&& Geometry::Quad == view.m_cubeMapGeo)
{
char exec[64];
bx::snprintf(exec, BX_COUNTOF(exec), "view cubemap %+f %+f", -yDelta, -xDelta);
@ -1029,10 +1152,19 @@ int _main_(int _argc, char** _argv)
ImGui::EndPopup();
}
if (help == false
&& help != view.m_help)
if (help != view.m_help)
{
if (!help)
{
ImGui::OpenPopup("Help");
inputRemoveBindings(s_bindingName[Binding::View]);
}
else
{
inputAddBindings(s_bindingName[Binding::View], s_binding[Binding::View]);
}
help = view.m_help;
}
if (ImGui::BeginPopupModal("Help", NULL, ImGuiWindowFlags_AlwaysAutoResize) )
@ -1068,6 +1200,7 @@ int _main_(int _argc, char** _argv)
keyBindingHelp("<", "Reset MIP level.");
keyBindingHelp(",/,", "MIP level up/down.");
keyBindingHelp("/", "Toggle linear/point texture sampling.");
keyBindingHelp("[space]", "Change cubemap mode.");
ImGui::NextLine();
keyBindingHelp("left", "Previous layer in texture array.");
@ -1099,8 +1232,6 @@ int _main_(int _argc, char** _argv)
ImGui::EndPopup();
}
help = view.m_help;
imguiEndFrame();
if (!bgfx::isValid(texture)
@ -1175,12 +1306,22 @@ int _main_(int _argc, char** _argv)
float ortho[16];
bx::mtxOrtho(ortho, 0.0f, float(width), float(height), 0.0f, 0.0f, 1000.0f, 0.0f, caps->homogeneousDepth);
bx::mtxOrtho(
ortho
, 0.0f
, float(width)
, float(height)
, 0.0f
, 0.0f
, 1000.0f
, 0.0f
, caps->homogeneousDepth
);
bgfx::setViewTransform(BACKGROUND_VIEW_ID, NULL, ortho);
bgfx::setViewRect(BACKGROUND_VIEW_ID, 0, 0, uint16_t(width), uint16_t(height) );
screenQuad(
0
setGeometry(Geometry::Quad
, 0
, 0
, width
, height
@ -1202,7 +1343,17 @@ int _main_(int _argc, char** _argv)
float px = posx.getValue();
float py = posy.getValue();
bx::mtxOrtho(ortho, px-width/2, px+width/2, py+height/2, py-height/2, 0.0f, 1000.0f, 0.0f, caps->homogeneousDepth);
bx::mtxOrtho(
ortho
, px-width/2.0f
, px+width/2.0f
, py+height/2.0f
, py-height/2.0f
, 0.0f
, 1000.0f
, 0.0f
, caps->homogeneousDepth
);
bgfx::setViewTransform(IMAGE_VIEW_ID, NULL, ortho);
bgfx::setViewRect(IMAGE_VIEW_ID, 0, 0, uint16_t(width), uint16_t(height) );
@ -1229,8 +1380,8 @@ int _main_(int _argc, char** _argv)
* zoom.getValue()
;
screenQuad(
-int(view.m_info.width * ss)/2
setGeometry(view.m_info.cubeMap ? view.m_cubeMapGeo : Geometry::Quad
, -int(view.m_info.width * ss)/2
, -int(view.m_info.height * ss)/2
, int(view.m_info.width * ss)
, int(view.m_info.height * ss)
@ -1286,7 +1437,10 @@ int _main_(int _argc, char** _argv)
}
else if (view.m_info.cubeMap)
{
program = textureCubeProgram;
program = Geometry::Quad == view.m_cubeMapGeo
? textureCubeProgram
: textureCube2Program
;
}
else if (1 < view.m_info.numLayers)
{
@ -1307,6 +1461,7 @@ int _main_(int _argc, char** _argv)
{
bgfx::destroyTexture(texture);
}
bgfx::destroyTexture(checkerBoard);
bgfx::destroyUniform(s_texColor);
bgfx::destroyUniform(u_mtx);
@ -1314,7 +1469,9 @@ int _main_(int _argc, char** _argv)
bgfx::destroyProgram(textureProgram);
bgfx::destroyProgram(textureArrayProgram);
bgfx::destroyProgram(textureCubeProgram);
bgfx::destroyProgram(textureCube2Program);
bgfx::destroyProgram(textureSdfProgram);
bgfx::destroyProgram(texture3DProgram);
imguiDestroy();

View File

@ -1,8 +1,6 @@
vec4 v_color0 : COLOR0 = vec4(1.0, 0.0, 0.0, 1.0);
vec3 v_normal : NORMAL = vec3(0.0, 0.0, 1.0);
vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
vec4 v_color0 : COLOR0 = vec4(1.0, 1.0, 1.0, 1.0);
vec3 v_texcoord0 : TEXCOORD0 = vec3(0.0, 0.0, 0.0);
vec3 a_position : POSITION;
vec4 a_normal : NORMAL;
vec4 a_color0 : COLOR0;
vec2 a_texcoord0 : TEXCOORD0;
vec3 a_texcoord0 : TEXCOORD0;