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_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/"; 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; } // Create vertex stream declaration. s_PosColorTexCoord0Decl.begin(); s_PosColorTexCoord0Decl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float); s_PosColorTexCoord0Decl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true); s_PosColorTexCoord0Decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float); s_PosColorTexCoord0Decl.end(); 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_lightDir = bgfx::createUniform("u_lightDir", bgfx::UniformType::Uniform3fv); bgfx::ProgramHandle raymarching = loadProgram("vs_raymarching", "fs_raymarching"); while (!processEvents(width, height, debug, reset) ) { // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, height); // Set view 1 default viewport. bgfx::setViewRect(1, 0, 0, width, height); // This dummy draw call is here to make sure that view 0 is cleared // if no other draw calls are submitted to viewZ 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; // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/03-raymarch"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Updating shader uniforms."); 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, -15.0f }; float view[16]; float proj[16]; mtxLookAt(view, eye, at); mtxProj(proj, 60.0f, 16.0f/9.0f, 0.1f, 100.0f); // Set view and projection matrix for view 1. bgfx::setViewTransform(0, view, proj); float ortho[16]; mtxOrtho(ortho, 0.0f, 1280.0f, 720.0f, 0.0f, 0.0f, 100.0f); // Set view and projection matrix for view 0. bgfx::setViewTransform(1, NULL, ortho); float time = (float)(bx::getHPCounter()/double(bx::getHPFrequency() ) ); float vp[16]; mtxMul(vp, view, proj); float mtx[16]; mtxRotateXY(mtx , time , time*0.37f ); float mtxInv[16]; mtxInverse(mtxInv, mtx); float lightDirModel[4] = { -0.4f, -0.5f, -1.0f, 0.0f }; float lightDirModelN[4]; vec3Norm(lightDirModelN, lightDirModel); float lightDir[4]; vec4MulMtx(lightDir, lightDirModelN, mtxInv); bgfx::setUniform(u_lightDir, lightDir); float mvp[16]; mtxMul(mvp, mtx, vp); float invMvp[16]; mtxInverse(invMvp, mvp); bgfx::setUniform(u_mtx, invMvp); bgfx::setUniform(u_time, &time); renderScreenSpaceQuad(1, raymarching, 0.0f, 0.0f, 1280.0f, 720.0f); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } // Cleanup. bgfx::destroyProgram(raymarching); bgfx::destroyUniform(u_time); bgfx::destroyUniform(u_mtx); bgfx::destroyUniform(u_lightDir); // Shutdown bgfx. bgfx::shutdown(); return 0; }
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 clear color palette for index 0 bgfx::setClearColor(0, UINT32_C(0x00000000) ); // Set clear color palette for index 1 bgfx::setClearColor(1, UINT32_C(0x303030ff) ); // Set geometry pass view clear state. bgfx::setViewClear(RENDER_PASS_GEOMETRY_ID , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH , 1.0f , 0 , 1 ); // Set light pass view clear state. bgfx::setViewClear(RENDER_PASS_LIGHT_ID , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH , 1.0f , 0 , 0 ); // Create vertex stream declaration. PosNormalTangentTexcoordVertex::init(); PosTexCoord0Vertex::init(); DebugVertex::init(); calcTangents(s_cubeVertices , BX_COUNTOF(s_cubeVertices) , PosNormalTangentTexcoordVertex::ms_decl , s_cubeIndices , BX_COUNTOF(s_cubeIndices) ); // Create static vertex buffer. bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer( bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) ) , PosNormalTangentTexcoordVertex::ms_decl ); // Create static index buffer. bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) ) ); // Create texture sampler uniforms. bgfx::UniformHandle s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle s_texNormal = bgfx::createUniform("s_texNormal", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle s_albedo = bgfx::createUniform("s_albedo", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle s_normal = bgfx::createUniform("s_normal", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle s_depth = bgfx::createUniform("s_depth", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle s_light = bgfx::createUniform("s_light", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Uniform4x4fv); bgfx::UniformHandle u_lightPosRadius = bgfx::createUniform("u_lightPosRadius", bgfx::UniformType::Uniform4fv); bgfx::UniformHandle u_lightRgbInnerR = bgfx::createUniform("u_lightRgbInnerR", bgfx::UniformType::Uniform4fv); // Create program from shaders. bgfx::ProgramHandle geomProgram = loadProgram("vs_deferred_geom", "fs_deferred_geom"); bgfx::ProgramHandle lightProgram = loadProgram("vs_deferred_light", "fs_deferred_light"); bgfx::ProgramHandle combineProgram = loadProgram("vs_deferred_combine", "fs_deferred_combine"); bgfx::ProgramHandle debugProgram = loadProgram("vs_deferred_debug", "fs_deferred_debug"); bgfx::ProgramHandle lineProgram = loadProgram("vs_deferred_debug_line", "fs_deferred_debug_line"); // Load diffuse texture. bgfx::TextureHandle textureColor = loadTexture("fieldstone-rgba.dds"); // Load normal texture. bgfx::TextureHandle textureNormal = loadTexture("fieldstone-n.dds"); bgfx::TextureHandle gbufferTex[3] = { BGFX_INVALID_HANDLE, BGFX_INVALID_HANDLE, BGFX_INVALID_HANDLE }; bgfx::FrameBufferHandle gbuffer = BGFX_INVALID_HANDLE; bgfx::FrameBufferHandle lightBuffer = BGFX_INVALID_HANDLE; // Imgui. imguiCreate(); const int64_t timeOffset = bx::getHPCounter(); const bgfx::RendererType::Enum renderer = bgfx::getRendererType(); const float texelHalf = bgfx::RendererType::Direct3D9 == renderer ? 0.5f : 0.0f; s_originBottomLeft = bgfx::RendererType::OpenGL == renderer || bgfx::RendererType::OpenGLES == renderer; // Get renderer capabilities info. const bgfx::Caps* caps = bgfx::getCaps(); uint32_t oldWidth = 0; uint32_t oldHeight = 0; uint32_t oldReset = reset; int32_t scrollArea = 0; int32_t numLights = 512; float lightAnimationSpeed = 0.3f; bool animateMesh = true; bool showScissorRects = false; bool showGBuffer = true; float view[16]; float initialPos[3] = { 0.0f, 0.0f, -15.0f }; cameraCreate(); cameraSetPosition(initialPos); cameraSetVerticalAngle(0.0f); cameraGetViewMtx(view); entry::MouseState mouseState; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { 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; const float deltaTime = float(frameTime/freq); float time = (float)( (now-timeOffset)/freq); // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/21-deferred"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: MRT rendering and deferred shading."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); if (2 > caps->maxFBAttachments) { // When multiple render targets (MRT) is not supported by GPU, // implement alternative code path that doesn't use MRT. bool blink = uint32_t(time*3.0f)&1; bgfx::dbgTextPrintf(0, 5, blink ? 0x1f : 0x01, " MRT not supported by GPU. "); // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, 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::submit(0); } else { if (oldWidth != width || oldHeight != height || oldReset != reset || !bgfx::isValid(gbuffer) ) { // Recreate variable size render targets when resolution changes. oldWidth = width; oldHeight = height; oldReset = reset; if (bgfx::isValid(gbuffer) ) { bgfx::destroyFrameBuffer(gbuffer); } const uint32_t samplerFlags = 0 | BGFX_TEXTURE_RT | BGFX_TEXTURE_MIN_POINT | BGFX_TEXTURE_MAG_POINT | BGFX_TEXTURE_MIP_POINT | BGFX_TEXTURE_U_CLAMP | BGFX_TEXTURE_V_CLAMP ; gbufferTex[0] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::BGRA8, samplerFlags); gbufferTex[1] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::BGRA8, samplerFlags); gbufferTex[2] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::D24, samplerFlags); gbuffer = bgfx::createFrameBuffer(BX_COUNTOF(gbufferTex), gbufferTex, true); if (bgfx::isValid(lightBuffer) ) { bgfx::destroyFrameBuffer(lightBuffer); } lightBuffer = bgfx::createFrameBuffer(width, height, bgfx::TextureFormat::BGRA8, samplerFlags); } 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("Num lights", numLights, 1, 2048); if (imguiCheck("Show G-Buffer.", showGBuffer) ) { showGBuffer = !showGBuffer; } if (imguiCheck("Show light scissor.", showScissorRects) ) { showScissorRects = !showScissorRects; } if (imguiCheck("Animate mesh.", animateMesh) ) { animateMesh = !animateMesh; } imguiSlider("Lights animation speed", lightAnimationSpeed, 0.0f, 0.4f, 0.01f); imguiEndScrollArea(); imguiEndFrame(); // Update camera. cameraUpdate(deltaTime, mouseState); cameraGetViewMtx(view); // Setup views float vp[16]; float invMvp[16]; { bgfx::setViewRect(RENDER_PASS_GEOMETRY_ID, 0, 0, width, height); bgfx::setViewRect(RENDER_PASS_LIGHT_ID, 0, 0, width, height); bgfx::setViewRect(RENDER_PASS_COMBINE_ID, 0, 0, width, height); bgfx::setViewRect(RENDER_PASS_DEBUG_LIGHTS_ID, 0, 0, width, height); bgfx::setViewRect(RENDER_PASS_DEBUG_GBUFFER_ID, 0, 0, width, height); bgfx::setViewFrameBuffer(RENDER_PASS_LIGHT_ID, lightBuffer); float proj[16]; mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); bgfx::setViewFrameBuffer(RENDER_PASS_GEOMETRY_ID, gbuffer); bgfx::setViewTransform(RENDER_PASS_GEOMETRY_ID, view, proj); bx::mtxMul(vp, view, proj); bx::mtxInverse(invMvp, vp); bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); bgfx::setViewTransform(RENDER_PASS_LIGHT_ID, NULL, proj); bgfx::setViewTransform(RENDER_PASS_COMBINE_ID, NULL, proj); const float aspectRatio = float(height)/float(width); const float size = 10.0f; bx::mtxOrtho(proj, -size, size, size*aspectRatio, -size*aspectRatio, 0.0f, 1000.0f); bgfx::setViewTransform(RENDER_PASS_DEBUG_GBUFFER_ID, NULL, proj); bx::mtxOrtho(proj, 0.0f, (float)width, 0.0f, (float)height, 0.0f, 1000.0f); bgfx::setViewTransform(RENDER_PASS_DEBUG_LIGHTS_ID, NULL, proj); } const uint32_t dim = 11; const float offset = (float(dim-1) * 3.0f) * 0.5f; // Draw into geometry pass. for (uint32_t yy = 0; yy < dim; ++yy) { for (uint32_t xx = 0; xx < dim; ++xx) { float mtx[16]; if (animateMesh) { bx::mtxRotateXY(mtx, time*1.023f + xx*0.21f, time*0.03f + yy*0.37f); } else { bx::mtxIdentity(mtx); } mtx[12] = -offset + float(xx)*3.0f; mtx[13] = -offset + float(yy)*3.0f; mtx[14] = 0.0f; // Set transform for draw call. bgfx::setTransform(mtx); // Set vertex and fragment shaders. bgfx::setProgram(geomProgram); // Set vertex and index buffer. bgfx::setVertexBuffer(vbh); bgfx::setIndexBuffer(ibh); // Bind textures. bgfx::setTexture(0, s_texColor, textureColor); bgfx::setTexture(1, s_texNormal, textureNormal); // 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_MSAA ); // Submit primitive for rendering to view 0. bgfx::submit(RENDER_PASS_GEOMETRY_ID); } } // Draw lights into light buffer. for (int32_t light = 0; light < numLights; ++light) { Sphere lightPosRadius; float lightTime = time * lightAnimationSpeed * (sinf(light/float(numLights) * bx::piHalf ) * 0.5f + 0.5f); lightPosRadius.m_center[0] = sinf( ( (lightTime + light*0.47f) + bx::piHalf*1.37f ) )*offset; lightPosRadius.m_center[1] = cosf( ( (lightTime + light*0.69f) + bx::piHalf*1.49f ) )*offset; lightPosRadius.m_center[2] = sinf( ( (lightTime + light*0.37f) + bx::piHalf*1.57f ) )*2.0f; lightPosRadius.m_radius = 2.0f; Aabb aabb; sphereToAabb(aabb, lightPosRadius); float box[8][3] = { { aabb.m_min[0], aabb.m_min[1], aabb.m_min[2] }, { aabb.m_min[0], aabb.m_min[1], aabb.m_max[2] }, { aabb.m_min[0], aabb.m_max[1], aabb.m_min[2] }, { aabb.m_min[0], aabb.m_max[1], aabb.m_max[2] }, { aabb.m_max[0], aabb.m_min[1], aabb.m_min[2] }, { aabb.m_max[0], aabb.m_min[1], aabb.m_max[2] }, { aabb.m_max[0], aabb.m_max[1], aabb.m_min[2] }, { aabb.m_max[0], aabb.m_max[1], aabb.m_max[2] }, }; float xyz[3]; bx::vec3MulMtxH(xyz, box[0], vp); float minx = xyz[0]; float miny = xyz[1]; float maxx = xyz[0]; float maxy = xyz[1]; float maxz = xyz[2]; for (uint32_t ii = 1; ii < 8; ++ii) { bx::vec3MulMtxH(xyz, box[ii], vp); minx = bx::fmin(minx, xyz[0]); miny = bx::fmin(miny, xyz[1]); maxx = bx::fmax(maxx, xyz[0]); maxy = bx::fmax(maxy, xyz[1]); maxz = bx::fmax(maxz, xyz[2]); } // Cull light if it's fully behind camera. if (maxz >= 0.0f) { float x0 = bx::fclamp( (minx * 0.5f + 0.5f) * width, 0.0f, (float)width); float y0 = bx::fclamp( (miny * 0.5f + 0.5f) * height, 0.0f, (float)height); float x1 = bx::fclamp( (maxx * 0.5f + 0.5f) * width, 0.0f, (float)width); float y1 = bx::fclamp( (maxy * 0.5f + 0.5f) * height, 0.0f, (float)height); if (showScissorRects) { bgfx::TransientVertexBuffer tvb; bgfx::TransientIndexBuffer tib; if (bgfx::allocTransientBuffers(&tvb, DebugVertex::ms_decl, 4, &tib, 8) ) { uint32_t abgr = 0x8000ff00; DebugVertex* vertex = (DebugVertex*)tvb.data; vertex->m_x = x0; vertex->m_y = y0; vertex->m_z = 0.0f; vertex->m_abgr = abgr; ++vertex; vertex->m_x = x1; vertex->m_y = y0; vertex->m_z = 0.0f; vertex->m_abgr = abgr; ++vertex; vertex->m_x = x1; vertex->m_y = y1; vertex->m_z = 0.0f; vertex->m_abgr = abgr; ++vertex; vertex->m_x = x0; vertex->m_y = y1; vertex->m_z = 0.0f; vertex->m_abgr = abgr; uint16_t* indices = (uint16_t*)tib.data; *indices++ = 0; *indices++ = 1; *indices++ = 1; *indices++ = 2; *indices++ = 2; *indices++ = 3; *indices++ = 3; *indices++ = 0; bgfx::setProgram(lineProgram); bgfx::setVertexBuffer(&tvb); bgfx::setIndexBuffer(&tib); bgfx::setState(0 | BGFX_STATE_RGB_WRITE | BGFX_STATE_PT_LINES | BGFX_STATE_BLEND_ALPHA ); bgfx::submit(RENDER_PASS_DEBUG_LIGHTS_ID); } } uint8_t val = light&7; float lightRgbInnerR[4] = { val & 0x1 ? 1.0f : 0.25f, val & 0x2 ? 1.0f : 0.25f, val & 0x4 ? 1.0f : 0.25f, 0.8f, }; // Draw light. bgfx::setUniform(u_lightPosRadius, &lightPosRadius); bgfx::setUniform(u_lightRgbInnerR, lightRgbInnerR); bgfx::setUniform(u_mtx, invMvp); const uint16_t scissorHeight = uint16_t(y1-y0); bgfx::setScissor(uint16_t(x0), height-scissorHeight-uint16_t(y0), uint16_t(x1-x0), scissorHeight); bgfx::setTexture(0, s_normal, gbuffer, 1); bgfx::setTexture(1, s_depth, gbuffer, 2); bgfx::setProgram(lightProgram); bgfx::setState(0 | BGFX_STATE_RGB_WRITE | BGFX_STATE_ALPHA_WRITE | BGFX_STATE_BLEND_ADD ); screenSpaceQuad( (float)width, (float)height, texelHalf, s_originBottomLeft); bgfx::submit(RENDER_PASS_LIGHT_ID); } } // Combine color and light buffers. bgfx::setTexture(0, s_albedo, gbuffer, 0); bgfx::setTexture(1, s_light, lightBuffer, 0); bgfx::setProgram(combineProgram); bgfx::setState(0 | BGFX_STATE_RGB_WRITE | BGFX_STATE_ALPHA_WRITE ); screenSpaceQuad( (float)width, (float)height, texelHalf, s_originBottomLeft); bgfx::submit(RENDER_PASS_COMBINE_ID); if (showGBuffer) { const float aspectRatio = float(width)/float(height); // Draw debug GBuffer. for (uint32_t ii = 0; ii < BX_COUNTOF(gbufferTex); ++ii) { float mtx[16]; bx::mtxSRT(mtx , aspectRatio, 1.0f, 1.0f , 0.0f, 0.0f, 0.0f , -7.9f - BX_COUNTOF(gbufferTex)*0.1f*0.5f + ii*2.1f*aspectRatio, 4.0f, 0.0f ); bgfx::setTransform(mtx); bgfx::setProgram(debugProgram); bgfx::setVertexBuffer(vbh); bgfx::setIndexBuffer(ibh, 0, 6); bgfx::setTexture(0, s_texColor, gbufferTex[ii]); bgfx::setState(BGFX_STATE_RGB_WRITE); bgfx::submit(RENDER_PASS_DEBUG_GBUFFER_ID); } } } // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } // Cleanup. cameraDestroy(); imguiDestroy(); if (bgfx::isValid(gbuffer) ) { bgfx::destroyFrameBuffer(gbuffer); bgfx::destroyFrameBuffer(lightBuffer); } bgfx::destroyIndexBuffer(ibh); bgfx::destroyVertexBuffer(vbh); bgfx::destroyProgram(geomProgram); bgfx::destroyProgram(lightProgram); bgfx::destroyProgram(combineProgram); bgfx::destroyProgram(debugProgram); bgfx::destroyProgram(lineProgram); bgfx::destroyTexture(textureColor); bgfx::destroyTexture(textureNormal); bgfx::destroyUniform(s_texColor); bgfx::destroyUniform(s_texNormal); bgfx::destroyUniform(s_albedo); bgfx::destroyUniform(s_normal); bgfx::destroyUniform(s_depth); bgfx::destroyUniform(s_light); bgfx::destroyUniform(u_lightPosRadius); bgfx::destroyUniform(u_lightRgbInnerR); bgfx::destroyUniform(u_mtx); // Shutdown bgfx. bgfx::shutdown(); return 0; }
int _main_(int _argc, char** _argv) { Args args(_argc, _argv); uint32_t width = 1280; uint32_t height = 720; uint32_t debug = BGFX_DEBUG_TEXT; uint32_t reset = BGFX_RESET_VSYNC; bgfx::init(args.m_type, args.m_pciId); bgfx::reset(width, height, reset); // Enable debug text. bgfx::setDebug(debug); // Set view 0 clear state. bgfx::setViewClear(0 , BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH , 0x303030ff , 1.0f , 0 ); // Setup root path for binary shaders. Shader binaries are different // for each renderer. switch (bgfx::getRendererType() ) { default: break; case bgfx::RendererType::OpenGL: case bgfx::RendererType::OpenGLES: s_oglNdc = true; break; } // Create vertex stream declaration. PosColorTexCoord0Vertex::init(); bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Mat4); bgfx::UniformHandle u_lightDirTime = bgfx::createUniform("u_lightDirTime", bgfx::UniformType::Vec4); // Create program from shaders. bgfx::ProgramHandle raymarching = loadProgram("vs_raymarching", "fs_raymarching"); int64_t timeOffset = bx::getHPCounter(); while (!entry::processEvents(width, height, debug, reset) ) { // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, height); // Set view 1 default viewport. bgfx::setViewRect(1, 0, 0, width, height); // This dummy draw call is here to make sure that view 0 is cleared // if no other draw calls are submitted to viewZ 0. bgfx::touch(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; // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/03-raymarch"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Updating shader uniforms."); 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, -15.0f }; float view[16]; float proj[16]; bx::mtxLookAt(view, eye, at); mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); // Set view and projection matrix for view 1. bgfx::setViewTransform(0, view, proj); float ortho[16]; bx::mtxOrtho(ortho, 0.0f, 1280.0f, 720.0f, 0.0f, 0.0f, 100.0f); // Set view and projection matrix for view 0. bgfx::setViewTransform(1, NULL, ortho); float time = (float)( (bx::getHPCounter()-timeOffset)/double(bx::getHPFrequency() ) ); float vp[16]; bx::mtxMul(vp, view, proj); float mtx[16]; bx::mtxRotateXY(mtx , time , time*0.37f ); float mtxInv[16]; bx::mtxInverse(mtxInv, mtx); float lightDirModel[4] = { -0.4f, -0.5f, -1.0f, 0.0f }; float lightDirModelN[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; bx::vec3Norm(lightDirModelN, lightDirModel); float lightDirTime[4]; bx::vec4MulMtx(lightDirTime, lightDirModelN, mtxInv); lightDirTime[3] = time; bgfx::setUniform(u_lightDirTime, lightDirTime); float mvp[16]; bx::mtxMul(mvp, mtx, vp); float invMvp[16]; bx::mtxInverse(invMvp, mvp); bgfx::setUniform(u_mtx, invMvp); renderScreenSpaceQuad(1, raymarching, 0.0f, 0.0f, 1280.0f, 720.0f); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } // Cleanup. bgfx::destroyProgram(raymarching); bgfx::destroyUniform(u_mtx); bgfx::destroyUniform(u_lightDirTime); // 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 ); 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) { 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/"; break; case bgfx::RendererType::Direct3D11: s_shaderPath = "shaders/dx11/"; break; case bgfx::RendererType::OpenGL: s_shaderPath = "shaders/glsl/"; break; case bgfx::RendererType::OpenGLES2: case bgfx::RendererType::OpenGLES3: s_shaderPath = "shaders/gles/"; break; } // Create vertex stream declaration. s_PosNormalTangentTexcoordDecl.begin(); s_PosNormalTangentTexcoordDecl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float); s_PosNormalTangentTexcoordDecl.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true); s_PosNormalTangentTexcoordDecl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Uint8, true, true); s_PosNormalTangentTexcoordDecl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Int16, true, true); s_PosNormalTangentTexcoordDecl.end(); const bgfx::Memory* mem; calcTangents(s_cubeVertices, countof(s_cubeVertices), s_PosNormalTangentTexcoordDecl, s_cubeIndices, countof(s_cubeIndices) ); // Create static vertex buffer. mem = bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) ); bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer(mem, s_PosNormalTangentTexcoordDecl); // Create static index buffer. mem = bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) ); bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(mem); // Create texture sampler uniforms. bgfx::UniformHandle u_texColor = bgfx::createUniform("u_texColor", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle u_texNormal = bgfx::createUniform("u_texNormal", bgfx::UniformType::Uniform1iv); uint16_t numLights = 4; bgfx::UniformHandle u_lightPosRadius = bgfx::createUniform("u_lightPosRadius", bgfx::UniformType::Uniform4fv, numLights); bgfx::UniformHandle u_lightRgbInnerR = bgfx::createUniform("u_lightRgbInnerR", bgfx::UniformType::Uniform4fv, numLights); // Load vertex shader. mem = loadShader("vs_bump"); bgfx::VertexShaderHandle vsh = bgfx::createVertexShader(mem); // Load fragment shader. mem = loadShader("fs_bump"); bgfx::FragmentShaderHandle fsh = bgfx::createFragmentShader(mem); // Create program from shaders. bgfx::ProgramHandle program = bgfx::createProgram(vsh, fsh); // We can destroy vertex and fragment shader here since // their reference is kept inside bgfx after calling createProgram. // Vertex and fragment shader will be destroyed once program is^ // destroyed. bgfx::destroyVertexShader(vsh); bgfx::destroyFragmentShader(fsh); // Load diffuse texture. mem = loadTexture("fieldstone-rgba.dds"); bgfx::TextureHandle textureColor = bgfx::createTexture(mem); // Load normal texture. mem = loadTexture("fieldstone-n.dds"); bgfx::TextureHandle textureNormal = bgfx::createTexture(mem); while (!processEvents(width, height, debug, reset) ) { // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, 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::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); // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/06-bump"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Loading textures."); 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, -7.0f }; float view[16]; float proj[16]; mtxLookAt(view, eye, at); mtxProj(proj, 60.0f, 16.0f/9.0f, 0.1f, 100.0f); float lightPosRadius[4][4]; for (uint32_t ii = 0; ii < numLights; ++ii) { lightPosRadius[ii][0] = sin( (time*(0.1f + ii*0.17f) + float(ii*M_PI_2)*1.37f ) )*3.0f; lightPosRadius[ii][1] = cos( (time*(0.2f + ii*0.29f) + float(ii*M_PI_2)*1.49f ) )*3.0f; lightPosRadius[ii][2] = -2.5f; lightPosRadius[ii][3] = 3.0f; } bgfx::setUniform(u_lightPosRadius, lightPosRadius, numLights); float lightRgbInnerR[4][4] = { { 1.0f, 0.7f, 0.2f, 0.8f }, { 0.7f, 0.2f, 1.0f, 0.8f }, { 0.2f, 1.0f, 0.7f, 0.8f }, { 1.0f, 0.4f, 0.2f, 0.8f }, }; bgfx::setUniform(u_lightRgbInnerR, lightRgbInnerR, numLights); // Set view and projection matrix for view 0. bgfx::setViewTransform(0, view, proj); const uint16_t instanceStride = 64; const bgfx::InstanceDataBuffer* idb = bgfx::allocInstanceDataBuffer(9, instanceStride); if (NULL != idb) { uint8_t* data = idb->data; // Write instance data for 3x3 cubes. for (uint32_t yy = 0; yy < 3; ++yy) { for (uint32_t xx = 0; xx < 3; ++xx) { float* mtx = (float*)data; mtxRotateXY(mtx, time*0.023f + xx*0.21f, time*0.03f + yy*0.37f); mtx[12] = -3.0f + float(xx)*3.0f; mtx[13] = -3.0f + float(yy)*3.0f; mtx[14] = 0.0f; float* color = (float*)&data[64]; color[0] = sin(time+float(xx)/11.0f)*0.5f+0.5f; color[1] = cos(time+float(yy)/11.0f)*0.5f+0.5f; color[2] = sin(time*3.0f)*0.5f+0.5f; color[3] = 1.0f; data += instanceStride; } } uint16_t numInstances = (uint16_t)( (data - idb->data)/instanceStride); // Set vertex and fragment shaders. bgfx::setProgram(program); // Set vertex and index buffer. bgfx::setVertexBuffer(vbh); bgfx::setIndexBuffer(ibh); // Set instance data buffer. bgfx::setInstanceDataBuffer(idb, numInstances); // Bind textures. bgfx::setTexture(0, u_texColor, textureColor); bgfx::setTexture(1, u_texNormal, textureNormal); // 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_MSAA ); // Submit primitive for rendering to view 0. bgfx::submit(0); } // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } // Cleanup. bgfx::destroyIndexBuffer(ibh); bgfx::destroyVertexBuffer(vbh); bgfx::destroyProgram(program); bgfx::destroyTexture(textureColor); bgfx::destroyTexture(textureNormal); bgfx::destroyUniform(u_texColor); bgfx::destroyUniform(u_texNormal); bgfx::destroyUniform(u_lightPosRadius); bgfx::destroyUniform(u_lightRgbInnerR); // Shutdown bgfx. bgfx::shutdown(); return 0; }
int _main_(int /*_argc*/, char** /*_argv*/) { // Create vertex stream declaration. PosColorVertex::init(); 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); // Get renderer capabilities info. const bgfx::Caps* caps = bgfx::getCaps(); // Setup root path for binary shaders. Shader binaries are different // for each renderer. switch (caps->rendererType) { 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::OpenGLES: 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); const bgfx::Memory* mem; // Create static vertex buffer. mem = bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) ); bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer(mem, PosColorVertex::ms_decl); // Create static index buffer. mem = bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) ); bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(mem); // Create texture sampler uniforms. bgfx::UniformHandle u_texColor0 = bgfx::createUniform("u_texColor0", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle u_texColor1 = bgfx::createUniform("u_texColor1", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle u_color = bgfx::createUniform("u_color", bgfx::UniformType::Uniform4fv); bgfx::ProgramHandle blend = loadProgram("vs_oit", "fs_oit" ); bgfx::ProgramHandle wbSeparatePass = loadProgram("vs_oit", "fs_oit_wb_separate" ); bgfx::ProgramHandle wbSeparateBlit = loadProgram("vs_oit_blit", "fs_oit_wb_separate_blit" ); bgfx::ProgramHandle wbPass = loadProgram("vs_oit", "fs_oit_wb" ); bgfx::ProgramHandle wbBlit = loadProgram("vs_oit_blit", "fs_oit_wb_blit" ); bgfx::TextureHandle fbtextures[2] = { BGFX_INVALID_HANDLE, BGFX_INVALID_HANDLE }; bgfx::FrameBufferHandle fbh = BGFX_INVALID_HANDLE; int64_t timeOffset = bx::getHPCounter(); uint32_t mode = 1; int32_t scrollArea = 0; bool frontToBack = true; bool fadeInOut = false; uint32_t oldWidth = 0; uint32_t oldHeight = 0; uint32_t oldReset = reset; entry::MouseState mouseState; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { if (oldWidth != width || oldHeight != height || oldReset != reset || !bgfx::isValid(fbh) ) { // Recreate variable size render targets when resolution changes. oldWidth = width; oldHeight = height; oldReset = reset; if (bgfx::isValid(fbh) ) { bgfx::destroyFrameBuffer(fbh); } fbtextures[0] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::RGBA16F, BGFX_TEXTURE_RT), fbtextures[1] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::R16F, BGFX_TEXTURE_RT), fbh = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true); } 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 / 4 - 10, 10, width / 4, height / 3, &scrollArea); imguiSeparatorLine(); imguiLabel("Blend mode:"); mode = imguiChoose(mode , "None" , "Separate" , "MRT Independent" ); imguiSeparatorLine(); if (imguiCheck("Front to back", frontToBack) ) { frontToBack ^= true; } if (imguiCheck("Fade in/out", fadeInOut) ) { fadeInOut ^= true; } imguiEndScrollArea(); imguiEndFrame(); // Set view 0 default viewport. bgfx::setViewRectMask(0x3, 0, 0, width, height); 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-timeOffset)/freq); // Use debug font to print information about this example. bgfx::dbgTextClear(); // Reference: // Weighted, Blended Order-Independent Transparency // http://jcgt.org/published/0002/02/09/ // http://casual-effects.blogspot.com/2014/03/weighted-blended-order-independent.html bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/19-oit"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Weighted, Blended Order Independent Transparency."); 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, -7.0f }; float view[16]; float proj[16]; // Set view and projection matrix for view 0. mtxLookAt(view, eye, at); mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); bgfx::setViewTransform(0, view, proj); bgfx::setViewClearMask(0x3 , BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT , 0x00000000 , 1.0f , 0 ); bgfx::FrameBufferHandle invalid = BGFX_INVALID_HANDLE; bgfx::setViewFrameBuffer(0, 0 == mode ? invalid : fbh); // Set view and projection matrix for view 1. mtxIdentity(view); mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); bgfx::setViewTransform(1, view, proj); for (uint32_t depth = 0; depth < 3; ++depth) { uint32_t zz = frontToBack ? 2-depth : depth; for (uint32_t yy = 0; yy < 3; ++yy) { for (uint32_t xx = 0; xx < 3; ++xx) { float color[4] = { xx*1.0f/3.0f, zz*1.0f/3.0f, yy*1.0f/3.0f, 0.5f }; if (fadeInOut && zz == 1) { color[3] = sinf(time*3.0f)*0.49f+0.5f; } bgfx::setUniform(u_color, color); BX_UNUSED(time); float mtx[16]; mtxRotateXY(mtx, time*0.023f + xx*0.21f, time*0.03f + yy*0.37f); //mtxIdentity(mtx); mtx[12] = -2.5f + float(xx)*2.5f; mtx[13] = -2.5f + float(yy)*2.5f; mtx[14] = -2.5f + float(zz)*2.5f; //0.0f; // sinf(time + ( (xx+1)*(yy+1)/9.0f)*float(M_PI) )*50.0f+50.0f; //90.0f - (xx+1)*(yy+1)*10.0f; // Set transform for draw call. bgfx::setTransform(mtx); // Set vertex and index buffer. bgfx::setVertexBuffer(vbh); bgfx::setIndexBuffer(ibh); const uint64_t state = 0 | BGFX_STATE_CULL_CW | BGFX_STATE_RGB_WRITE | BGFX_STATE_ALPHA_WRITE | BGFX_STATE_DEPTH_TEST_LESS | BGFX_STATE_MSAA ; switch (mode) { case 0: // Set vertex and fragment shaders. bgfx::setProgram(blend); // Set render states. bgfx::setState(state | BGFX_STATE_BLEND_ALPHA ); break; case 1: // Set vertex and fragment shaders. bgfx::setProgram(wbSeparatePass); // Set render states. bgfx::setState(state | BGFX_STATE_BLEND_FUNC_SEPARATE(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ZERO, BGFX_STATE_BLEND_INV_SRC_ALPHA) ); break; default: // Set vertex and fragment shaders. bgfx::setProgram(wbPass); // Set render states. bgfx::setState(state | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_ONE, BGFX_STATE_BLEND_ONE) | BGFX_STATE_BLEND_INDEPENDENT , 0 | BGFX_STATE_BLEND_FUNC_RT_1(BGFX_STATE_BLEND_ZERO, BGFX_STATE_BLEND_SRC_COLOR) ); break; } // Submit primitive for rendering to view 0. bgfx::submit(0); } } } if (0 != mode) { bgfx::setTexture(0, u_texColor0, fbtextures[0]); bgfx::setTexture(1, u_texColor1, fbtextures[1]); bgfx::setProgram(1 == mode ? wbSeparateBlit : wbBlit); bgfx::setState(0 | BGFX_STATE_RGB_WRITE | BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_INV_SRC_ALPHA, BGFX_STATE_BLEND_SRC_ALPHA) ); screenSpaceQuad( (float)width, (float)height, s_flipV); bgfx::submit(1); } // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } // Cleanup. imguiDestroy(); bgfx::destroyFrameBuffer(fbh); bgfx::destroyIndexBuffer(ibh); bgfx::destroyVertexBuffer(vbh); bgfx::destroyProgram(blend); bgfx::destroyProgram(wbSeparatePass); bgfx::destroyProgram(wbSeparateBlit); bgfx::destroyProgram(wbPass); bgfx::destroyProgram(wbBlit); bgfx::destroyUniform(u_texColor0); bgfx::destroyUniform(u_texColor1); bgfx::destroyUniform(u_color); // 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_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*/) { 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); // 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; } // Uniforms. u_shadowMap = bgfx::createUniform("u_shadowMap", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle u_lightPos = bgfx::createUniform("u_lightPos", bgfx::UniformType::Uniform4fv); bgfx::UniformHandle u_lightMtx = bgfx::createUniform("u_lightMtx", bgfx::UniformType::Uniform4x4fv); // Programs. bgfx::ProgramHandle progPackDepth = loadProgram("vs_smsimple_packdepth", "fs_smsimple_packdepth"); bgfx::ProgramHandle progDraw = loadProgram("vs_smsimple_draw", "fs_smsimple_draw"); // Vertex declarations. bgfx::VertexDecl PosNormalDecl; PosNormalDecl.begin(); PosNormalDecl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float); PosNormalDecl.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true); PosNormalDecl.end(); // Meshes. Mesh bunnyMesh; Mesh cubeMesh; Mesh hollowcubeMesh; Mesh hplaneMesh; bunnyMesh.load("meshes/bunny.bin"); cubeMesh.load("meshes/cube.bin"); hollowcubeMesh.load("meshes/hollowcube.bin"); hplaneMesh.load(s_hplaneVertices, s_numHPlaneVertices, PosNormalDecl, s_planeIndices, s_numPlaneIndices); // Render targets. uint16_t shadowMapSize = 512; bgfx::TextureHandle fbtextures[] = { bgfx::createTexture2D(shadowMapSize, shadowMapSize, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT), bgfx::createTexture2D(shadowMapSize, shadowMapSize, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_BUFFER_ONLY), }; s_shadowMapFB = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true); // Set view and projection matrices. float view[16]; float proj[16]; const float eye[3] = { 0.0f, 30.0f, -60.0f }; const float at[3] = { 0.0f, 5.0f, 0.0f }; mtxLookAt(view, eye, at); const float aspect = float(int32_t(width) ) / float(int32_t(height) ); mtxProj(proj, 60.0f, aspect, 0.1f, 1000.0f); // Time acumulators. float timeAccumulatorLight = 0.0f; float timeAccumulatorScene = 0.0f; entry::MouseState mouseState; while (!entry::processEvents(width, height, debug, reset, &mouseState) ) { // Time. 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; const float deltaTime = float(frameTime/freq); // Update time accumulators. timeAccumulatorLight += deltaTime; timeAccumulatorScene += deltaTime; // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/15-shadowmaps-simple"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Shadow maps example."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); // Setup lights. float lightPos[4]; lightPos[0] = -cos(timeAccumulatorLight); lightPos[1] = -1.0f; lightPos[2] = -sin(timeAccumulatorLight); lightPos[3] = 0.0f; bgfx::setUniform(u_lightPos, lightPos); // Setup instance matrices. float mtxFloor[16]; mtxScaleRotateTranslate(mtxFloor , 30.0f //scaleX , 30.0f //scaleY , 30.0f //scaleZ , 0.0f //rotX , 0.0f //rotY , 0.0f //rotZ , 0.0f //translateX , 0.0f //translateY , 0.0f //translateZ ); float mtxBunny[16]; mtxScaleRotateTranslate(mtxBunny , 5.0f , 5.0f , 5.0f , 0.0f , float(M_PI) - timeAccumulatorScene , 0.0f , 15.0f , 5.0f , 0.0f ); float mtxHollowcube[16]; mtxScaleRotateTranslate(mtxHollowcube , 2.5f , 2.5f , 2.5f , 0.0f , 1.56f - timeAccumulatorScene , 0.0f , 0.0f , 10.0f , 0.0f ); float mtxCube[16]; mtxScaleRotateTranslate(mtxCube , 2.5f , 2.5f , 2.5f , 0.0f , 1.56f - timeAccumulatorScene , 0.0f , -15.0f , 5.0f , 0.0f ); // Define matrices. float screenView[16]; float screenProj[16]; mtxIdentity(screenView); mtxOrtho(screenProj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f); float lightView[16]; float lightProj[16]; const float eye[3] = { -lightPos[0], -lightPos[1], -lightPos[2], }; const float at[3] = { 0.0f, 0.0f, 0.0f }; mtxLookAt(lightView, eye, at); const float area = 30.0f; mtxOrtho(lightProj, -area, area, -area, area, -100.0f, 100.0f); bgfx::setViewRect(RENDER_SHADOW_PASS_ID, 0, 0, shadowMapSize, shadowMapSize); bgfx::setViewRect(RENDER_SCENE_PASS_ID, 0, 0, width, height); bgfx::setViewTransform(RENDER_SHADOW_PASS_ID, lightView, lightProj); bgfx::setViewTransform(RENDER_SCENE_PASS_ID, view, proj); bgfx::setViewFrameBuffer(RENDER_SHADOW_PASS_ID, s_shadowMapFB); // Clear backbuffer and shadowmap framebuffer at beginning. bgfx::setViewClearMask(0x3, BGFX_CLEAR_COLOR_BIT | BGFX_CLEAR_DEPTH_BIT, 0x303030ff, 1.0f, 0); bgfx::submitMask(0x3); // Render. { // Craft shadow map. hplaneMesh.submit(RENDER_SHADOW_PASS_ID, mtxFloor, progPackDepth); bunnyMesh.submit(RENDER_SHADOW_PASS_ID, mtxBunny, progPackDepth); hollowcubeMesh.submit(RENDER_SHADOW_PASS_ID, mtxHollowcube, progPackDepth); cubeMesh.submit(RENDER_SHADOW_PASS_ID, mtxCube, progPackDepth); } { // Draw Scene. float mtxShadow[16]; //lightviewProjCrop float lightMtx[16]; //modelLightviewProjCrop const float s = (s_flipV) ? 1.0f : -1.0f; //sign const float mtxCrop[16] = { 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, s*0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, }; float mtxTmp[16]; mtxMul(mtxTmp, lightProj, mtxCrop); mtxMul(mtxShadow, lightView, mtxTmp); // Floor. mtxMul(lightMtx, mtxFloor, mtxShadow); bgfx::setUniform(u_lightMtx, lightMtx); hplaneMesh.submit(RENDER_SCENE_PASS_ID, mtxFloor, progDraw); // Bunny. mtxMul(lightMtx, mtxBunny, mtxShadow); bgfx::setUniform(u_lightMtx, lightMtx); bunnyMesh.submit(RENDER_SCENE_PASS_ID, mtxBunny, progDraw); // Hollow cube. mtxMul(lightMtx, mtxHollowcube, mtxShadow); bgfx::setUniform(u_lightMtx, lightMtx); hollowcubeMesh.submit(RENDER_SCENE_PASS_ID, mtxHollowcube, progDraw); // Cube. mtxMul(lightMtx, mtxCube, mtxShadow); bgfx::setUniform(u_lightMtx, lightMtx); cubeMesh.submit(RENDER_SCENE_PASS_ID, mtxCube, progDraw); } // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } bunnyMesh.unload(); cubeMesh.unload(); hollowcubeMesh.unload(); hplaneMesh.unload(); bgfx::destroyProgram(progPackDepth); bgfx::destroyProgram(progDraw); bgfx::destroyFrameBuffer(s_shadowMapFB); bgfx::destroyUniform(u_shadowMap); bgfx::destroyUniform(u_lightPos); bgfx::destroyUniform(u_lightMtx); // Shutdown bgfx. bgfx::shutdown(); return 0; }
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 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/"; break; case bgfx::RendererType::Direct3D11: s_shaderPath = "shaders/dx11/"; break; case bgfx::RendererType::OpenGL: s_shaderPath = "shaders/glsl/"; break; case bgfx::RendererType::OpenGLES2: case bgfx::RendererType::OpenGLES3: s_shaderPath = "shaders/gles/"; break; } // Create vertex stream declaration. s_PosTexcoordDecl.begin(); s_PosTexcoordDecl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float); s_PosTexcoordDecl.add(bgfx::Attrib::TexCoord0, 3, bgfx::AttribType::Float); s_PosTexcoordDecl.end(); const bgfx::Memory* mem; // Create static vertex buffer. mem = bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) ); bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer(mem, s_PosTexcoordDecl); // Create static index buffer. mem = bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) ); bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(mem); // Create texture sampler uniforms. bgfx::UniformHandle u_texCube = bgfx::createUniform("u_texCube", bgfx::UniformType::Uniform1iv); // Load vertex shader. mem = loadShader("vs_update"); bgfx::VertexShaderHandle vsh = bgfx::createVertexShader(mem); // Load fragment shader. mem = loadShader("fs_update"); bgfx::FragmentShaderHandle fsh = bgfx::createFragmentShader(mem); // Create program from shaders. bgfx::ProgramHandle program = bgfx::createProgram(vsh, fsh); // We can destroy vertex and fragment shader here since // their reference is kept inside bgfx after calling createProgram. // Vertex and fragment shader will be destroyed once program is // destroyed. bgfx::destroyVertexShader(vsh); bgfx::destroyFragmentShader(fsh); const uint32_t textureSide = 2048; bgfx::TextureHandle textureCube = bgfx::createTextureCube(6 , textureSide , 1 , bgfx::TextureFormat::BGRA8 , BGFX_TEXTURE_MIN_POINT|BGFX_TEXTURE_MAG_POINT|BGFX_TEXTURE_MIP_POINT ); uint8_t rr = rand()%255; uint8_t gg = rand()%255; uint8_t bb = rand()%255; int64_t updateTime = 0; RectPackCubeT<256> cube(textureSide); uint32_t hit = 0; uint32_t miss = 0; std::list<PackCube> quads; int64_t timeOffset = bx::getHPCounter(); while (!processEvents(width, height, debug, reset) ) { // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, 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::submit(0); int64_t now = bx::getHPCounter(); static int64_t last = now; const int64_t frameTime = now - last; last = now; const int64_t freq = bx::getHPFrequency(); const double toMs = 1000.0/double(freq); float time = (float)( (now - timeOffset)/double(bx::getHPFrequency() ) ); // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/08-update"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Updating textures."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); if (now > updateTime) { PackCube face; uint32_t bw = bx::uint16_max(1, rand()%(textureSide/4) ); uint32_t bh = bx::uint16_max(1, rand()%(textureSide/4) ); if (cube.find(bw, bh, face) ) { quads.push_back(face); ++hit; bgfx::TextureInfo ti; const Pack2D& rect = face.m_rect; bgfx::calcTextureSize(ti, rect.m_width, rect.m_height, 1, 1, bgfx::TextureFormat::BGRA8); // updateTime = now + freq/10; const bgfx::Memory* mem = bgfx::alloc(ti.storageSize); uint8_t* data = (uint8_t*)mem->data; for (uint32_t ii = 0, num = ti.storageSize*8/ti.bitsPerPixel; ii < num; ++ii) { data[0] = bb; data[1] = rr; data[2] = gg; data[3] = 0xff; data += 4; } bgfx::updateTextureCube(textureCube, face.m_side, 0, rect.m_x, rect.m_y, rect.m_width, rect.m_height, mem); rr = rand()%255; gg = rand()%255; bb = rand()%255; } else { ++miss; for (uint32_t ii = 0, num = bx::uint32_min(10, (uint32_t)quads.size() ); ii < num; ++ii) { const PackCube& face = quads.front(); cube.clear(face); quads.pop_front(); } } } bgfx::dbgTextPrintf(0, 4, 0x0f, "hit: %d, miss %d", hit, miss); float at[3] = { 0.0f, 0.0f, 0.0f }; float eye[3] = { 0.0f, 0.0f, -5.0f }; float view[16]; float proj[16]; mtxLookAt(view, eye, at); mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); // Set view and projection matrix for view 0. bgfx::setViewTransform(0, view, proj); float mtx[16]; mtxRotateXY(mtx, time, time*0.37f); // Set model matrix for rendering. bgfx::setTransform(mtx); // Set vertex and fragment shaders. bgfx::setProgram(program); // Set vertex and index buffer. bgfx::setVertexBuffer(vbh); bgfx::setIndexBuffer(ibh); // Bind texture. bgfx::setTexture(0, u_texCube, textureCube); // Set render states. bgfx::setState(BGFX_STATE_DEFAULT); // Submit primitive for rendering to view 0. bgfx::submit(0); // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } // Cleanup. bgfx::destroyIndexBuffer(ibh); bgfx::destroyVertexBuffer(vbh); bgfx::destroyProgram(program); bgfx::destroyTexture(textureCube); bgfx::destroyUniform(u_texCube); // 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; }
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 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/"; 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; } bgfx::UniformHandle u_texColor = bgfx::createUniform("u_texColor", bgfx::UniformType::Uniform1iv); bgfx::UniformHandle u_stipple = bgfx::createUniform("u_stipple", bgfx::UniformType::Uniform3fv); bgfx::UniformHandle u_texStipple = bgfx::createUniform("u_texStipple", bgfx::UniformType::Uniform1iv); bgfx::ProgramHandle program = loadProgram("vs_tree", "fs_tree"); const bgfx::Memory* mem; mem = loadTexture("leafs1.dds"); bgfx::TextureHandle textureLeafs = bgfx::createTexture(mem); mem = loadTexture("bark1.dds"); bgfx::TextureHandle textureBark = bgfx::createTexture(mem); bgfx::TextureHandle textureStipple; const bgfx::Memory* stipple = bgfx::alloc(8*4); memset(stipple->data, 0, stipple->size); for (uint32_t ii = 0; ii < 32; ++ii) { stipple->data[knightTour[ii].m_y * 8 + knightTour[ii].m_x] = ii*4; } textureStipple = bgfx::createTexture2D(8, 4, 1, bgfx::TextureFormat::L8, BGFX_TEXTURE_MAG_POINT|BGFX_TEXTURE_MIN_POINT, stipple); Mesh mesh_top[3]; mesh_top[0].load("meshes/tree1b_lod0_1.bin"); mesh_top[1].load("meshes/tree1b_lod1_1.bin"); mesh_top[2].load("meshes/tree1b_lod2_1.bin"); Mesh mesh_trunk[3]; mesh_trunk[0].load("meshes/tree1b_lod0_2.bin"); mesh_trunk[1].load("meshes/tree1b_lod1_2.bin"); mesh_trunk[2].load("meshes/tree1b_lod2_2.bin"); 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); int32_t scrollArea = 0; bool transitions = true; int transitionFrame = 0; int currLOD = 0; int targetLOD = 0; float at[3] = { 0.0f, 1.0f, 0.0f }; float eye[3] = { 0.0f, 1.0f, -2.0f }; 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 ); imguiBeginScrollArea("Toggle transitions", width - width / 5 - 10, 10, width / 5, height / 6, &scrollArea); imguiSeparatorLine(); if (imguiButton(transitions ? "ON" : "OFF") ) { transitions = !transitions; } static float distance = 2.0f; imguiSlider("Distance", &distance, 2.0f, 6.0f, .01f); imguiEndScrollArea(); imguiEndFrame(); // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, 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::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; // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/12-lod"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Mesh LOD transitions."); bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs); bgfx::dbgTextPrintf(0, 4, transitions ? 0x2f : 0x1f, transitions ? "Transitions on" : "Transitions off"); eye[2] = -distance; float view[16]; float proj[16]; mtxLookAt(view, eye, at); mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); // Set view and projection matrix for view 0. bgfx::setViewTransform(0, view, proj); float mtx[16]; mtxIdentity(mtx); float stipple[3]; float stippleInv[3]; const int currentLODframe = transitions ? 32-transitionFrame : 32; const int mainLOD = transitions ? currLOD : targetLOD; stipple[0] = 0.0f; stipple[1] = -1.0f; stipple[2] = (float(currentLODframe)*4.0f/255.0f) - (1.0f/255.0f); stippleInv[0] = (float(31)*4.0f/255.0f); stippleInv[1] = 1.0f; stippleInv[2] = (float(transitionFrame)*4.0f/255.0f) - (1.0f/255.0f); bgfx::setTexture(0, u_texColor, textureBark); bgfx::setTexture(1, u_texStipple, textureStipple); bgfx::setUniform(u_stipple, stipple); mesh_trunk[mainLOD].submit(program, mtx, false); bgfx::setTexture(0, u_texColor, textureLeafs); bgfx::setTexture(1, u_texStipple, textureStipple); bgfx::setUniform(u_stipple, stipple); mesh_top[mainLOD].submit(program, mtx, true); if (transitions && (transitionFrame != 0) ) { bgfx::setTexture(0, u_texColor, textureBark); bgfx::setTexture(1, u_texStipple, textureStipple); bgfx::setUniform(u_stipple, stippleInv); mesh_trunk[targetLOD].submit(program, mtx, false); bgfx::setTexture(0, u_texColor, textureLeafs); bgfx::setTexture(1, u_texStipple, textureStipple); bgfx::setUniform(u_stipple, stippleInv); mesh_top[targetLOD].submit(program, mtx, true); } int lod = 0; if (eye[2] < -2.5f) { lod = 1; } if (eye[2] < -5.0f) { lod = 2; } if (targetLOD!=lod) { if (targetLOD==currLOD) { targetLOD = lod; } } if (currLOD != targetLOD) { transitionFrame++; } if (transitionFrame>32) { currLOD = targetLOD; transitionFrame = 0; } // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } for (uint32_t ii = 0; ii < 3; ++ii) { mesh_top[ii].unload(); mesh_trunk[ii].unload(); } // Cleanup. bgfx::destroyProgram(program); bgfx::destroyUniform(u_texColor); bgfx::destroyUniform(u_stipple); bgfx::destroyUniform(u_texStipple); bgfx::destroyTexture(textureStipple); bgfx::destroyTexture(textureLeafs); bgfx::destroyTexture(textureBark); // Shutdown bgfx. bgfx::shutdown(); return 0; }
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 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/"; break; case bgfx::RendererType::Direct3D11: s_shaderPath = "shaders/dx11/"; break; case bgfx::RendererType::OpenGL: s_shaderPath = "shaders/glsl/"; break; case bgfx::RendererType::OpenGLES2: case bgfx::RendererType::OpenGLES3: s_shaderPath = "shaders/gles/"; break; } // Create vertex stream declaration. s_PosColorDecl.begin(); s_PosColorDecl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float); s_PosColorDecl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true); s_PosColorDecl.end(); const bgfx::Memory* mem; // Create static vertex buffer. mem = bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) ); bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer(mem, s_PosColorDecl); // Create static index buffer. mem = bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) ); bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(mem); // Load vertex shader. mem = loadShader("vs_instancing"); bgfx::VertexShaderHandle vsh = bgfx::createVertexShader(mem); // Load fragment shader. mem = loadShader("fs_instancing"); bgfx::FragmentShaderHandle fsh = bgfx::createFragmentShader(mem); // Create program from shaders. bgfx::ProgramHandle program = bgfx::createProgram(vsh, fsh); // We can destroy vertex and fragment shader here since // their reference is kept inside bgfx after calling createProgram. // Vertex and fragment shader will be destroyed once program is // destroyed. bgfx::destroyVertexShader(vsh); bgfx::destroyFragmentShader(fsh); int64_t timeOffset = bx::getHPCounter(); while (!entry::processEvents(width, height, debug, reset) ) { // Set view 0 default viewport. bgfx::setViewRect(0, 0, 0, width, 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::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 - timeOffset)/double(bx::getHPFrequency() ) ); // Use debug font to print information about this example. bgfx::dbgTextClear(); bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/05-instancing"); bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Geometry instancing."); 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, -35.0f }; float view[16]; float proj[16]; mtxLookAt(view, eye, at); mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f); // Set view and projection matrix for view 0. bgfx::setViewTransform(0, view, proj); const uint16_t instanceStride = 80; const bgfx::InstanceDataBuffer* idb = bgfx::allocInstanceDataBuffer(121, instanceStride); if (NULL != idb) { uint8_t* data = idb->data; // Write instance data for 11x11 cubes. for (uint32_t yy = 0; yy < 11; ++yy) { for (uint32_t xx = 0; xx < 11; ++xx) { float* mtx = (float*)data; mtxRotateXY(mtx, time + xx*0.21f, time + yy*0.37f); mtx[12] = -15.0f + float(xx)*3.0f; mtx[13] = -15.0f + float(yy)*3.0f; mtx[14] = 0.0f; float* color = (float*)&data[64]; color[0] = sin(time+float(xx)/11.0f)*0.5f+0.5f; color[1] = cos(time+float(yy)/11.0f)*0.5f+0.5f; color[2] = sin(time*3.0f)*0.5f+0.5f; color[3] = 1.0f; data += instanceStride; } } // Set vertex and fragment shaders. bgfx::setProgram(program); // Set vertex and index buffer. bgfx::setVertexBuffer(vbh); bgfx::setIndexBuffer(ibh); // Set instance data buffer. bgfx::setInstanceDataBuffer(idb); // Set render states. bgfx::setState(BGFX_STATE_DEFAULT); // Submit primitive for rendering to view 0. bgfx::submit(0); } // Advance to next frame. Rendering thread will be kicked to // process submitted rendering primitives. bgfx::frame(); } // Cleanup. bgfx::destroyIndexBuffer(ibh); bgfx::destroyVertexBuffer(vbh); bgfx::destroyProgram(program); // Shutdown bgfx. bgfx::shutdown(); return 0; }