Merge pull request #75 from dariomanesku/master

18-ibl example and some minor fixes.
This commit is contained in:
Branimir Karadžić 2014-02-14 00:07:16 -08:00
commit 8f56c5a120
53 changed files with 1133 additions and 45 deletions

View file

@ -19,7 +19,7 @@ SAMPLER2D(u_texStencil, 7);
#define u_ambientPass u_params.x
#define u_lightningPass u_params.y
#define u_alpha u_params.z
#define u_texelHalf u_params.z
#define u_specular u_specular_shininess.xyz
#define u_shininess u_specular_shininess.w
@ -68,6 +68,7 @@ void main()
vec3 lightColor = calcLight(v_view, normal, viewDir) * u_lightningPass;
vec2 ndc = ((v_pos.xy / v_pos.w) + 1.0) / 2.0;
ndc += u_viewTexel.xy * u_texelHalf;
vec4 texcolor = texture2D(u_texStencil, ndc);
float s = (texcolor.x - texcolor.y) + 2.0 * (texcolor.z - texcolor.w);
s *= u_useStencilTex;
@ -84,5 +85,5 @@ void main()
vec3 final = mix(ambient, ambient + diffuse, float((abs(s) < 0.0001)));
gl_FragColor.xyz = mix(u_fogColor, final, fogFactor);
gl_FragColor.w = u_alpha;
gl_FragColor.w = 1.0;
}

View file

@ -20,7 +20,7 @@ SAMPLER2D(u_texStencil, 7);
#define u_ambientPass u_params.x
#define u_lightningPass u_params.y
#define u_alpha u_params.z
#define u_texelHalf u_params.z
#define u_specular u_specular_shininess.xyz
#define u_shininess u_specular_shininess.w
@ -69,6 +69,7 @@ void main()
vec3 lightColor = calcLight(v_view, normal, viewDir) * u_lightningPass;
vec2 ndc = ((v_pos.xy / v_pos.w) + 1.0) / 2.0;
ndc += u_viewTexel.xy * u_texelHalf;
vec4 texcolor = texture2D(u_texStencil, ndc);
float s = (texcolor.x - texcolor.y) + 2.0 * (texcolor.z - texcolor.w);
s *= u_useStencilTex;
@ -85,6 +86,6 @@ void main()
vec3 final = mix(ambient, ambient + diffuse, float((abs(s) < 0.0001)));
gl_FragColor.xyz = mix(u_fogColor, final, fogFactor);
gl_FragColor.w = u_alpha;
gl_FragColor.w = 1.0;
}

View file

@ -99,6 +99,7 @@ static const uint16_t s_planeIndices[s_numPlaneIndices] =
static const char* s_shaderPath = NULL;
static bool s_flipV = false;
static float s_texelHalf = 0.0f;
static uint32_t s_viewMask = 0;
@ -266,8 +267,7 @@ struct Uniforms
{
m_params.m_ambientPass = 1.0f;
m_params.m_lightningPass = 1.0f;
m_params.m_lightCount = 4.0f;
m_params.m_alpha = 1.0f;
m_params.m_texelHalf = 0.0f;
m_ambient[0] = 0.05f;
m_ambient[1] = 0.05f;
@ -374,16 +374,16 @@ struct Uniforms
{
float m_ambientPass;
float m_lightningPass;
float m_alpha;
float m_lightCount;
float m_texelHalf;
float m_unused00;
};
struct SvParams
{
float m_useStencilTex;
float m_dfail;
float m_unused0;
float m_unused1;
float m_unused10;
float m_unused11;
};
Params m_params;
@ -402,8 +402,8 @@ struct Uniforms
/**
* u_params.x - u_ambientPass
* u_params.y - u_lightningPass
* u_params.z - u_alpha
* u_params.w - u_lightCount
* u_params.z - u_texelHalf
* u_params.w - unused
* u_svparams.x - u_useStencilTex
* u_svparams.y - u_dfail
@ -1944,23 +1944,22 @@ int _main_(int /*_argc*/, char** /*_argv*/)
default:
case bgfx::RendererType::Direct3D9:
s_shaderPath = "shaders/dx9/";
s_flipV = true;
s_texelHalf = 0.5f;
break;
case bgfx::RendererType::Direct3D11:
s_shaderPath = "shaders/dx11/";
s_flipV = true;
break;
case bgfx::RendererType::OpenGL:
s_shaderPath = "shaders/glsl/";
s_flipV = false;
s_flipV = true;
break;
case bgfx::RendererType::OpenGLES2:
case bgfx::RendererType::OpenGLES3:
s_shaderPath = "shaders/gles/";
s_flipV = false;
s_flipV = true;
break;
}
@ -2331,7 +2330,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
//update settings
s_uniforms.m_params.m_ambientPass = 1.0f;
s_uniforms.m_params.m_lightningPass = 1.0f;
s_uniforms.m_params.m_lightCount = settings_numLights;
s_uniforms.m_params.m_texelHalf = s_texelHalf;
s_uniforms.m_svparams.m_useStencilTex = float(settings_useStencilTexture);
s_uniforms.submitPerFrameUniforms();

View file

@ -19,5 +19,5 @@ void main()
v_view = mul(u_modelView, vec4(a_position, 1.0)).xyz;
v_pos = gl_Position;
v_pos.y *= -u_flipV;
v_pos.y *= u_flipV;
}

View file

@ -21,5 +21,5 @@ void main()
v_texcoord0 = a_texcoord0;
v_pos = gl_Position;
v_pos.y *= -u_flipV;
v_pos.y *= u_flipV;
}

View file

@ -86,9 +86,9 @@ struct LightType
{
enum Enum
{
SpotLight = 0,
PointLight = 1,
DirectionalLight = 2,
SpotLight,
PointLight,
DirectionalLight,
Count
};
@ -99,8 +99,8 @@ struct DepthImpl
{
enum Enum
{
InvZ = 0,
Linear = 1,
InvZ,
Linear,
Count
};
@ -110,8 +110,8 @@ struct PackDepth
{
enum Enum
{
RGBA = 0,
VSM = 1,
RGBA,
VSM,
Count
};
@ -121,10 +121,10 @@ struct SmImpl
{
enum Enum
{
Hard = 0,
PCF = 1,
VSM = 2,
ESM = 3,
Hard,
PCF,
VSM,
ESM,
Count
};
@ -134,9 +134,9 @@ struct SmType
{
enum Enum
{
Single = 0,
Omni = 1,
Cascade = 2,
Single,
Omni,
Cascade,
Count
};
@ -146,12 +146,12 @@ struct TetrahedronFaces
{
enum Enum
{
Green = 0,
Yellow = 1,
Blue = 2,
Red = 3,
Green,
Yellow,
Blue,
Red,
Count = 4
Count
};
};
@ -159,8 +159,8 @@ struct ProjType
{
enum Enum
{
Horizontal = 0,
Vertical = 1,
Horizontal,
Vertical,
Count
};
@ -170,10 +170,10 @@ struct ShadowMapRenderTargets
{
enum Enum
{
First = 0,
Second = 1,
Third = 2,
Fourth = 3,
First,
Second,
Third,
Fourth,
Count
};

View file

@ -0,0 +1,79 @@
$input v_view, v_normal
/*
* Copyright 2014 Dario Manesku. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "../common/common.sh"
uniform float u_time;
uniform vec4 u_params;
uniform mat4 u_mtx;
uniform vec4 u_flags;
uniform vec3 u_camPos;
uniform vec3 u_rgbDiff;
uniform vec3 u_rgbSpec;
SAMPLERCUBE(u_texCube, 4);
SAMPLERCUBE(u_texCubeIrr, 5);
#define u_glossiness u_params.x
#define u_exposure u_params.y
#define u_diffspec u_params.z
#define u_doDiffuse u_flags.x
#define u_doSpecular u_flags.y
#define u_doDiffuseIbl u_flags.z
#define u_doSpecularIbl u_flags.w
vec3 fresnel(vec3 _cspec, float _dot)
{
return _cspec + (1.0 - _cspec) * pow(1.0 - _dot, 5);
}
void main()
{
vec3 light = vec3(0.0f, 0.0f, -1.0f);
vec3 clight = vec3(1.0f, 1.0f, 1.0f);
vec3 v = v_view;
vec3 n = normalize(v_normal);
vec3 l = normalize(light);
vec3 h = normalize(v + l);
float ndotl = clamp(dot(n, l), 0.0, 1.0); //diff
float ndoth = clamp(dot(n, h), 0.0, 1.0); //spec
float vdoth = clamp(dot(v, h), 0.0, 1.0); //spec fresnel
float ndotv = clamp(dot(n, v), 0.0, 1.0); //env spec fresnel
vec3 r = 2.0*ndotv*n - v; // reflect(v, n);
vec3 cubeR = normalize(mul(u_mtx, vec4(r, 0.0)).xyz);
vec3 cubeN = normalize(mul(u_mtx, vec4(n, 0.0)).xyz);
float mipLevel = min((1.0 - u_glossiness)*11.0 + 1.0, 8.0);
vec3 cenv = textureCubeLod(u_texCube, cubeR, mipLevel).xyz;
vec3 kd = u_rgbDiff;
vec3 ks = u_rgbSpec;
vec3 cs = ks * u_diffspec;
vec3 cd = kd * (1.0 - cs);
vec3 diff = cd;
float pwr = exp2(u_glossiness * 11.0 + 1.0);
vec3 spec = cs * pow(ndoth, pwr) * ( (pwr + 8.0)/8.0) * fresnel(cs, vdoth);
vec3 ambspec = fresnel(cs, ndotv) * cenv;
vec3 ambdiff = cd * textureCube(u_texCubeIrr, cubeN).xyz;
vec3 lc = ( diff * u_doDiffuse + spec * u_doSpecular ) * ndotl * clight;
vec3 ec = (ambdiff * u_doDiffuseIbl + ambspec * u_doSpecularIbl);
vec3 color = lc + ec;
color = color * exp2(u_exposure);
gl_FragColor.xyz = toFilmic(color);
gl_FragColor.w = 1.0;
}

View file

@ -0,0 +1,23 @@
$input v_dir
/*
* Copyright 2014 Dario Manesku. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "../common/common.sh"
SAMPLERCUBE(u_texCube, 4);
uniform vec4 u_params;
#define u_exposure u_params.y
void main()
{
vec3 dir = normalize(v_dir);
vec4 color = textureCubeLod(u_texCube, dir, 0.0);
color *= exp2(u_exposure);
gl_FragColor = toFilmic(color);
}

921
examples/18-ibl/ibl.cpp Normal file
View file

@ -0,0 +1,921 @@
/*
* Copyright 2014 Dario Manesku. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include <string>
#include <vector>
#include "common.h"
#include <bgfx.h>
#include <bx/timer.h>
#include <bx/readerwriter.h>
#include "entry/entry.h"
#include "fpumath.h"
#include "imgui/imgui.h"
#include <stdio.h>
#include <string.h>
static const char* s_shaderPath = NULL;
static bool s_flipV = false;
static float s_texelHalf = 0.0f;
static void shaderFilePath(char* _out, const char* _name)
{
strcpy(_out, s_shaderPath);
strcat(_out, _name);
strcat(_out, ".bin");
}
long int fsize(FILE* _file)
{
long int pos = ftell(_file);
fseek(_file, 0L, SEEK_END);
long int size = ftell(_file);
fseek(_file, pos, SEEK_SET);
return size;
}
static const bgfx::Memory* load(const char* _filePath)
{
FILE* file = fopen(_filePath, "rb");
if (NULL != file)
{
uint32_t size = (uint32_t)fsize(file);
const bgfx::Memory* mem = bgfx::alloc(size+1);
size_t ignore = fread(mem->data, 1, size, file);
BX_UNUSED(ignore);
fclose(file);
mem->data[mem->size-1] = '\0';
return mem;
}
return NULL;
}
static const bgfx::Memory* loadShader(const char* _name)
{
char filePath[512];
shaderFilePath(filePath, _name);
return load(filePath);
}
static bgfx::ProgramHandle loadProgram(const char* _vsName, const char* _fsName)
{
const bgfx::Memory* mem;
mem = loadShader(_vsName);
bgfx::VertexShaderHandle vs = bgfx::createVertexShader(mem);
mem = loadShader(_fsName);
bgfx::FragmentShaderHandle fs = bgfx::createFragmentShader(mem);
bgfx::ProgramHandle program = bgfx::createProgram(vs, fs);
bgfx::destroyVertexShader(vs);
bgfx::destroyFragmentShader(fs);
return program;
}
static const bgfx::Memory* loadTexture(const char* _name)
{
char filePath[512];
strcpy(filePath, "textures/");
strcat(filePath, _name);
return load(filePath);
}
struct Uniforms
{
void init()
{
m_time = 0.0f;
mtxIdentity(m_mtx);
u_time = bgfx::createUniform("u_time", bgfx::UniformType::Uniform1f);
u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Uniform4x4fv);
u_params = bgfx::createUniform("u_params", bgfx::UniformType::Uniform4fv);
u_flags = bgfx::createUniform("u_flags", bgfx::UniformType::Uniform4fv);
u_camPos = bgfx::createUniform("u_camPos", bgfx::UniformType::Uniform3fv);
u_rgbDiff = bgfx::createUniform("u_rgbDiff", bgfx::UniformType::Uniform3fv);
u_rgbSpec = bgfx::createUniform("u_rgbSpec", bgfx::UniformType::Uniform3fv);
}
// Call this once at initialization.
void submitConstUniforms()
{
}
// Call this once per frame.
void submitPerFrameUniforms()
{
bgfx::setUniform(u_time, &m_time);
bgfx::setUniform(u_mtx, m_mtx);
bgfx::setUniform(u_flags, m_flags);
bgfx::setUniform(u_camPos, m_camPos);
bgfx::setUniform(u_rgbDiff, m_rgbDiff);
bgfx::setUniform(u_rgbSpec, m_rgbSpec);
}
// Call this before each draw call.
void submitPerDrawUniforms()
{
bgfx::setUniform(u_params, m_params);
}
void destroy()
{
bgfx::destroyUniform(u_rgbSpec);
bgfx::destroyUniform(u_rgbDiff);
bgfx::destroyUniform(u_camPos);
bgfx::destroyUniform(u_flags);
bgfx::destroyUniform(u_params);
bgfx::destroyUniform(u_mtx);
bgfx::destroyUniform(u_time);
}
union
{
struct
{
float m_glossiness;
float m_exposure;
float m_diffspec;
float m_unused0;
};
float m_params[4];
};
union
{
struct
{
float m_diffuse;
float m_specular;
float m_diffuseIbl;
float m_specularIbl;
};
float m_flags[4];
};
float m_time;
float m_mtx[16];
float m_camPos[3];
float m_rgbDiff[3];
float m_rgbSpec[3];
bgfx::UniformHandle u_time;
bgfx::UniformHandle u_mtx;
bgfx::UniformHandle u_params;
bgfx::UniformHandle u_flags;
bgfx::UniformHandle u_camPos;
bgfx::UniformHandle u_rgbDiff;
bgfx::UniformHandle u_rgbSpec;
};
static Uniforms s_uniforms;
struct Aabb
{
float m_min[3];
float m_max[3];
};
struct Obb
{
float m_mtx[16];
};
struct Sphere
{
float m_center[3];
float m_radius;
};
struct Primitive
{
uint32_t m_startIndex;
uint32_t m_numIndices;
uint32_t m_startVertex;
uint32_t m_numVertices;
Sphere m_sphere;
Aabb m_aabb;
Obb m_obb;
};
typedef std::vector<Primitive> PrimitiveArray;
struct Group
{
Group()
{
reset();
}
void reset()
{
m_vbh.idx = bgfx::invalidHandle;
m_ibh.idx = bgfx::invalidHandle;
m_prims.clear();
}
bgfx::VertexBufferHandle m_vbh;
bgfx::IndexBufferHandle m_ibh;
Sphere m_sphere;
Aabb m_aabb;
Obb m_obb;
PrimitiveArray m_prims;
};
struct Mesh
{
void load(const char* _filePath)
{
#define BGFX_CHUNK_MAGIC_VB BX_MAKEFOURCC('V', 'B', ' ', 0x0)
#define BGFX_CHUNK_MAGIC_IB BX_MAKEFOURCC('I', 'B', ' ', 0x0)
#define BGFX_CHUNK_MAGIC_PRI BX_MAKEFOURCC('P', 'R', 'I', 0x0)
bx::CrtFileReader reader;
reader.open(_filePath);
Group group;
uint32_t chunk;
while (4 == bx::read(&reader, chunk) )
{
switch (chunk)
{
case BGFX_CHUNK_MAGIC_VB:
{
bx::read(&reader, group.m_sphere);
bx::read(&reader, group.m_aabb);
bx::read(&reader, group.m_obb);
bx::read(&reader, m_decl);
uint16_t stride = m_decl.getStride();
uint16_t numVertices;
bx::read(&reader, numVertices);
const bgfx::Memory* mem = bgfx::alloc(numVertices*stride);
bx::read(&reader, mem->data, mem->size);
group.m_vbh = bgfx::createVertexBuffer(mem, m_decl);
}
break;
case BGFX_CHUNK_MAGIC_IB:
{
uint32_t numIndices;
bx::read(&reader, numIndices);
const bgfx::Memory* mem = bgfx::alloc(numIndices*2);
bx::read(&reader, mem->data, mem->size);
group.m_ibh = bgfx::createIndexBuffer(mem);
}
break;
case BGFX_CHUNK_MAGIC_PRI:
{
uint16_t len;
bx::read(&reader, len);
std::string material;
material.resize(len);
bx::read(&reader, const_cast<char*>(material.c_str() ), len);
uint16_t num;
bx::read(&reader, num);
for (uint32_t ii = 0; ii < num; ++ii)
{
bx::read(&reader, len);
std::string name;
name.resize(len);
bx::read(&reader, const_cast<char*>(name.c_str() ), len);
Primitive prim;
bx::read(&reader, prim.m_startIndex);
bx::read(&reader, prim.m_numIndices);
bx::read(&reader, prim.m_startVertex);
bx::read(&reader, prim.m_numVertices);
bx::read(&reader, prim.m_sphere);
bx::read(&reader, prim.m_aabb);
bx::read(&reader, prim.m_obb);
group.m_prims.push_back(prim);
}
m_groups.push_back(group);
group.reset();
}
break;
default:
DBG("%08x at %d", chunk, reader.seek() );
break;
}
}
reader.close();
}
void unload()
{
for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it)
{
const Group& group = *it;
bgfx::destroyVertexBuffer(group.m_vbh);
if (bgfx::isValid(group.m_ibh) )
{
bgfx::destroyIndexBuffer(group.m_ibh);
}
}
m_groups.clear();
}
void submit(uint8_t _view, bgfx::ProgramHandle _program, float* _mtx)
{
for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it)
{
const Group& group = *it;
// Set uniforms.
s_uniforms.submitPerDrawUniforms();
// Set model matrix for rendering.
bgfx::setTransform(_mtx);
bgfx::setProgram(_program);
bgfx::setIndexBuffer(group.m_ibh);
bgfx::setVertexBuffer(group.m_vbh);
// Set render states.
bgfx::setState(0
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_ALPHA_WRITE
| BGFX_STATE_DEPTH_WRITE
| BGFX_STATE_DEPTH_TEST_LESS
| BGFX_STATE_CULL_CCW
| BGFX_STATE_MSAA
);
// Submit primitive for rendering to view 0.
bgfx::submit(_view);
}
}
bgfx::VertexDecl m_decl;
typedef std::vector<Group> GroupArray;
GroupArray m_groups;
};
struct PosColorTexCoord0Vertex
{
float m_x;
float m_y;
float m_z;
uint32_t m_rgba;
float m_u;
float m_v;
static void init()
{
ms_decl.begin();
ms_decl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
ms_decl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true);
ms_decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
ms_decl.end();
}
static bgfx::VertexDecl ms_decl;
};
bgfx::VertexDecl PosColorTexCoord0Vertex::ms_decl;
void screenSpaceQuad(float _textureWidth, float _textureHeight, bool _originBottomLeft = false, float _width = 1.0f, float _height = 1.0f)
{
if (bgfx::checkAvailTransientVertexBuffer(3, PosColorTexCoord0Vertex::ms_decl) )
{
bgfx::TransientVertexBuffer vb;
bgfx::allocTransientVertexBuffer(&vb, 3, PosColorTexCoord0Vertex::ms_decl);
PosColorTexCoord0Vertex* vertex = (PosColorTexCoord0Vertex*)vb.data;
const float zz = 0.0f;
const float minx = -_width;
const float maxx = _width;
const float miny = 0.0f;
const float maxy = _height*2.0f;
const float texelHalfW = s_texelHalf/_textureWidth;
const float texelHalfH = s_texelHalf/_textureHeight;
const float minu = -1.0f + texelHalfW;
const float maxu = 1.0f + texelHalfW;
float minv = texelHalfH;
float maxv = 2.0f + texelHalfH;
if (_originBottomLeft)
{
std::swap(minv, maxv);
minv -= 1.0f;
maxv -= 1.0f;
}
vertex[0].m_x = minx;
vertex[0].m_y = miny;
vertex[0].m_z = zz;
vertex[0].m_rgba = 0xffffffff;
vertex[0].m_u = minu;
vertex[0].m_v = minv;
vertex[1].m_x = maxx;
vertex[1].m_y = miny;
vertex[1].m_z = zz;
vertex[1].m_rgba = 0xffffffff;
vertex[1].m_u = maxu;
vertex[1].m_v = minv;
vertex[2].m_x = maxx;
vertex[2].m_y = maxy;
vertex[2].m_z = zz;
vertex[2].m_rgba = 0xffffffff;
vertex[2].m_u = maxu;
vertex[2].m_v = maxv;
bgfx::setVertexBuffer(&vb);
}
}
void mtxScaleRotateTranslate(float* _result
, const float _scaleX
, const float _scaleY
, const float _scaleZ
, const float _rotX
, const float _rotY
, const float _rotZ
, const float _translateX
, const float _translateY
, const float _translateZ
)
{
float mtxRotateTranslate[16];
float mtxScale[16];
mtxRotateXYZ(mtxRotateTranslate, _rotX, _rotY, _rotZ);
mtxRotateTranslate[12] = _translateX;
mtxRotateTranslate[13] = _translateY;
mtxRotateTranslate[14] = _translateZ;
memset(mtxScale, 0, sizeof(float)*16);
mtxScale[0] = _scaleX;
mtxScale[5] = _scaleY;
mtxScale[10] = _scaleZ;
mtxScale[15] = 1.0f;
mtxMul(_result, mtxScale, mtxRotateTranslate);
}
void imguiBool(const char* _str, bool& _flag, bool _enabled = true)
{
if (imguiCheck(_str, _flag, _enabled) )
{
_flag = !_flag;
}
}
int _main_(int /*_argc*/, char** /*_argv*/)
{
uint32_t width = 1280;
uint32_t height = 720;
uint32_t debug = BGFX_DEBUG_TEXT;
uint32_t reset = BGFX_RESET_VSYNC;
bgfx::init();
bgfx::reset(width, height, reset);
// Enable debug text.
bgfx::setDebug(debug);
// Set views clear state.
bgfx::setViewClear(0
, BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT
, 0x303030ff
, 1.0f
, 0
);
// Setup root path for binary shaders. Shader binaries are different
// for each renderer.
switch (bgfx::getRendererType() )
{
default:
case bgfx::RendererType::Direct3D9:
s_shaderPath = "shaders/dx9/";
break;
case bgfx::RendererType::Direct3D11:
s_shaderPath = "shaders/dx11/";
break;
case bgfx::RendererType::OpenGL:
s_shaderPath = "shaders/glsl/";
s_flipV = true;
break;
case bgfx::RendererType::OpenGLES2:
case bgfx::RendererType::OpenGLES3:
s_shaderPath = "shaders/gles/";
s_flipV = true;
break;
}
// Imgui.
FILE* file = fopen("font/droidsans.ttf", "rb");
uint32_t size = (uint32_t)fsize(file);
void* data = malloc(size);
size_t ignore = fread(data, 1, size, file);
BX_UNUSED(ignore);
fclose(file);
imguiCreate(data, size);
// Uniforms.
s_uniforms.init();
// Vertex declarations.
PosColorTexCoord0Vertex::init();
struct LightProbe
{
void load(const char* _name)
{
const uint32_t texFlags = BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_W_CLAMP;
char filePath[512];
strcpy(filePath, _name);
strcat(filePath, "_lod.dds");
m_tex = bgfx::createTexture(loadTexture(filePath), texFlags);
strcpy(filePath, _name);
strcat(filePath, "_irr.dds");
m_texIrr = bgfx::createTexture(loadTexture(filePath), texFlags);
}
void destroy()
{
bgfx::destroyTexture(m_tex);
bgfx::destroyTexture(m_texIrr);
}
bgfx::TextureHandle m_tex;
bgfx::TextureHandle m_texIrr;
};
enum LightProbes
{
LPWells,
LPUffizi,
LPPisa,
LPEnnis,
LPGrace,
LPCount
};
LightProbe lightProbes[LPCount];
lightProbes[LPWells].load("wells");
lightProbes[LPUffizi].load("uffizi");
lightProbes[LPPisa].load("pisa");
lightProbes[LPEnnis].load("ennis");
lightProbes[LPGrace].load("grace");
uint8_t currentLightProbe = LPWells;
bgfx::UniformHandle u_time = bgfx::createUniform("u_time", bgfx::UniformType::Uniform1f);
bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Uniform4x4fv);
bgfx::UniformHandle u_params = bgfx::createUniform("u_params", bgfx::UniformType::Uniform4fv);
bgfx::UniformHandle u_flags = bgfx::createUniform("u_flags", bgfx::UniformType::Uniform4fv);
bgfx::UniformHandle u_camPos = bgfx::createUniform("u_camPos", bgfx::UniformType::Uniform3fv);
bgfx::UniformHandle u_texCube = bgfx::createUniform("u_texCube", bgfx::UniformType::Uniform1i);
bgfx::UniformHandle u_texCubeIrr = bgfx::createUniform("u_texCubeIrr", bgfx::UniformType::Uniform1i);
bgfx::UniformHandle u_texAlbedo = bgfx::createUniform("u_texAlbedo", bgfx::UniformType::Uniform1i);
bgfx::UniformHandle u_texNormal = bgfx::createUniform("u_texNormal", bgfx::UniformType::Uniform1i);
bgfx::UniformHandle u_texSpecular = bgfx::createUniform("u_texSpecular", bgfx::UniformType::Uniform1i);
bgfx::UniformHandle u_texRoughness = bgfx::createUniform("u_texRoughness", bgfx::UniformType::Uniform1i);
bgfx::ProgramHandle programMesh = loadProgram("vs_ibl_mesh", "fs_ibl_mesh");
bgfx::ProgramHandle programSky = loadProgram("vs_ibl_skybox", "fs_ibl_skybox");
Mesh meshBunny;
meshBunny.load("meshes/bunny.bin");
struct Settings
{
float m_speed;
float m_glossiness;
float m_exposure;
float m_diffspec;
float m_rgbDiff[3];
float m_rgbSpec[3];
bool m_diffuse;
bool m_specular;
bool m_diffuseIbl;
bool m_specularIbl;
bool m_singleSliderDiff;
bool m_singleSliderSpec;
};
Settings settings;
settings.m_speed = 0.37f;
settings.m_glossiness = 1.0f;
settings.m_exposure = 0.0f;
settings.m_diffspec = 0.65f;
settings.m_rgbDiff[0] = 0.2f;
settings.m_rgbDiff[1] = 0.2f;
settings.m_rgbDiff[2] = 0.2f;
settings.m_rgbSpec[0] = 1.0f;
settings.m_rgbSpec[1] = 1.0f;
settings.m_rgbSpec[2] = 1.0f;
settings.m_diffuse = true;
settings.m_specular = true;
settings.m_diffuseIbl = true;
settings.m_specularIbl = true;
settings.m_singleSliderDiff = false;
settings.m_singleSliderSpec = false;
float time = 0.0f;
s_uniforms.submitConstUniforms();
entry::MouseState mouseState;
while (!entry::processEvents(width, height, debug, reset, &mouseState) )
{
imguiBeginFrame(mouseState.m_mx
, mouseState.m_my
, (mouseState.m_buttons[entry::MouseButton::Left ] ? IMGUI_MBUT_LEFT : 0)
| (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0)
, 0
, width
, height
);
static int32_t rightScrollArea = 0;
imguiBeginScrollArea("Settings", width - 256 - 10, 10, 256, 426, &rightScrollArea);
imguiLabel("Shade:");
imguiSeparator();
imguiBool("Diffuse", settings.m_diffuse);
imguiBool("Specular", settings.m_specular);
imguiBool("IBL Diffuse", settings.m_diffuseIbl);
imguiBool("IBL Specular", settings.m_specularIbl);
imguiSeparatorLine();
imguiSlider("Speed", &settings.m_speed, 0.0f, 1.0f, 0.01f);
imguiSeparatorLine();
imguiLabel("Environment:");
currentLightProbe = imguiChoose(currentLightProbe
, "Wells"
, "Uffizi"
, "Pisa"
, "Ennis"
, "Grace"
);
imguiSeparator();
imguiSlider("Exposure", &settings.m_exposure, -8.0f, 8.0f, 0.01f);
imguiEndScrollArea();
static int32_t leftScrollArea = 0;
imguiBeginScrollArea("Settings", 10, 70, 256, 576, &leftScrollArea);
imguiLabel("Material properties:");
imguiSeparator();
imguiSlider("Diffuse - Specular", &settings.m_diffspec, 0.0f, 1.0f, 0.01f);
imguiSlider("Glossiness" , &settings.m_glossiness, 0.0f, 1.0f, 0.01f);
imguiSeparatorLine();
imguiLabel("Diffuse color:");
imguiSeparator();
imguiBool("Single slider", settings.m_singleSliderDiff);
if (settings.m_singleSliderDiff)
{
imguiSlider("RGB:", &settings.m_rgbDiff[0], 0.0f, 1.0f, 0.01f);
settings.m_rgbDiff[1] = settings.m_rgbDiff[0];
settings.m_rgbDiff[2] = settings.m_rgbDiff[0];
}
else
{
imguiSlider("R:", &settings.m_rgbDiff[0], 0.0f, 1.0f, 0.01f);
imguiSlider("G:", &settings.m_rgbDiff[1], 0.0f, 1.0f, 0.01f);
imguiSlider("B:", &settings.m_rgbDiff[2], 0.0f, 1.0f, 0.01f);
}
imguiSeparatorLine();
imguiLabel("Specular color:");
imguiSeparator();
imguiBool("Single slider", settings.m_singleSliderSpec);
if (settings.m_singleSliderSpec)
{
imguiSlider("RGB:", &settings.m_rgbSpec[0], 0.0f, 1.0f, 0.01f);
settings.m_rgbSpec[1] = settings.m_rgbSpec[0];
settings.m_rgbSpec[2] = settings.m_rgbSpec[0];
}
else
{
imguiSlider("R:", &settings.m_rgbSpec[0], 0.0f, 1.0f, 0.01f);
imguiSlider("G:", &settings.m_rgbSpec[1], 0.0f, 1.0f, 0.01f);
imguiSlider("B:", &settings.m_rgbSpec[2], 0.0f, 1.0f, 0.01f);
}
imguiSeparatorLine();
imguiLabel("Predefined materials:");
imguiSeparator();
if (imguiButton("Gold") )
{
settings.m_glossiness = 0.8f;
settings.m_diffspec = 1.0f;
settings.m_rgbDiff[0] = 0.0f;
settings.m_rgbDiff[1] = 0.0f;
settings.m_rgbDiff[2] = 0.0f;
settings.m_rgbSpec[0] = 1.0f;
settings.m_rgbSpec[1] = 0.86f;
settings.m_rgbSpec[2] = 0.58f;
settings.m_singleSliderSpec = false;
}
if (imguiButton("Copper") )
{
settings.m_glossiness = 0.67f;
settings.m_diffspec = 1.0f;
settings.m_rgbDiff[0] = 0.0f;
settings.m_rgbDiff[1] = 0.0f;
settings.m_rgbDiff[2] = 0.0f;
settings.m_rgbSpec[0] = 0.98f;
settings.m_rgbSpec[1] = 0.82f;
settings.m_rgbSpec[2] = 0.76f;
settings.m_singleSliderSpec = false;
}
if (imguiButton("Titanium") )
{
settings.m_glossiness = 0.57f;
settings.m_diffspec = 1.0f;
settings.m_rgbDiff[0] = 0.0f;
settings.m_rgbDiff[1] = 0.0f;
settings.m_rgbDiff[2] = 0.0f;
settings.m_rgbSpec[0] = 0.76f;
settings.m_rgbSpec[1] = 0.73f;
settings.m_rgbSpec[2] = 0.71f;
settings.m_singleSliderSpec = false;
}
if (imguiButton("Steel") )
{
settings.m_glossiness = 0.82f;
settings.m_diffspec = 1.0f;
settings.m_rgbDiff[0] = 0.0f;
settings.m_rgbDiff[1] = 0.0f;
settings.m_rgbDiff[2] = 0.0f;
settings.m_rgbSpec[0] = 0.77f;
settings.m_rgbSpec[1] = 0.78f;
settings.m_rgbSpec[2] = 0.77f;
settings.m_singleSliderSpec = false;
}
imguiEndScrollArea();
imguiEndFrame();
s_uniforms.m_glossiness = settings.m_glossiness;
s_uniforms.m_exposure = settings.m_exposure;
s_uniforms.m_diffspec = settings.m_diffspec;
s_uniforms.m_flags[0] = float(settings.m_diffuse);
s_uniforms.m_flags[1] = float(settings.m_specular);
s_uniforms.m_flags[2] = float(settings.m_diffuseIbl);
s_uniforms.m_flags[3] = float(settings.m_specularIbl);
memcpy(s_uniforms.m_rgbDiff, settings.m_rgbDiff, 3*sizeof(float));
memcpy(s_uniforms.m_rgbSpec, settings.m_rgbSpec, 3*sizeof(float));
s_uniforms.submitPerFrameUniforms();
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 double toMs = 1000.0/freq;
time += (float)(frameTime*settings.m_speed/freq);
s_uniforms.m_time = time;
// Use debug font to print information about this example.
bgfx::dbgTextClear();
bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/18-ibl");
bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Image based lightning.");
bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
float at[3] = { 0.0f, 0.0f, 0.0f };
float eye[3] = { 0.0f, 0.0f, -3.0f };
mtxRotateXY(s_uniforms.m_mtx
, 0.0f
, time
);
float view[16];
float proj[16];
mtxIdentity(view);
mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f);
bgfx::setViewTransform(0, view, proj);
mtxLookAt(view, eye, at);
memcpy(s_uniforms.m_camPos, eye, 3*sizeof(float));
mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f);
bgfx::setViewTransform(1, view, proj);
bgfx::setViewRect(0, 0, 0, width, height);
bgfx::setViewRect(1, 0, 0, width, height);
// View 0.
bgfx::setTexture(4, u_texCube, lightProbes[currentLightProbe].m_tex);
bgfx::setProgram(programSky);
bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
screenSpaceQuad( (float)width, (float)height, true);
bgfx::submit(0);
// View 1.
float mtx[16];
mtxScaleRotateTranslate(mtx
, 1.0f
, 1.0f
, 1.0f
, 0.0f
, (float(M_PI))+time
, 0.0f
, 0.0f
, -1.0f
, 0.0f
);
bgfx::setTexture(4, u_texCube, lightProbes[currentLightProbe].m_tex);
bgfx::setTexture(5, u_texCubeIrr, lightProbes[currentLightProbe].m_texIrr);
meshBunny.submit(1, programMesh, mtx);
// Advance to next frame. Rendering thread will be kicked to
// process submitted rendering primitives.
bgfx::frame();
}
meshBunny.unload();
// Cleanup.
bgfx::destroyProgram(programMesh);
bgfx::destroyProgram(programSky);
bgfx::destroyUniform(u_camPos);
bgfx::destroyUniform(u_flags);
bgfx::destroyUniform(u_params);
bgfx::destroyUniform(u_mtx);
bgfx::destroyUniform(u_time);
bgfx::destroyUniform(u_texRoughness);
bgfx::destroyUniform(u_texSpecular);
bgfx::destroyUniform(u_texNormal);
bgfx::destroyUniform(u_texAlbedo);
bgfx::destroyUniform(u_texCube);
bgfx::destroyUniform(u_texCubeIrr);
for (uint8_t ii = 0; ii < LPCount; ++ii)
{
lightProbes[ii].destroy();
}
s_uniforms.destroy();
imguiDestroy();
// Shutdown bgfx.
bgfx::shutdown();
return 0;
}

17
examples/18-ibl/makefile Normal file
View file

@ -0,0 +1,17 @@
#
# Copyright 2014 Dario Manesku. All rights reserved.
# License: http://www.opensource.org/licenses/BSD-2-Clause
#
BGFX_DIR=../..
RUNTIME_DIR=$(BGFX_DIR)/examples/runtime
BUILD_DIR=../../.build
include $(BGFX_DIR)/premake/shader.mk
rebuild:
@make -s --no-print-directory TARGET=0 clean all
@make -s --no-print-directory TARGET=1 clean all
@make -s --no-print-directory TARGET=2 clean all
@make -s --no-print-directory TARGET=3 clean all
@make -s --no-print-directory TARGET=4 clean all

View file

@ -0,0 +1,7 @@
vec3 v_normal : NORMAL = vec3(0.0, 0.0, 1.0);
vec3 v_dir : TEXCOORD1 = vec3(0.0, 0.0, 0.0);
vec3 v_view : TEXCOORD2 = vec3(0.0, 0.0, 0.0);
vec3 a_position : POSITION;
vec2 a_texcoord0 : TEXCOORD0;
vec3 a_normal : NORMAL;

View file

@ -0,0 +1,20 @@
$input a_position, a_normal
$output v_view, v_normal
/*
* Copyright 2014 Dario Manesku. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "../common/common.sh"
uniform vec3 u_camPos;
void main()
{
gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) );
vec3 normal = a_normal * 2.0 - 1.0;
v_normal = mul(u_model[0], vec4(normal, 0.0) ).xyz;
v_view = normalize(u_camPos - mul(u_model[0], vec4(a_position, 1.0)).xyz);
}

View file

@ -0,0 +1,19 @@
$input a_position, a_texcoord0
$output v_dir
/*
* Copyright 2014 Dario Manesku. All rights reserved.
* License: http://www.opensource.org/licenses/BSD-2-Clause
*/
#include "../common/common.sh"
uniform mat4 u_mtx;
void main()
{
gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) );
vec2 tex = 2.0 * a_texcoord0 - 1.0;
v_dir = mul(u_mtx, vec4(tex, 1.0, 0.0) ).xyz;
}

View file

@ -197,7 +197,7 @@ namespace entry
const MouseEvent* mouse = static_cast<const MouseEvent*>(ev);
//TODO: move this from here.
cameraSetMouseState(mouse->m_mx, mouse->m_my, mouse->m_down, mouse->m_move);
cameraSetMouseState(mouse->m_mx, mouse->m_my, mouse->m_down && MouseButton::Right == mouse->m_button, mouse->m_move);
if (mouse->m_move)
{

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.

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.

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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -165,6 +165,7 @@ exampleProject("14-shadowvolumes", "d7eb4bcc-37bc-11e3-b7a4-e46428d43830")
exampleProject("15-shadowmaps-simple", "a10f22ab-e0ee-471a-b2b6-2f6cb1c63fdc")
exampleProject("16-shadowmaps", "f9a91cb0-7b1b-11e3-981f-0800200c9a66")
exampleProject("17-drawstress", "9aeea4c6-80dc-11e3-b3ca-4da6db0f677b")
exampleProject("18-ibl", "711bcbb0-9531-11e3-a5e2-0800200c9a66")
dofile "makedisttex.lua"
dofile "shaderc.lua"