void calcAabb(Aabb& _aabb, const float* _mtx, const void* _vertices, uint32_t _numVertices, uint32_t _stride) { float min[3], max[3]; uint8_t* vertex = (uint8_t*)_vertices; float position[3]; vec3MulMtx(position, (float*)vertex, _mtx); min[0] = max[0] = position[0]; min[1] = max[1] = position[1]; min[2] = max[2] = position[2]; vertex += _stride; for (uint32_t ii = 1; ii < _numVertices; ++ii) { vec3MulMtx(position, (float*)vertex, _mtx); vertex += _stride; float xx = position[0]; float yy = position[1]; float zz = position[2]; min[0] = fmin(xx, min[0]); min[1] = fmin(yy, min[1]); min[2] = fmin(zz, min[2]); max[0] = fmax(xx, max[0]); max[1] = fmax(yy, max[1]); max[2] = fmax(zz, max[2]); } _aabb.m_min[0] = min[0]; _aabb.m_min[1] = min[1]; _aabb.m_min[2] = min[2]; _aabb.m_max[0] = max[0]; _aabb.m_max[1] = max[1]; _aabb.m_max[2] = max[2]; }
int _main_(int /*_argc*/, char** /*_argv*/) { PosColorTexCoord0Vertex::init(); 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 view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT , 0x303030ff , 1.0f , 0 ); bgfx::TextureHandle uffizi = loadTexture("uffizi.dds", BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_W_CLAMP); bgfx::ProgramHandle skyProgram = loadProgram("vs_hdr_skybox", "fs_hdr_skybox"); bgfx::ProgramHandle lumProgram = loadProgram("vs_hdr_lum", "fs_hdr_lum"); bgfx::ProgramHandle lumAvgProgram = loadProgram("vs_hdr_lumavg", "fs_hdr_lumavg"); bgfx::ProgramHandle blurProgram = loadProgram("vs_hdr_blur", "fs_hdr_blur"); bgfx::ProgramHandle brightProgram = loadProgram("vs_hdr_bright", "fs_hdr_bright"); bgfx::ProgramHandle meshProgram = loadProgram("vs_hdr_mesh", "fs_hdr_mesh"); bgfx::ProgramHandle tonemapProgram = loadProgram("vs_hdr_tonemap", "fs_hdr_tonemap"); bgfx::UniformHandle u_time = bgfx::createUniform("u_time", bgfx::UniformType::Uniform1f); bgfx::UniformHandle u_texCube = bgfx::createUniform("u_texCube", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_texColor = bgfx::createUniform("u_texColor", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_texLum = bgfx::createUniform("u_texLum", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_texBlur = bgfx::createUniform("u_texBlur", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Uniform4x4fv); bgfx::UniformHandle u_tonemap = bgfx::createUniform("u_tonemap", bgfx::UniformType::Uniform4fv); bgfx::UniformHandle u_offset = bgfx::createUniform("u_offset", bgfx::UniformType::Uniform4fv, 16); Mesh* mesh = meshLoad("meshes/bunny.bin"); bgfx::FrameBufferHandle fbh; bgfx::TextureHandle fbtextures[] = { bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT|BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP), bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_BUFFER_ONLY), }; fbh = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true); bgfx::FrameBufferHandle lum[5]; lum[0] = bgfx::createFrameBuffer(128, 128, bgfx::TextureFormat::BGRA8); lum[1] = bgfx::createFrameBuffer( 64, 64, bgfx::TextureFormat::BGRA8); lum[2] = bgfx::createFrameBuffer( 16, 16, bgfx::TextureFormat::BGRA8); lum[3] = bgfx::createFrameBuffer( 4, 4, bgfx::TextureFormat::BGRA8); lum[4] = bgfx::createFrameBuffer( 1, 1, bgfx::TextureFormat::BGRA8); bgfx::FrameBufferHandle bright; bright = bgfx::createFrameBuffer(width/2, height/2, bgfx::TextureFormat::BGRA8); bgfx::FrameBufferHandle blur; blur = bgfx::createFrameBuffer(width/8, height/8, bgfx::TextureFormat::BGRA8); void* data = load("font/droidsans.ttf"); imguiCreate(data); free(data); float speed = 0.37f; float middleGray = 0.18f; float white = 1.1f; float treshold = 1.5f; int32_t scrollArea = 0; uint32_t oldWidth = 0; uint32_t oldHeight = 0; uint32_t oldReset = reset; entry::MouseState mouseState; float time = 0.0f; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { if (oldWidth != width || oldHeight != height || oldReset != reset) { // Recreate variable size render targets when resolution changes. oldWidth = width; oldHeight = height; oldReset = reset; uint32_t msaa = (reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT; bgfx::destroyFrameBuffer(fbh); bgfx::destroyFrameBuffer(bright); bgfx::destroyFrameBuffer(blur); fbtextures[0] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::BGRA8, ( (msaa+1)<<BGFX_TEXTURE_RT_MSAA_SHIFT)|BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP); fbtextures[1] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_BUFFER_ONLY|( (msaa+1)<<BGFX_TEXTURE_RT_MSAA_SHIFT) ); fbh = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true); bright = bgfx::createFrameBuffer(width/2, height/2, bgfx::TextureFormat::BGRA8); blur = bgfx::createFrameBuffer(width/8, height/8, bgfx::TextureFormat::BGRA8); } 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 ); imguiBeginScrollArea("Settings", width - width / 5 - 10, 10, width / 5, height / 3, &scrollArea); imguiSeparatorLine(); imguiSlider("Speed", &speed, 0.0f, 1.0f, 0.01f); imguiSeparator(); imguiSlider("Middle gray", &middleGray, 0.1f, 1.0f, 0.01f); imguiSlider("White point", &white, 0.1f, 2.0f, 0.01f); imguiSlider("Treshold", &treshold, 0.1f, 2.0f, 0.01f); imguiEndScrollArea(); imguiEndFrame(); // 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::submit(0); 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*speed/freq); bgfx::setUniform(u_time, &time); // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/09-hdr"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Using multiple views and render targets."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); // Set views. bgfx::setViewRectMask(0x1f, 0, 0, width, height); bgfx::setViewFrameBufferMask(0x3, fbh); bgfx::setViewRect(2, 0, 0, 128, 128); bgfx::setViewFrameBuffer(2, lum[0]); bgfx::setViewRect(3, 0, 0, 64, 64); bgfx::setViewFrameBuffer(3, lum[1]); bgfx::setViewRect(4, 0, 0, 16, 16); bgfx::setViewFrameBuffer(4, lum[2]); bgfx::setViewRect(5, 0, 0, 4, 4); bgfx::setViewFrameBuffer(5, lum[3]); bgfx::setViewRect(6, 0, 0, 1, 1); bgfx::setViewFrameBuffer(6, lum[4]); bgfx::setViewRect(7, 0, 0, width/2, height/2); bgfx::setViewFrameBuffer(7, bright); bgfx::setViewRect(8, 0, 0, width/8, height/8); bgfx::setViewFrameBuffer(8, blur); bgfx::setViewRect(9, 0, 0, width, height); float view[16]; float proj[16]; mtxIdentity(view); mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); // Set view and projection matrix for view 0. bgfx::setViewTransformMask(0 |(1<<0) |(1<<2) |(1<<3) |(1<<4) |(1<<5) |(1<<6) |(1<<7) |(1<<8) |(1<<9) , view , proj ); float at[3] = { 0.0f, 1.0f, 0.0f }; float eye[3] = { 0.0f, 1.0f, -2.5f }; float mtx[16]; mtxRotateXY(mtx , 0.0f , time ); float temp[4]; vec3MulMtx(temp, eye, mtx); mtxLookAt(view, temp, at); mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); // Set view and projection matrix for view 1. bgfx::setViewTransformMask(1<<1, view, proj); bgfx::setUniform(u_mtx, mtx); // Render skybox into view 0. bgfx::setTexture(0, u_texCube, uffizi); bgfx::setProgram(skyProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width, (float)height, true); bgfx::submit(0); // Render mesh into view 1 bgfx::setTexture(0, u_texCube, uffizi); meshSubmit(mesh, 1, meshProgram, NULL); // Calculate luminance. setOffsets2x2Lum(u_offset, 128, 128); bgfx::setTexture(0, u_texColor, fbtextures[0]); bgfx::setProgram(lumProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(128.0f, 128.0f, s_flipV); bgfx::submit(2); // Downscale luminance 0. setOffsets4x4Lum(u_offset, 128, 128); bgfx::setTexture(0, u_texColor, lum[0]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(64.0f, 64.0f, s_flipV); bgfx::submit(3); // Downscale luminance 1. setOffsets4x4Lum(u_offset, 64, 64); bgfx::setTexture(0, u_texColor, lum[1]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(16.0f, 16.0f, s_flipV); bgfx::submit(4); // Downscale luminance 2. setOffsets4x4Lum(u_offset, 16, 16); bgfx::setTexture(0, u_texColor, lum[2]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(4.0f, 4.0f, s_flipV); bgfx::submit(5); // Downscale luminance 3. setOffsets4x4Lum(u_offset, 4, 4); bgfx::setTexture(0, u_texColor, lum[3]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(1.0f, 1.0f, s_flipV); bgfx::submit(6); float tonemap[4] = { middleGray, square(white), treshold, 0.0f }; bgfx::setUniform(u_tonemap, tonemap); // Bright pass treshold is tonemap[3]. setOffsets4x4Lum(u_offset, width/2, height/2); bgfx::setTexture(0, u_texColor, fbtextures[0]); bgfx::setTexture(1, u_texLum, lum[4]); bgfx::setProgram(brightProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width/2.0f, (float)height/2.0f, s_flipV); bgfx::submit(7); // Blur bright pass vertically. bgfx::setTexture(0, u_texColor, bright); bgfx::setProgram(blurProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width/8.0f, (float)height/8.0f, s_flipV); bgfx::submit(8); // Blur bright pass horizontally, do tonemaping and combine. bgfx::setTexture(0, u_texColor, fbtextures[0]); bgfx::setTexture(1, u_texLum, lum[4]); bgfx::setTexture(2, u_texBlur, blur); bgfx::setProgram(tonemapProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width, (float)height, s_flipV); bgfx::submit(9); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); }
int _main_(int _argc, char** _argv) { PosColorTexCoord0Vertex::init(); uint32_t width = 1280; uint32_t height = 720; uint32_t debug = BGFX_DEBUG_TEXT; uint32_t reset = BGFX_RESET_NONE; bgfx::init(); bgfx::reset(width, height); // Enable debug text. bgfx::setDebug(debug); // Set view 0 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/"; s_texelHalf = 0.5f; 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; } const bgfx::Memory* mem; mem = loadTexture("uffizi.dds"); bgfx::TextureHandle uffizi = bgfx::createTexture(mem); bgfx::UniformHandle u_time = bgfx::createUniform("u_time", bgfx::UniformType::Uniform1f); bgfx::UniformHandle u_texCube = bgfx::createUniform("u_texCube", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_texColor = bgfx::createUniform("u_texColor", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_texLum = bgfx::createUniform("u_texLum", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_texBlur = bgfx::createUniform("u_texBlur", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Uniform4x4fv); bgfx::UniformHandle u_tonemap = bgfx::createUniform("u_tonemap", bgfx::UniformType::Uniform4fv); bgfx::UniformHandle u_offset = bgfx::createUniform("u_offset", bgfx::UniformType::Uniform4fv, 16); bgfx::UniformHandle u_weight = bgfx::createUniform("u_weight", bgfx::UniformType::Uniform4fv, 16); bgfx::ProgramHandle skyProgram = loadProgram("vs_hdr_skybox", "fs_hdr_skybox"); bgfx::ProgramHandle lumProgram = loadProgram("vs_hdr_lum", "fs_hdr_lum"); bgfx::ProgramHandle lumAvgProgram = loadProgram("vs_hdr_lumavg", "fs_hdr_lumavg"); bgfx::ProgramHandle blurProgram = loadProgram("vs_hdr_blur", "fs_hdr_blur"); bgfx::ProgramHandle brightProgram = loadProgram("vs_hdr_bright", "fs_hdr_bright"); bgfx::ProgramHandle meshProgram = loadProgram("vs_hdr_mesh", "fs_hdr_mesh"); bgfx::ProgramHandle tonemapProgram = loadProgram("vs_hdr_tonemap", "fs_hdr_tonemap"); Mesh mesh; mesh.load("meshes/bunny.bin"); bgfx::RenderTargetHandle rt = bgfx::createRenderTarget(width, height, BGFX_RENDER_TARGET_COLOR_RGBA|BGFX_RENDER_TARGET_DEPTH|BGFX_RENDER_TARGET_MSAA_X8); bgfx::RenderTargetHandle lum[5]; lum[0] = bgfx::createRenderTarget(128, 128, BGFX_RENDER_TARGET_COLOR_RGBA); lum[1] = bgfx::createRenderTarget( 64, 64, BGFX_RENDER_TARGET_COLOR_RGBA); lum[2] = bgfx::createRenderTarget( 16, 16, BGFX_RENDER_TARGET_COLOR_RGBA); lum[3] = bgfx::createRenderTarget( 4, 4, BGFX_RENDER_TARGET_COLOR_RGBA); lum[4] = bgfx::createRenderTarget( 1, 1, BGFX_RENDER_TARGET_COLOR_RGBA); bgfx::RenderTargetHandle bright; bright = bgfx::createRenderTarget(width/2, height/2, BGFX_RENDER_TARGET_COLOR_RGBA); bgfx::RenderTargetHandle blur; blur = bgfx::createRenderTarget(width/8, height/8, BGFX_RENDER_TARGET_COLOR_RGBA); uint32_t oldWidth = 0; uint32_t oldHeight = 0; while (!processEvents(width, height, debug, reset) ) { if (oldWidth != width || oldHeight != height) { // Recreate variable size render targets when resolution changes. oldWidth = width; oldHeight = height; bgfx::destroyRenderTarget(rt); bgfx::destroyRenderTarget(bright); bgfx::destroyRenderTarget(blur); rt = bgfx::createRenderTarget(width, height, BGFX_RENDER_TARGET_COLOR_RGBA|BGFX_RENDER_TARGET_DEPTH|BGFX_RENDER_TARGET_MSAA_X8); bright = bgfx::createRenderTarget(width/2, height/2, BGFX_RENDER_TARGET_COLOR_RGBA); blur = bgfx::createRenderTarget(width/8, height/8, BGFX_RENDER_TARGET_COLOR_RGBA); } // 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::submit(0); 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; float time = (float)(now/freq); bgfx::setUniform(u_time, &time); // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/09-hdr"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Using multiple views and render targets."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); // Set views. bgfx::setViewRectMask(0x1f, 0, 0, width, height); bgfx::setViewRenderTargetMask(0x3, rt); bgfx::setViewRect(2, 0, 0, 128, 128); bgfx::setViewRenderTarget(2, lum[0]); bgfx::setViewRect(3, 0, 0, 64, 64); bgfx::setViewRenderTarget(3, lum[1]); bgfx::setViewRect(4, 0, 0, 16, 16); bgfx::setViewRenderTarget(4, lum[2]); bgfx::setViewRect(5, 0, 0, 4, 4); bgfx::setViewRenderTarget(5, lum[3]); bgfx::setViewRect(6, 0, 0, 1, 1); bgfx::setViewRenderTarget(6, lum[4]); bgfx::setViewRect(7, 0, 0, width/2, height/2); bgfx::setViewRenderTarget(7, bright); bgfx::setViewRect(8, 0, 0, width/8, height/8); bgfx::setViewRenderTarget(8, blur); bgfx::setViewRect(9, 0, 0, width, height); float view[16]; float proj[16]; mtxIdentity(view); mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); // Set view and projection matrix for view 0. bgfx::setViewTransformMask(0 |(1<<0) |(1<<2) |(1<<3) |(1<<4) |(1<<5) |(1<<6) |(1<<7) |(1<<8) |(1<<9) , view , proj ); float at[3] = { 0.0f, 1.0f, 0.0f }; float eye[3] = { 0.0f, 1.0f, -2.5f }; float mtx[16]; mtxRotateXY(mtx , 0.0f , time*0.37f ); float temp[4]; vec3MulMtx(temp, eye, mtx); mtxLookAt(view, temp, at); mtxProj(proj, 60.0f, 16.0f/9.0f, 0.1f, 100.0f); // Set view and projection matrix for view 1. bgfx::setViewTransformMask(1<<1, view, proj); bgfx::setUniform(u_mtx, mtx); // Render skybox into view 0. bgfx::setTexture(0, u_texCube, uffizi); bgfx::setProgram(skyProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width, (float)height, true); bgfx::submit(0); // Render mesh into view 1 bgfx::setTexture(0, u_texCube, uffizi); mesh.submit(1, meshProgram, NULL); // Calculate luminance. setOffsets2x2Lum(u_offset, 128, 128); bgfx::setTexture(0, u_texColor, rt); bgfx::setProgram(lumProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(128.0f, 128.0f, s_flipV); bgfx::submit(2); // Downscale luminance 0. setOffsets4x4Lum(u_offset, 128, 128); bgfx::setTexture(0, u_texColor, lum[0]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(64.0f, 64.0f, s_flipV); bgfx::submit(3); // Downscale luminance 1. setOffsets4x4Lum(u_offset, 64, 64); bgfx::setTexture(0, u_texColor, lum[1]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(16.0f, 16.0f, s_flipV); bgfx::submit(4); // Downscale luminance 2. setOffsets4x4Lum(u_offset, 16, 16); bgfx::setTexture(0, u_texColor, lum[2]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(4.0f, 4.0f, s_flipV); bgfx::submit(5); // Downscale luminance 3. setOffsets4x4Lum(u_offset, 4, 4); bgfx::setTexture(0, u_texColor, lum[3]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(1.0f, 1.0f, s_flipV); bgfx::submit(6); float tonemap[4] = { 0.18f, square(1.1f), 1.5f, 0.0f }; bgfx::setUniform(u_tonemap, tonemap); // Bright pass treshold is tonemap[3]. setOffsets4x4Lum(u_offset, width/2, height/2); bgfx::setTexture(0, u_texColor, rt); bgfx::setTexture(1, u_texLum, lum[4]); bgfx::setProgram(brightProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width/2.0f, (float)height/2.0f, s_flipV); bgfx::submit(7); // Blur bright pass vertically. bgfx::setTexture(0, u_texColor, bright); bgfx::setProgram(blurProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width/8.0f, (float)height/8.0f, s_flipV); bgfx::submit(8); // Blur bright pass horizontally, do tonemaping and combine. bgfx::setTexture(0, u_texColor, rt); bgfx::setTexture(1, u_texLum, lum[4]); bgfx::setTexture(2, u_texBlur, blur); bgfx::setProgram(tonemapProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width, (float)height, s_flipV); bgfx::submit(9); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } // Cleanup. mesh.unload(); bgfx::destroyRenderTarget(lum[0]); bgfx::destroyRenderTarget(lum[1]); bgfx::destroyRenderTarget(lum[2]); bgfx::destroyRenderTarget(lum[3]); bgfx::destroyRenderTarget(lum[4]); bgfx::destroyRenderTarget(bright); bgfx::destroyRenderTarget(blur); bgfx::destroyRenderTarget(rt); bgfx::destroyProgram(meshProgram); bgfx::destroyProgram(skyProgram); bgfx::destroyProgram(tonemapProgram); bgfx::destroyProgram(lumProgram); bgfx::destroyProgram(lumAvgProgram); bgfx::destroyProgram(blurProgram); bgfx::destroyProgram(brightProgram); bgfx::destroyTexture(uffizi); bgfx::destroyUniform(u_time); bgfx::destroyUniform(u_texCube); bgfx::destroyUniform(u_texColor); bgfx::destroyUniform(u_texLum); bgfx::destroyUniform(u_texBlur); bgfx::destroyUniform(u_mtx); bgfx::destroyUniform(u_tonemap); bgfx::destroyUniform(u_offset); bgfx::destroyUniform(u_weight); // Shutdown bgfx. bgfx::shutdown(); return 0; }
int _main_(int /*_argc*/, char** /*_argv*/) { PosColorTexCoord0Vertex::init(); 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 view 0 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/"; s_texelHalf = 0.5f; 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; } const bgfx::Memory* mem; mem = loadTexture("uffizi.dds"); bgfx::TextureHandle uffizi = bgfx::createTexture(mem, BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_W_CLAMP); bgfx::UniformHandle u_time = bgfx::createUniform("u_time", bgfx::UniformType::Uniform1f); bgfx::UniformHandle u_texCube = bgfx::createUniform("u_texCube", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_texColor = bgfx::createUniform("u_texColor", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_texLum = bgfx::createUniform("u_texLum", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_texBlur = bgfx::createUniform("u_texBlur", bgfx::UniformType::Uniform1i); bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Uniform4x4fv); bgfx::UniformHandle u_tonemap = bgfx::createUniform("u_tonemap", bgfx::UniformType::Uniform4fv); bgfx::UniformHandle u_offset = bgfx::createUniform("u_offset", bgfx::UniformType::Uniform4fv, 16); bgfx::UniformHandle u_weight = bgfx::createUniform("u_weight", bgfx::UniformType::Uniform4fv, 16); bgfx::ProgramHandle skyProgram = loadProgram("vs_hdr_skybox", "fs_hdr_skybox"); bgfx::ProgramHandle lumProgram = loadProgram("vs_hdr_lum", "fs_hdr_lum"); bgfx::ProgramHandle lumAvgProgram = loadProgram("vs_hdr_lumavg", "fs_hdr_lumavg"); bgfx::ProgramHandle blurProgram = loadProgram("vs_hdr_blur", "fs_hdr_blur"); bgfx::ProgramHandle brightProgram = loadProgram("vs_hdr_bright", "fs_hdr_bright"); bgfx::ProgramHandle meshProgram = loadProgram("vs_hdr_mesh", "fs_hdr_mesh"); bgfx::ProgramHandle tonemapProgram = loadProgram("vs_hdr_tonemap", "fs_hdr_tonemap"); Mesh mesh; mesh.load("meshes/bunny.bin"); bgfx::RenderTargetHandle rt = bgfx::createRenderTarget(width, height, BGFX_RENDER_TARGET_COLOR_RGBA8|BGFX_RENDER_TARGET_DEPTH); bgfx::RenderTargetHandle lum[5]; lum[0] = bgfx::createRenderTarget(128, 128, BGFX_RENDER_TARGET_COLOR_RGBA8); lum[1] = bgfx::createRenderTarget( 64, 64, BGFX_RENDER_TARGET_COLOR_RGBA8); lum[2] = bgfx::createRenderTarget( 16, 16, BGFX_RENDER_TARGET_COLOR_RGBA8); lum[3] = bgfx::createRenderTarget( 4, 4, BGFX_RENDER_TARGET_COLOR_RGBA8); lum[4] = bgfx::createRenderTarget( 1, 1, BGFX_RENDER_TARGET_COLOR_RGBA8); bgfx::RenderTargetHandle bright; bright = bgfx::createRenderTarget(width/2, height/2, BGFX_RENDER_TARGET_COLOR_RGBA8); bgfx::RenderTargetHandle blur; blur = bgfx::createRenderTarget(width/8, height/8, BGFX_RENDER_TARGET_COLOR_RGBA8); 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); free(data); float speed = 0.37f; float middleGray = 0.18f; float white = 1.1f; float treshold = 1.5f; int32_t scrollArea = 0; uint32_t oldWidth = 0; uint32_t oldHeight = 0; entry::MouseState mouseState; float time = 0.0f; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { if (oldWidth != width || oldHeight != height) { // Recreate variable size render targets when resolution changes. oldWidth = width; oldHeight = height; bgfx::destroyRenderTarget(rt); bgfx::destroyRenderTarget(bright); bgfx::destroyRenderTarget(blur); rt = bgfx::createRenderTarget(width, height, BGFX_RENDER_TARGET_COLOR_RGBA8|BGFX_RENDER_TARGET_DEPTH); bright = bgfx::createRenderTarget(width/2, height/2, BGFX_RENDER_TARGET_COLOR_RGBA8); blur = bgfx::createRenderTarget(width/8, height/8, BGFX_RENDER_TARGET_COLOR_RGBA8); } 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 ); imguiBeginScrollArea("Settings", width - width / 5 - 10, 10, width / 5, height / 3, &scrollArea); imguiSeparatorLine(); imguiSlider("Speed", &speed, 0.0f, 1.0f, 0.01f); imguiSeparator(); imguiSlider("Middle gray", &middleGray, 0.1f, 1.0f, 0.01f); imguiSlider("White point", &white, 0.1f, 2.0f, 0.01f); imguiSlider("Treshold", &treshold, 0.1f, 2.0f, 0.01f); imguiEndScrollArea(); imguiEndFrame(); // 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::submit(0); 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*speed/freq); bgfx::setUniform(u_time, &time); // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/09-hdr"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Using multiple views and render targets."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); // Set views. bgfx::setViewRectMask(0x1f, 0, 0, width, height); bgfx::setViewRenderTargetMask(0x3, rt); bgfx::setViewRect(2, 0, 0, 128, 128); bgfx::setViewRenderTarget(2, lum[0]); bgfx::setViewRect(3, 0, 0, 64, 64); bgfx::setViewRenderTarget(3, lum[1]); bgfx::setViewRect(4, 0, 0, 16, 16); bgfx::setViewRenderTarget(4, lum[2]); bgfx::setViewRect(5, 0, 0, 4, 4); bgfx::setViewRenderTarget(5, lum[3]); bgfx::setViewRect(6, 0, 0, 1, 1); bgfx::setViewRenderTarget(6, lum[4]); bgfx::setViewRect(7, 0, 0, width/2, height/2); bgfx::setViewRenderTarget(7, bright); bgfx::setViewRect(8, 0, 0, width/8, height/8); bgfx::setViewRenderTarget(8, blur); bgfx::setViewRect(9, 0, 0, width, height); float view[16]; float proj[16]; mtxIdentity(view); mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); // Set view and projection matrix for view 0. bgfx::setViewTransformMask(0 |(1<<0) |(1<<2) |(1<<3) |(1<<4) |(1<<5) |(1<<6) |(1<<7) |(1<<8) |(1<<9) , view , proj ); float at[3] = { 0.0f, 1.0f, 0.0f }; float eye[3] = { 0.0f, 1.0f, -2.5f }; float mtx[16]; mtxRotateXY(mtx , 0.0f , time ); float temp[4]; vec3MulMtx(temp, eye, mtx); mtxLookAt(view, temp, at); mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); // Set view and projection matrix for view 1. bgfx::setViewTransformMask(1<<1, view, proj); bgfx::setUniform(u_mtx, mtx); // Render skybox into view 0. bgfx::setTexture(0, u_texCube, uffizi); bgfx::setProgram(skyProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width, (float)height, true); bgfx::submit(0); // Render mesh into view 1 bgfx::setTexture(0, u_texCube, uffizi); mesh.submit(1, meshProgram, NULL); // Calculate luminance. setOffsets2x2Lum(u_offset, 128, 128); bgfx::setTexture(0, u_texColor, rt); bgfx::setProgram(lumProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(128.0f, 128.0f, s_flipV); bgfx::submit(2); // Downscale luminance 0. setOffsets4x4Lum(u_offset, 128, 128); bgfx::setTexture(0, u_texColor, lum[0]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(64.0f, 64.0f, s_flipV); bgfx::submit(3); // Downscale luminance 1. setOffsets4x4Lum(u_offset, 64, 64); bgfx::setTexture(0, u_texColor, lum[1]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(16.0f, 16.0f, s_flipV); bgfx::submit(4); // Downscale luminance 2. setOffsets4x4Lum(u_offset, 16, 16); bgfx::setTexture(0, u_texColor, lum[2]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(4.0f, 4.0f, s_flipV); bgfx::submit(5); // Downscale luminance 3. setOffsets4x4Lum(u_offset, 4, 4); bgfx::setTexture(0, u_texColor, lum[3]); bgfx::setProgram(lumAvgProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad(1.0f, 1.0f, s_flipV); bgfx::submit(6); float tonemap[4] = { middleGray, square(white), treshold, 0.0f }; bgfx::setUniform(u_tonemap, tonemap); // Bright pass treshold is tonemap[3]. setOffsets4x4Lum(u_offset, width/2, height/2); bgfx::setTexture(0, u_texColor, rt); bgfx::setTexture(1, u_texLum, lum[4]); bgfx::setProgram(brightProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width/2.0f, (float)height/2.0f, s_flipV); bgfx::submit(7); // Blur bright pass vertically. bgfx::setTexture(0, u_texColor, bright); bgfx::setProgram(blurProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width/8.0f, (float)height/8.0f, s_flipV); bgfx::submit(8); // Blur bright pass horizontally, do tonemaping and combine. bgfx::setTexture(0, u_texColor, rt); bgfx::setTexture(1, u_texLum, lum[4]); bgfx::setTexture(2, u_texBlur, blur); bgfx::setProgram(tonemapProgram); bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE); screenSpaceQuad( (float)width, (float)height, s_flipV); bgfx::submit(9); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } imguiDestroy(); // Cleanup. mesh.unload(); bgfx::destroyRenderTarget(lum[0]); bgfx::destroyRenderTarget(lum[1]); bgfx::destroyRenderTarget(lum[2]); bgfx::destroyRenderTarget(lum[3]); bgfx::destroyRenderTarget(lum[4]); bgfx::destroyRenderTarget(bright); bgfx::destroyRenderTarget(blur); bgfx::destroyRenderTarget(rt); bgfx::destroyProgram(meshProgram); bgfx::destroyProgram(skyProgram); bgfx::destroyProgram(tonemapProgram); bgfx::destroyProgram(lumProgram); bgfx::destroyProgram(lumAvgProgram); bgfx::destroyProgram(blurProgram); bgfx::destroyProgram(brightProgram); bgfx::destroyTexture(uffizi); bgfx::destroyUniform(u_time); bgfx::destroyUniform(u_texCube); bgfx::destroyUniform(u_texColor); bgfx::destroyUniform(u_texLum); bgfx::destroyUniform(u_texBlur); bgfx::destroyUniform(u_mtx); bgfx::destroyUniform(u_tonemap); bgfx::destroyUniform(u_offset); bgfx::destroyUniform(u_weight); // Shutdown bgfx. bgfx::shutdown(); return 0; }