Example #1
0
void CMaNGOS_Map::handleTools()
{
	int type = !m_tool ? TOOL_NONE : m_tool->type();

    if (imguiCheck("Draw Map Mesh", m_DrawMapMesh))
    {
        m_DrawMapMesh = !m_DrawMapMesh;
    }

    if (imguiCheck("Draw VMap Mesh", m_DrawVMapMesh))
    {
        m_DrawVMapMesh = !m_DrawVMapMesh;
    }
    
    if (!m_navMesh)
        return;
    
    imguiSeparatorLine();

	if (imguiCheck("Test Navmesh", type == TOOL_NAVMESH_TESTER))
	{
		setTool(new NavMeshTesterTool);
	}
	/*if (imguiCheck("Prune Navmesh", type == TOOL_NAVMESH_PRUNE))
	{
		//setTool(new NavMeshPruneTool);
	}
	if (imguiCheck("Create Off-Mesh Links", type == TOOL_OFFMESH_CONNECTION))
	{
		//setTool(new OffMeshConnectionTool);
	}
	if (imguiCheck("Create Convex Volumes", type == TOOL_CONVEX_VOLUME))
	{
		//setTool(new ConvexVolumeTool);
	}
	if (imguiCheck("Create Crowds", type == TOOL_CROWD))
	{
		//setTool(new CrowdTool);
	}*/
	
	imguiSeparatorLine();

	imguiIndent();

	if (m_tool)
		m_tool->handleMenu();

	imguiUnindent();
}
void Sample_TileMesh::handleTools()
{
	int type = !m_tool ? TOOL_NONE : m_tool->type();

	if (imguiCheck("Test Navmesh", type == TOOL_NAVMESH_TESTER))
	{
		setTool(new NavMeshTesterTool);
	}
	if (imguiCheck("Create Tiles", type == TOOL_TILE_EDIT))
	{
		setTool(new NavMeshTileTool);
	}
	if (imguiCheck("Create Off-Mesh Links", type == TOOL_OFFMESH_CONNECTION))
	{
		setTool(new OffMeshConnectionTool);
	}
	if (imguiCheck("Create Convex Volumes", type == TOOL_CONVEX_VOLUME))
	{
		setTool(new ConvexVolumeTool);
	}
	if (imguiCheck("Create Crowds", type == TOOL_CROWD))
	{
		setTool(new CrowdTool);
	}
	
	imguiSeparatorLine();

	imguiIndent();

	if (m_tool)
		m_tool->handleMenu();

	imguiUnindent();
}
Example #3
0
File: main.cpp Project: find/bgfx
int _main_(int, char**)
{
    uint32_t width = 800, height = 600;
    uint32_t debug = BGFX_DEBUG_TEXT | BGFX_DEBUG_STATS;
    uint32_t reset = BGFX_RESET_VSYNC | BGFX_RESET_MSAA_X8;
    bool showStats = true;

    bgfx::init();
    bgfx::reset(width, height, reset);

    bgfx::setDebug(debug);

    size_t sz = 0;
    void* fontdata = nullptr;
    if(loadfile("assets/font/droidsans.ttf", fontdata, sz))
        imguiCreate(fontdata, sz);
    else
        imguiCreate();
    free(fontdata);

    entry::MouseState mouseState;
    float rgb[3] = {0.3f, 0.3f, 0.3f};
    bool colorwheelActivated = false;
    int32_t scrollArea = 0;
    while(!entry::processEvents(width, height, debug, reset, &mouseState)) {
        auto encodeColor = [&rgb]()->uint32_t{
            return uint32_t(rgb[0]*255)<<24|uint32_t(rgb[1]*255)<<16|uint32_t(rgb[2]*255)<<8|0xff;
        };
        bgfx::setViewClear(0,
                BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH,
                encodeColor(), 1.0f, 0);

        bgfx::setViewRect(0, 0, 0, width, height);
        
        bgfx::submit(0, BGFX_INVALID_HANDLE);
        bgfx::dbgTextPrintf(0, 1, 0x4f, "hello world");
        bgfx::dbgTextPrintf(0, 2, 0x5f, "simple bgfx program");

        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("Test", width-350, 50, 330, 500, &scrollArea);
        imguiSeparatorLine();
        imguiLabel("foobar");
        if(imguiButton("say hi"))
            fprintf(stdout, "hi there\n");
        imguiBool("show stats", showStats);
        uint32_t newDebug = BGFX_DEBUG_TEXT | (showStats ? BGFX_DEBUG_STATS : 0);
        if(newDebug != debug) {
            debug = newDebug;
            bgfx::setDebug(debug);
        }
        imguiColorWheel("bg color", rgb, colorwheelActivated);
        ImGui::ColorEdit3("bg color", rgb);
        imguiSeparatorLine();
        if(imguiButton("quit"))
            break;
        imguiEndScrollArea();
        imguiEndFrame();

        bgfx::frame();
    }

    imguiDestroy();
    bgfx::shutdown();
    return 0;
}
Example #4
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;
}
Example #5
0
int main( int argc, char **argv )
{
    int width = 1024, height=768;

    // Initialise GLFW
    if( !glfwInit() )
    {
        fprintf( stderr, "Failed to initialize GLFW\n" );
        exit( EXIT_FAILURE );
    }

    // Open a window and create its OpenGL context
    if( !glfwOpenWindow( width, height, 0,0,0,0, 24,0, GLFW_WINDOW ) )
    {
        fprintf( stderr, "Failed to open GLFW window\n" );
        glfwTerminate();
        exit( EXIT_FAILURE );
    }

    glfwSetWindowTitle( "imgui sample imguiRenderGL2" );
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
          /* Problem: glewInit failed, something is seriously wrong. */
          fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
          exit( EXIT_FAILURE );
    }

    // Ensure we can capture the escape key being pressed below
    glfwEnable( GLFW_STICKY_KEYS );

    // Enable vertical sync (on cards that support it)
    glfwSwapInterval( 1 );

    // Init UI
    if (!imguiRenderGLInit("DroidSans.ttf"))
    {
        fprintf(stderr, "Could not init GUI renderer.\n");
        exit(EXIT_FAILURE);
    }

    glClearColor(0.8f, 0.8f, 0.8f, 1.f);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_DEPTH_TEST);

    // imgui states
    bool checked1 = false;
    bool checked2 = false;
    bool checked3 = true;
    bool checked4 = false;
    float value1 = 50.f;
    float value2 = 30.f;
    int scrollarea1 = 0;
    int scrollarea2 = 0;

    // glfw scrolling
    int glfwscroll = 0;
    do
    {
        glfwGetWindowSize(&width, &height);
        glViewport(0, 0, width, height);

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // Mouse states
        unsigned char mousebutton = 0;
        int currentglfwscroll = glfwGetMouseWheel();
        int mscroll = 0;
        if (currentglfwscroll < glfwscroll)
            mscroll = 2;
         if (currentglfwscroll > glfwscroll)
            mscroll = -2;
        glfwscroll = currentglfwscroll;
        int mousex; int mousey;
        glfwGetMousePos(&mousex, &mousey);
        mousey = height - mousey;
        int leftButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_LEFT );
        int rightButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_RIGHT );
        int middleButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_MIDDLE );
        int toggle = 0;
        if( leftButton == GLFW_PRESS )
            mousebutton |= IMGUI_MBUT_LEFT;
    
        // Draw UI
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        float projection[16] = { 2.f/width, 0.f, 0.f,  0.f,
                                 0.f, 2.f/height,  0.f,  0.f,
                                 0.f,  0.f, -2.f, 0.f,
                                 -1.f, -1.f,  -1.f,  1.f };
        glLoadMatrixf(projection);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glUseProgram(0);


        imguiBeginFrame(mousex, mousey, mousebutton, mscroll);

        imguiBeginScrollArea("Scroll area", 10, 10, width / 5, height - 20, &scrollarea1);
        imguiSeparatorLine();
        imguiSeparator();

        imguiButton("Button");
        imguiButton("Disabled button", false);
        imguiItem("Item");
        imguiItem("Disabled item", false);
        toggle = imguiCheck("Checkbox", checked1);
        if (toggle)
            checked1 = !checked1;
        toggle = imguiCheck("Disabled checkbox", checked2, false);
        if (toggle)
            checked2 = !checked2;
        toggle = imguiCollapse("Collapse", "subtext", checked3);
        if (checked3)
        {
            imguiIndent();
            imguiLabel("Collapsible element");
            imguiUnindent();
        }
        if (toggle)
            checked3 = !checked3;
        toggle = imguiCollapse("Disabled collapse", "subtext", checked4, false);
        if (toggle)
            checked4 = !checked4;
        imguiLabel("Label");
        imguiValue("Value");
        imguiSlider("Slider", &value1, 0.f, 100.f, 1.f);
        imguiSlider("Disabled slider", &value2, 0.f, 100.f, 1.f, false);
        imguiIndent();
        imguiLabel("Indented");
        imguiUnindent();
        imguiLabel("Unindented");

        imguiEndScrollArea();

        imguiBeginScrollArea("Scroll area", 20 + width / 5, 500, width / 5, height - 510, &scrollarea2);
        imguiSeparatorLine();
        imguiSeparator();
        for (int i = 0; i < 100; ++i)
            imguiLabel("A wall of text");

        imguiEndScrollArea();
        imguiEndFrame();

        imguiDrawText(30 + width / 5 * 2, height - 20, IMGUI_ALIGN_LEFT, "Free text",  imguiRGBA(32,192, 32,192));
        imguiDrawText(30 + width / 5 * 2 + 100, height - 40, IMGUI_ALIGN_RIGHT, "Free text",  imguiRGBA(32, 32, 192, 192));
        imguiDrawText(30 + width / 5 * 2 + 50, height - 60, IMGUI_ALIGN_CENTER, "Free text",  imguiRGBA(192, 32, 32,192));

        imguiDrawLine(30 + width / 5 * 2, height - 80, 30 + width / 5 * 2 + 100, height - 60, 1.f, imguiRGBA(32,192, 32,192));
        imguiDrawLine(30 + width / 5 * 2, height - 100, 30 + width / 5 * 2 + 100, height - 80, 2.f, imguiRGBA(32, 32, 192, 192));
        imguiDrawLine(30 + width / 5 * 2, height - 120, 30 + width / 5 * 2 + 100, height - 100, 3.f, imguiRGBA(192, 32, 32,192));

        imguiDrawRoundedRect(30 + width / 5 * 2, height - 240, 100, 100, 5.f, imguiRGBA(32,192, 32,192));
        imguiDrawRoundedRect(30 + width / 5 * 2, height - 350, 100, 100, 10.f, imguiRGBA(32, 32, 192, 192));
        imguiDrawRoundedRect(30 + width / 5 * 2, height - 470, 100, 100, 20.f, imguiRGBA(192, 32, 32,192));
        
        imguiDrawRect(30 + width / 5 * 2, height - 590, 100, 100, imguiRGBA(32, 192, 32, 192));
        imguiDrawRect(30 + width / 5 * 2, height - 710, 100, 100, imguiRGBA(32, 32, 192, 192));
        imguiDrawRect(30 + width / 5 * 2, height - 830, 100, 100, imguiRGBA(192, 32, 32,192));

        imguiRenderGLDraw(width, height); 

        // Check for errors
        GLenum err = glGetError();
        if(err != GL_NO_ERROR)
        {
            fprintf(stderr, "OpenGL Error : %s\n", gluErrorString(err));
        }

        // Swap buffers
        glfwSwapBuffers();

    } // Check if the ESC key was pressed or the window was closed
    while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS &&
           glfwGetWindowParam( GLFW_OPENED ) );

    // Clean UI
    imguiRenderGLDestroy();

    // Close OpenGL window and terminate GLFW
    glfwTerminate();

    exit( EXIT_SUCCESS );
}
Example #6
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:
		break;

	case bgfx::RendererType::OpenGL:
	case bgfx::RendererType::OpenGLES:
		s_flipV = true;
		break;
	}

	// Imgui.
	void* data = load("font/droidsans.ttf");
	imguiCreate(data);
	free(data);

	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.
		bx::mtxLookAt(view, eye, at);
		bx::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.
		bx::mtxIdentity(view);
		bx::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];
					bx::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;
}
//  This function's code is from the RecastDemo project's main.cpp file by Mikko Mononen
void MyRecastDemo::guiRender()
{

	GLdouble proj[16];
	GLdouble model[16];
	GLint view[4];
	glGetDoublev(GL_PROJECTION_MATRIX, proj);
	glGetDoublev(GL_MODELVIEW_MATRIX, model);
	glGetIntegerv(GL_VIEWPORT, view);
		
	GLdouble x, y, z;
	gluUnProject(m_mouseX, m_mouseY, 0.0f, model, proj, view, &x, &y, &z);
	m_rays[0] = (float)x; m_rays[1] = (float)y; m_rays[2] = (float)z;
	gluUnProject(m_mouseX, m_mouseY, 1.0f, model, proj, view, &x, &y, &z);
	m_raye[0] = (float)x; m_raye[1] = (float)y; m_raye[2] = (float)z;


	glDisable(GL_DEPTH_TEST);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0, m_width, 0, m_height);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
		
	glColor4ub(255,255,255,255);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

	m_mouseOverMenu = false;
		
	imguiBeginFrame( m_mouseX,m_mouseY,m_mouseBut,m_mouseScroll );
		
	const char msg[] = "W/S/A/D: move (+ shift)  |  F1: toggle recast gui  |  F2: toggle node names  |  F12: invert mouse";
	imguiDrawText(280, m_height-20, IMGUI_ALIGN_LEFT, msg, imguiRGBA(255,255,255,200));
	
		
	if (m_showMenu)
	{
		if (m_sample)
		{
			m_sample->handleRenderOverlay((double*)proj, (double*)model, (int*)view);

		}

		if (imguiBeginScrollArea("Properties", m_width-250-10, 10, 250, m_height-20, &m_propScroll))
			m_mouseOverMenu = true;

		if (imguiCheck("Show Log", m_showLog))
			m_showLog = !m_showLog;
		if (imguiCheck("Show Tools", m_showTools))
			m_showTools = !m_showTools;

		imguiSeparator();
		imguiLabel("Sample");
		if (imguiButton(m_sampleName))
		{
			if (m_showSample)
			{
				m_showSample = false;
			}
			else
			{
				m_showSample = true;
				m_showConfig = false;
			}
		}
			
		imguiSeparator();
		imguiLabel("Config File");
		if (imguiButton(m_configName))
		{
			if (m_showConfig)
			{
				m_showConfig = false;
			}
			else
			{
				m_showSample = false;
				m_showConfig = true;
				scanDirectory("Content", ".xml", m_files);
			}
		}
		if (m_geom)
		{
			char text[64];
			snprintf(text, 64, "Verts: %.1fk  Tris: %.1fk",
						m_geom->getMesh()->getVertCount()/1000.0f,
						m_geom->getMesh()->getTriCount()/1000.0f);
			imguiValue(text);
		}
		imguiSeparator();

		if (m_geom && m_sample)
		{
			imguiSeparatorLine();
				
			m_sample->handleSettings();

			if (imguiButton("Build"))
			{
				m_ctx.resetLog();
				if (!m_sample->handleBuild())
				{
					m_showLog = true;
					m_logScroll = 0;
				}
				m_ctx.dumpLog("Build log %s:", m_configName);
			}

			imguiSeparator();
		}
			
		if (m_sample)
		{
			imguiSeparatorLine();
			m_sample->handleDebugMode();
		}

		imguiEndScrollArea();
	}
	
	
	// Sample selection dialog.
	if (m_showSample)
	{
		static int levelScroll = 0;
		if (imguiBeginScrollArea("Choose Sample", m_width-10-250-10-200, m_height-10-250, 200, 250, &levelScroll))
			m_mouseOverMenu = true;

		Sample* newSample = 0;
		for (int i = 0; i < g_nsamples; ++i)
		{
			if (imguiItem(g_samples[i].name))
			{
				newSample = g_samples[i].create();
				if (newSample)
					strcpy(m_sampleName, g_samples[i].name);
			}
		}
		if (newSample)
		{
			delete m_geom;
			m_geom = 0;
			delete m_sample;
			m_sample = newSample;
			m_sample->setContext(&m_ctx);
			if (m_geom && m_sample)
			{
				m_sample->handleMeshChanged(m_geom);
			}
			else if(!m_geom)
			{
				m_geom = new InputGeom();
				m_geom->loadMesh( &m_ctx, m_configXmlFile.c_str() );
			}
			if( m_geom && m_sample )
			{
				m_sample->handleMeshChanged(m_geom);
				m_sample->handleSettings();
			}

			m_showSample = false;
		}			
		imguiEndScrollArea();
	}

	// Config selection dialog.
	if (m_showConfig)
	{
		static int levelScroll = 0;
		if (imguiBeginScrollArea("Choose Config File", m_width-10-250-10-200, m_height-10-450, 200, 450, &levelScroll))
			m_mouseOverMenu = true;
			
		int levelToLoad = -1;
		for (int i = 0; i < m_files.size; ++i)
		{
			if (imguiItem(m_files.files[i]))
				levelToLoad = i;
		}
			
		if (levelToLoad != -1)
		{
			strncpy(m_configName, m_files.files[levelToLoad], sizeof(m_configName));
			m_configName[sizeof(m_configName)-1] = '\0';
			m_showConfig = false;
				
			delete m_geom;
			m_geom = 0;
				
			char path[256];
			strcpy(path, "Content/");
			strcat(path, m_configName);
			
			m_configXmlFile = path;

			m_geom = new InputGeom();

			if( m_loadedSceneGraphRes )
			{
				// Remove previously loaded scene .
				// Every scene.xml file loaded should group its children in a GroupNode.
				int nrFoundNodes = h3dFindNodes( H3DRootNode, "", H3DNodeTypes::Group);
				for( int i = 0; i<2; ++i )
				{
					int node = h3dGetNodeFindResult(i);
					const char* name = h3dGetNodeParamStr( node, H3DNodeParams::NameStr);
					std::string camName(name);
					// Do not delete nodes directly under the root node (e.g. the demo's camera)
					if( camName.compare("RootNode") != 0) 
					{
						h3dRemoveNode( h3dGetNodeFindResult(i) );
					}
				}
				
				int a =	h3dRemoveResource( m_loadedSceneGraphRes );
				h3dReleaseUnusedResources();
			}

			if( !loadSceneFileFromConfig( path) )
			{
				m_showLog = true;
				m_logScroll = 0;
				m_ctx.log(RC_LOG_ERROR, "Error loading resources from specified scene file.");
			}

			if (!m_geom || !m_geom->loadMesh(&m_ctx, m_configXmlFile.c_str()) )
			{
				delete m_geom;
				m_geom = 0;
					
				m_showLog = true;
				m_logScroll = 0;
				m_ctx.log(RC_LOG_ERROR, "Error loading nav mesh geometry from: \"%s\"", m_configName);
				m_ctx.dumpLog("Config: Geom load log %s:", m_configName);
			}
			if (m_sample && m_geom)
			{
				m_sample->handleMeshChanged(m_geom);
			}
		}
			
		imguiEndScrollArea();
			
	}

	// Log
	if (m_showLog && m_showMenu)
	{
		if (imguiBeginScrollArea("Log", 250+20, 10, m_width - 300 - 250, 200, &m_logScroll))
			m_mouseOverMenu = true;
		for (int i = 0; i < m_ctx.getLogCount(); ++i)
			imguiLabel(m_ctx.getLogText(i));
		imguiEndScrollArea();
	}
		
	// Tools
	if (!m_showTestCases && m_showTools && m_showMenu) // && m_geom && m_sample)
	{
		if (imguiBeginScrollArea("Tools", 10, 10, 250, m_height-20, &m_toolsScroll))
			m_mouseOverMenu = true;

		if (m_sample)
			m_sample->handleTools();
			
		imguiEndScrollArea();
	}

	m_wasMouseOverMenu = m_mouseOverMenu;
	if(!m_wasMouseOverMenu)
	{
		// In case we move a GUI slider and leave the menu area
		m_mouseBut = 0;
	}
	m_mouseScroll = 0;
	
	imguiEndFrame();
	
	imguiRenderGLDraw();

	glDisable(GL_BLEND);
	glEnable(GL_DEPTH_TEST);
}
Example #8
0
void sInterface()
{
	int menuWidth = 200;
	ui.mouseOverMenu = false;
	if (ui.showMenu)
	{
		bool over = imguiBeginScrollArea("Testbed Controls", g_camera.m_width - menuWidth - 10, 10, menuWidth, g_camera.m_height - 20, &ui.scrollarea1);
		if (over) ui.mouseOverMenu = true;

		imguiSeparatorLine();

		imguiLabel("Script");
		if (imguiButton(entry->name, true))
		{
			ui.chooseTest = !ui.chooseTest;
		}

		imguiSeparatorLine();

		imguiSlider("Vel Iters", &settings.velocityIterations, 0, 50, 1, true);
		imguiSlider("Pos Iters", &settings.positionIterations, 0, 50, 1, true);
		imguiSlider("Hertz", &settings.hz, 5.0f, 120.0f, 5.0f, true);

		if (imguiCheck("Sleep", settings.enableSleep, true))
			settings.enableSleep = !settings.enableSleep;
		if (imguiCheck("Warm Starting", settings.enableWarmStarting, true))
			settings.enableWarmStarting = !settings.enableWarmStarting;
		if (imguiCheck("Time of Impact", settings.enableContinuous, true))
			settings.enableContinuous = !settings.enableContinuous;
		if (imguiCheck("Sub-Stepping", settings.enableSubStepping, true))
			settings.enableSubStepping = !settings.enableSubStepping;

		imguiSeparatorLine();

		if (imguiCheck("Shapes", settings.drawShapes, true))
			settings.drawShapes = !settings.drawShapes;
		if (imguiCheck("Joints", settings.drawJoints, true))
			settings.drawJoints = !settings.drawJoints;
		if (imguiCheck("AABBs", settings.drawAABBs, true))
			settings.drawAABBs = !settings.drawAABBs;
		if (imguiCheck("Contact Points", settings.drawContactPoints, true))
			settings.drawContactPoints = !settings.drawContactPoints;
		if (imguiCheck("Contact Normals", settings.drawContactNormals, true))
			settings.drawContactNormals = !settings.drawContactNormals;
		if (imguiCheck("Contact Impulses", settings.drawContactImpulse, true))
			settings.drawContactImpulse = !settings.drawContactImpulse;
		if (imguiCheck("Friction Impulses", settings.drawFrictionImpulse, true))
			settings.drawFrictionImpulse = !settings.drawFrictionImpulse;
		if (imguiCheck("Center of Masses", settings.drawCOMs, true))
			settings.drawCOMs = !settings.drawCOMs;
		if (imguiCheck("Statistics", settings.drawStats, true))
			settings.drawStats = !settings.drawStats;
		if (imguiCheck("Profile", settings.drawProfile, true))
			settings.drawProfile = !settings.drawProfile;

		if (imguiButton("Pause", true))
			settings.pause = !settings.pause;

		if (imguiButton("Single Step", true))
			settings.singleStep = !settings.singleStep;

		if (imguiButton("Restart", true))
			sRestart();

		if (imguiButton("Quit", true))
			glfwSetWindowShouldClose(mainWindow, GL_TRUE);

		imguiEndScrollArea();
	}

	int testMenuWidth = 200;
	if (ui.chooseTest)
	{
		static int testScroll = 0;
		bool over = imguiBeginScrollArea("Choose Script", g_camera.m_width - menuWidth - testMenuWidth - 20, 10, testMenuWidth, g_camera.m_height - 20, &testScroll);
		if (over) ui.mouseOverMenu = true;

//		for (int i = 0; i < testCount; ++i)
		size_t i = 0;
		for(auto const& s : b2d_scripts)
		{
			if (imguiItem(s.name.c_str(), true))
			{
				script_index = i;
				delete test;
				//entry = g_testEntries + i;
				test = entry->createFcn(b2d_scripts[script_index].filepath);
				ui.chooseTest = false;
			}

			++i;
		}

		imguiEndScrollArea();
	}

	imguiEndFrame();

}
Example #9
0
void CMaNGOS_Map::handleExtraSettings()
{
    imguiLabel("Map Id");
    char buff[4];
    memset(buff, 0, sizeof(buff));
    itoa(m_mapID, buff, 10);
    if (imguiButton(buff))
    {
        if (m_showLevel == SHOW_LEVEL_MAP)
        {
            m_showLevel = SHOW_LEVEL_NONE;
        }
        else
        {
            m_showLevel = SHOW_LEVEL_MAP;
        }
    }

    imguiLabel("Tile");
    if (imguiButton(m_TileButtonStr.c_str()))
    {
        if (m_showLevel == SHOW_LEVEL_TILES || m_showLevel == SHOW_LEVEL_NEIGHBOR_TILES)
        {
            m_showLevel = SHOW_LEVEL_NONE;
        }
        else
        {
            if (m_MapInfos->IsEmpty())
                m_showLevel = SHOW_LEVEL_TILES;
            else if (!m_NeighborTiles.empty())
                    m_showLevel = SHOW_LEVEL_NEIGHBOR_TILES;
        }
    }

    if (!m_MapInfos->IsEmpty())
    {
        imguiSeparatorLine();
        MeshObjectsMap::const_iterator itr = m_MapInfos->GetGeomsMap()->begin();
        imguiLabel("Loaded tile");
        while (itr != m_MapInfos->GetGeomsMap()->end())
        {
            MeshObjects* mo = (*itr).second;
            string map = mo->GetMap() ? "MAP " : "";
            string vmap = mo->GetVMap() ? "VMAP " : "";
            string mmap = m_MapInfos->GetTileRef(mo->GetTileX(), mo->GetTileY()) ? "MMAP" : "";

            char buff[40];
            snprintf(buff, sizeof(buff), "%dx%d > Found %s%s%s", mo->GetTileX(), mo->GetTileY(), map.c_str(), vmap.c_str(), mmap.c_str());
            if (imguiItem(buff))
            {
                RemoveTileData(mo->GetTileX(), mo->GetTileY());
                unsigned int pxy = VMAP::StaticMapTree::packTileID(mo->GetTileX(), mo->GetTileY());
                m_NeighborTiles.insert(pxy);

                if (m_MapInfos->IsEmpty())
                {
                    m_TileButtonStr = "Click to choose a tile";
                }
                break;
            }
            else
                ++itr;
        }
    }
}
Example #10
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 views  clear state.
	bgfx::setViewClear(0
		, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
		, 0x303030ff
		, 1.0f
		, 0
		);

	// Imgui.
	imguiCreate();

	// Uniforms.
	s_uniforms.init();

	// Vertex declarations.
	PosColorTexCoord0Vertex::init();

	LightProbe lightProbes[LightProbe::Count];
	lightProbes[LightProbe::Wells ].load("wells");
	lightProbes[LightProbe::Uffizi].load("uffizi");
	lightProbes[LightProbe::Pisa  ].load("pisa");
	lightProbes[LightProbe::Ennis ].load("ennis");
	lightProbes[LightProbe::Grace ].load("grace");
	LightProbe::Enum currentLightProbe = LightProbe::Wells;

	bgfx::UniformHandle u_mtx        = bgfx::createUniform("u_mtx",        bgfx::UniformType::Mat4);
	bgfx::UniformHandle u_params     = bgfx::createUniform("u_params",     bgfx::UniformType::Vec4);
	bgfx::UniformHandle u_flags      = bgfx::createUniform("u_flags",      bgfx::UniformType::Vec4);
	bgfx::UniformHandle u_camPos     = bgfx::createUniform("u_camPos",     bgfx::UniformType::Vec4);
	bgfx::UniformHandle s_texCube    = bgfx::createUniform("s_texCube",    bgfx::UniformType::Int1);
	bgfx::UniformHandle s_texCubeIrr = bgfx::createUniform("s_texCubeIrr", bgfx::UniformType::Int1);

	bgfx::ProgramHandle programMesh  = loadProgram("vs_ibl_mesh",   "fs_ibl_mesh");
	bgfx::ProgramHandle programSky   = loadProgram("vs_ibl_skybox", "fs_ibl_skybox");

	Mesh* meshBunny;
	meshBunny = meshLoad("meshes/bunny.bin");

	struct Settings
	{
		float m_speed;
		float m_glossiness;
		float m_exposure;
		float m_diffspec;
		float m_rgbDiff[3];
		float m_rgbSpec[3];
		bool m_diffuse;
		bool m_specular;
		bool m_diffuseIbl;
		bool m_specularIbl;
		bool m_showDiffColorWheel;
		bool m_showSpecColorWheel;
		ImguiCubemap::Enum m_crossCubemapPreview;
	};

	Settings settings;
	settings.m_speed = 0.37f;
	settings.m_glossiness = 1.0f;
	settings.m_exposure = 0.0f;
	settings.m_diffspec = 0.65f;
	settings.m_rgbDiff[0] = 0.2f;
	settings.m_rgbDiff[1] = 0.2f;
	settings.m_rgbDiff[2] = 0.2f;
	settings.m_rgbSpec[0] = 1.0f;
	settings.m_rgbSpec[1] = 1.0f;
	settings.m_rgbSpec[2] = 1.0f;
	settings.m_diffuse = true;
	settings.m_specular = true;
	settings.m_diffuseIbl = true;
	settings.m_specularIbl = true;
	settings.m_showDiffColorWheel = true;
	settings.m_showSpecColorWheel = false;
	settings.m_crossCubemapPreview = ImguiCubemap::Cross;

	float time = 0.0f;

	int32_t leftScrollArea = 0;

	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)
			| (mouseState.m_buttons[entry::MouseButton::Middle] ? IMGUI_MBUT_MIDDLE : 0)
			, mouseState.m_mz
			, width
			, height
			);

		static int32_t rightScrollArea = 0;
		imguiBeginScrollArea("Settings", width - 256 - 10, 10, 256, 540, &rightScrollArea);

		imguiLabel("Shade:");
		imguiSeparator();
		imguiBool("Diffuse",      settings.m_diffuse);
		imguiBool("Specular",     settings.m_specular);
		imguiBool("IBL Diffuse",  settings.m_diffuseIbl);
		imguiBool("IBL Specular", settings.m_specularIbl);

		imguiSeparatorLine();
		imguiSlider("Speed", settings.m_speed, 0.0f, 1.0f, 0.01f);
		imguiSeparatorLine();

		imguiSeparator();
		imguiSlider("Exposure", settings.m_exposure, -8.0f, 8.0f, 0.01f);
		imguiSeparator();

		imguiLabel("Environment:");
		currentLightProbe = LightProbe::Enum(imguiChoose(currentLightProbe
													   , "Wells"
													   , "Uffizi"
													   , "Pisa"
													   , "Ennis"
													   , "Grace"
													   ) );
		static float lod = 0.0f;
		if (imguiCube(lightProbes[currentLightProbe].m_tex, lod, settings.m_crossCubemapPreview, true) )
		{
			settings.m_crossCubemapPreview = ImguiCubemap::Enum( (settings.m_crossCubemapPreview+1) % ImguiCubemap::Count);
		}
		imguiSlider("Texture LOD", lod, 0.0f, 10.1f, 0.1f);

		imguiEndScrollArea();

		imguiBeginScrollArea("Settings", 10, 70, 256, 576, &leftScrollArea);

		imguiLabel("Material properties:");
		imguiSeparator();
		imguiSlider("Diffuse - Specular", settings.m_diffspec,   0.0f, 1.0f, 0.01f);
		imguiSlider("Glossiness"        , settings.m_glossiness, 0.0f, 1.0f, 0.01f);
		imguiSeparator();

		imguiColorWheel("Diffuse color:", &settings.m_rgbDiff[0], settings.m_showDiffColorWheel);
		imguiSeparator();
		imguiColorWheel("Specular color:", &settings.m_rgbSpec[0], settings.m_showSpecColorWheel);

		imguiSeparator();
		imguiLabel("Predefined materials:");
		imguiSeparator();

		if (imguiButton("Gold") )
		{
			settings.m_glossiness = 0.8f;
			settings.m_diffspec   = 1.0f;

			settings.m_rgbDiff[0] = 0.0f;
			settings.m_rgbDiff[1] = 0.0f;
			settings.m_rgbDiff[2] = 0.0f;

			settings.m_rgbSpec[0] = 1.0f;
			settings.m_rgbSpec[1] = 0.86f;
			settings.m_rgbSpec[2] = 0.58f;
		}

		if (imguiButton("Copper") )
		{
			settings.m_glossiness = 0.67f;
			settings.m_diffspec   = 1.0f;

			settings.m_rgbDiff[0] = 0.0f;
			settings.m_rgbDiff[1] = 0.0f;
			settings.m_rgbDiff[2] = 0.0f;

			settings.m_rgbSpec[0] = 0.98f;
			settings.m_rgbSpec[1] = 0.82f;
			settings.m_rgbSpec[2] = 0.76f;
		}

		if (imguiButton("Titanium") )
		{
			settings.m_glossiness = 0.57f;
			settings.m_diffspec   = 1.0f;

			settings.m_rgbDiff[0] = 0.0f;
			settings.m_rgbDiff[1] = 0.0f;
			settings.m_rgbDiff[2] = 0.0f;

			settings.m_rgbSpec[0] = 0.76f;
			settings.m_rgbSpec[1] = 0.73f;
			settings.m_rgbSpec[2] = 0.71f;
		}

		if (imguiButton("Steel") )
		{
			settings.m_glossiness = 0.82f;
			settings.m_diffspec   = 1.0f;

			settings.m_rgbDiff[0] = 0.0f;
			settings.m_rgbDiff[1] = 0.0f;
			settings.m_rgbDiff[2] = 0.0f;

			settings.m_rgbSpec[0] = 0.77f;
			settings.m_rgbSpec[1] = 0.78f;
			settings.m_rgbSpec[2] = 0.77f;
		}

		imguiEndScrollArea();

		imguiEndFrame();

		s_uniforms.m_glossiness = settings.m_glossiness;
		s_uniforms.m_exposure = settings.m_exposure;
		s_uniforms.m_diffspec = settings.m_diffspec;
		s_uniforms.m_flags[0] = float(settings.m_diffuse);
		s_uniforms.m_flags[1] = float(settings.m_specular);
		s_uniforms.m_flags[2] = float(settings.m_diffuseIbl);
		s_uniforms.m_flags[3] = float(settings.m_specularIbl);
		memcpy(s_uniforms.m_rgbDiff, settings.m_rgbDiff, 3*sizeof(float) );
		memcpy(s_uniforms.m_rgbSpec, settings.m_rgbSpec, 3*sizeof(float) );

		s_uniforms.submitPerFrameUniforms();

		int64_t now = bx::getHPCounter();
		static int64_t last = now;
		const int64_t frameTime = now - last;
		last = now;
		const double freq = double(bx::getHPFrequency() );
		const double toMs = 1000.0/freq;

		time += (float)(frameTime*settings.m_speed/freq);
		s_uniforms.m_camPosTime[3] = time;

		// Use debug font to print information about this example.
		bgfx::dbgTextClear();
		bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/18-ibl");
		bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Image based lightning.");
		bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);

		float at[3] = { 0.0f, 0.0f, 0.0f };
		float eye[3] = { 0.0f, 0.0f, -3.0f };

		bx::mtxRotateXY(s_uniforms.m_mtx
			, 0.0f
			, time
			);

		float view[16];
		float proj[16];

		bx::mtxIdentity(view);
		bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f);
		bgfx::setViewTransform(0, view, proj);

		bx::mtxLookAt(view, eye, at);
		memcpy(s_uniforms.m_camPosTime, eye, 3*sizeof(float) );
		bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f);
		bgfx::setViewTransform(1, view, proj);

		bgfx::setViewRect(0, 0, 0, width, height);
		bgfx::setViewRect(1, 0, 0, width, height);

		// View 0.
		bgfx::setTexture(0, s_texCube, lightProbes[currentLightProbe].m_tex);
		bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
		screenSpaceQuad( (float)width, (float)height, true);
		s_uniforms.submitPerDrawUniforms();
		bgfx::submit(0, programSky);

		// View 1.
		float mtx[16];
		bx::mtxSRT(mtx
				, 1.0f
				, 1.0f
				, 1.0f
				, 0.0f
				, bx::pi+time
				, 0.0f
				, 0.0f
				, -1.0f
				, 0.0f
				);

		bgfx::setTexture(0, s_texCube,    lightProbes[currentLightProbe].m_tex);
		bgfx::setTexture(1, s_texCubeIrr, lightProbes[currentLightProbe].m_texIrr);
		meshSubmit(meshBunny, 1, programMesh, mtx);

		// Advance to next frame. Rendering thread will be kicked to
		// process submitted rendering primitives.
		bgfx::frame();
	}

	meshUnload(meshBunny);

	// Cleanup.
	bgfx::destroyProgram(programMesh);
	bgfx::destroyProgram(programSky);

	bgfx::destroyUniform(u_camPos);
	bgfx::destroyUniform(u_flags);
	bgfx::destroyUniform(u_params);
	bgfx::destroyUniform(u_mtx);

	bgfx::destroyUniform(s_texCube);
	bgfx::destroyUniform(s_texCubeIrr);

	for (uint8_t ii = 0; ii < LightProbe::Count; ++ii)
	{
		lightProbes[ii].destroy();
	}

	s_uniforms.destroy();

	imguiDestroy();

	// Shutdown bgfx.
	bgfx::shutdown();

	return 0;
}
Example #11
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 | BGFX_CLEAR_DEPTH
		, 0x303030ff
		, 1.0f
		, 0
		);

	// Imgui.
	imguiCreate();

	char* bigText = loadText( "text/sherlock_holmes_a_scandal_in_bohemia_arthur_conan_doyle.txt");

	// Init the text rendering system.
	FontManager* fontManager = new FontManager(512);
	TextBufferManager* textBufferManager = new TextBufferManager(fontManager);

	TrueTypeHandle font = loadTtf(fontManager, "font/special_elite.ttf");

	// Create a distance field font.
	FontHandle fontSdf = fontManager->createFontByPixelSize(font, 0, 48, FONT_TYPE_DISTANCE);

	// Create a scaled down version of the same font (without adding anything to the atlas).
	FontHandle fontScaled = fontManager->createScaledFontToPixelSize(fontSdf, 14);

	TextLineMetrics metrics(fontManager->getFontInfo(fontScaled) );
	uint32_t lineCount = metrics.getLineCount(bigText);

	float visibleLineCount = 20.0f;

	const char* textBegin = 0;
	const char* textEnd = 0;
	metrics.getSubText(bigText, 0, (uint32_t)visibleLineCount, textBegin, textEnd);

	TextBufferHandle scrollableBuffer = textBufferManager->createTextBuffer(FONT_TYPE_DISTANCE, BufferType::Transient);
	textBufferManager->setTextColor(scrollableBuffer, 0xFFFFFFFF);

	textBufferManager->appendText(scrollableBuffer, fontScaled, textBegin, textEnd);

	entry::MouseState mouseState;
	int32_t scrollArea = 0;
	const int32_t guiPanelWidth = 250;
	const int32_t guiPanelHeight = 200;
	float textScroll = 0.0f;
	float textRotation = 0.0f;
	float textScale = 1.0f;
	float textSize = 14.0f;

	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)
			, mouseState.m_mz
			, width
			, height
			);

		imguiBeginScrollArea("Text Area"
			, width - guiPanelWidth - 10
			, 10
			, guiPanelWidth
			, guiPanelHeight
			, &scrollArea
			);
		imguiSeparatorLine();

		bool recomputeVisibleText = false;
		recomputeVisibleText |= imguiSlider("Number of lines", visibleLineCount, 1.0f, 177.0f , 1.0f);
		if (imguiSlider("Font size", textSize, 6.0f, 64.0f , 1.0f) )
		{
			fontManager->destroyFont(fontScaled);
			fontScaled = fontManager->createScaledFontToPixelSize(fontSdf, (uint32_t) textSize);
			metrics = TextLineMetrics(fontManager->getFontInfo(fontScaled) );
			recomputeVisibleText = true;
		}

		recomputeVisibleText |= imguiSlider("Scroll", textScroll, 0.0f, (lineCount-visibleLineCount) , 1.0f);
		imguiSlider("Rotate", textRotation, 0.0f, bx::pi*2.0f , 0.1f);
		recomputeVisibleText |= imguiSlider("Scale", textScale, 0.1f, 10.0f , 0.1f);

		if (recomputeVisibleText)
		{
			textBufferManager->clearTextBuffer(scrollableBuffer);
			metrics.getSubText(bigText,(uint32_t)textScroll, (uint32_t)(textScroll+visibleLineCount), textBegin, textEnd);
			textBufferManager->appendText(scrollableBuffer, fontScaled, textBegin, textEnd);
		}

		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 print32_t information about this example.
		bgfx::dbgTextClear();
		bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/11-fontsdf");
		bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Use a single distance field font to render text of various size.");
		bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime) * toMs);

		float at[3]  = { 0, 0, 0.0f };
		float eye[3] = {0, 0, -1.0f };

		float view[16];
		bx::mtxLookAt(view, eye, at);

		const float centering = 0.5f;

		// Setup a top-left ortho matrix for screen space drawing.
		const bgfx::HMD* hmd = bgfx::getHMD();
		if (NULL != hmd && 0 != (hmd->flags & BGFX_HMD_RENDERING) )
		{
			float proj[16];
			bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f);

			static float time = 0.0f;
			time += 0.05f;

			const float dist = 10.0f;
			const float offset0 = -proj[8] + (hmd->eye[0].viewOffset[0] / dist * proj[0]);
			const float offset1 = -proj[8] + (hmd->eye[1].viewOffset[0] / dist * proj[0]);

			float ortho[2][16];
			const float viewOffset = width/4.0f;
			const float viewWidth  = width/2.0f;
			bx::mtxOrtho(ortho[0], centering + viewOffset, centering + viewOffset + viewWidth, height + centering, centering, -1.0f, 1.0f, offset0);
			bx::mtxOrtho(ortho[1], centering + viewOffset, centering + viewOffset + viewWidth, height + centering, centering, -1.0f, 1.0f, offset1);
			bgfx::setViewTransform(0, view, ortho[0], BGFX_VIEW_STEREO, ortho[1]);
			bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height);
		}
		else
		{
			float ortho[16];
			bx::mtxOrtho(ortho, centering, width + centering, height + centering, centering, -1.0f, 1.0f);
			bgfx::setViewTransform(0, view, ortho);
			bgfx::setViewRect(0, 0, 0, width, height);
		}

		//very crude approximation :(
		float textAreaWidth = 0.5f * 66.0f * fontManager->getFontInfo(fontScaled).maxAdvanceWidth;

		float textRotMat[16];
		float textCenterMat[16];
		float textScaleMat[16];
		float screenCenterMat[16];

		bx::mtxRotateZ(textRotMat, textRotation);
		bx::mtxTranslate(textCenterMat, -(textAreaWidth * 0.5f), (-visibleLineCount)*metrics.getLineHeight()*0.5f, 0);
		bx::mtxScale(textScaleMat, textScale, textScale, 1.0f);
		bx::mtxTranslate(screenCenterMat, ( (width) * 0.5f), ( (height) * 0.5f), 0);

		//first translate to text center, then scale, then rotate
		float tmpMat[16];
		bx::mtxMul(tmpMat, textCenterMat, textRotMat);

		float tmpMat2[16];
		bx::mtxMul(tmpMat2, tmpMat, textScaleMat);

		float tmpMat3[16];
		bx::mtxMul(tmpMat3, tmpMat2, screenCenterMat);

		// Set model matrix for rendering.
		bgfx::setTransform(tmpMat3);

		// Draw your text.
		textBufferManager->submitTextBuffer(scrollableBuffer, 0);

		// Advance to next frame. Rendering thread will be kicked to
		// process submitted rendering primitives.
		bgfx::frame();
	}

	imguiDestroy();

	free(bigText);

	fontManager->destroyTtf(font);
	// Destroy the fonts.
	fontManager->destroyFont(fontSdf);
	fontManager->destroyFont(fontScaled);

	textBufferManager->destroyTextBuffer(scrollableBuffer);

	delete textBufferManager;
	delete fontManager;

	// Shutdown bgfx.
	bgfx::shutdown();

	return 0;
}
Example #12
0
void CrowdTool::handleMenu()
{
	if (!m_state)
		return;
	CrowdToolParams* params = m_state->getToolParams();

	if (imguiCheck("Create Agents", m_mode == TOOLMODE_CREATE))
		m_mode = TOOLMODE_CREATE;
	if (imguiCheck("Move Target", m_mode == TOOLMODE_MOVE_TARGET))
		m_mode = TOOLMODE_MOVE_TARGET;
	if (imguiCheck("Select Agent", m_mode == TOOLMODE_SELECT))
		m_mode = TOOLMODE_SELECT;
	if (imguiCheck("Toggle Polys", m_mode == TOOLMODE_TOGGLE_POLYS))
		m_mode = TOOLMODE_TOGGLE_POLYS;
	
	imguiSeparatorLine();
		
	if (imguiCollapse("Options", 0, params->m_expandOptions))
		params->m_expandOptions = !params->m_expandOptions;
	
	if (params->m_expandOptions)
	{
		imguiIndent();
		if (imguiCheck("Optimize Visibility", params->m_optimizeVis))
		{
			params->m_optimizeVis = !params->m_optimizeVis;
			m_state->updateAgentParams();
		}
		if (imguiCheck("Optimize Topology", params->m_optimizeTopo))
		{
			params->m_optimizeTopo = !params->m_optimizeTopo;
			m_state->updateAgentParams();
		}
		if (imguiCheck("Anticipate Turns", params->m_anticipateTurns))
		{
			params->m_anticipateTurns = !params->m_anticipateTurns;
			m_state->updateAgentParams();
		}
		if (imguiCheck("Obstacle Avoidance", params->m_obstacleAvoidance))
		{
			params->m_obstacleAvoidance = !params->m_obstacleAvoidance;
			m_state->updateAgentParams();
		}
		if (imguiSlider("Avoidance Quality", &params->m_obstacleAvoidanceType, 0.0f, 3.0f, 1.0f))
		{
			m_state->updateAgentParams();
		}
		if (imguiCheck("Separation", params->m_separation))
		{
			params->m_separation = !params->m_separation;
			m_state->updateAgentParams();
		}
		if (imguiSlider("Separation Weight", &params->m_separationWeight, 0.0f, 20.0f, 0.01f))
		{
			m_state->updateAgentParams();
		}
		
		imguiUnindent();
	}

	if (imguiCollapse("Selected Debug Draw", 0, params->m_expandSelectedDebugDraw))
		params->m_expandSelectedDebugDraw = !params->m_expandSelectedDebugDraw;
		
	if (params->m_expandSelectedDebugDraw)
	{
		imguiIndent();
		if (imguiCheck("Show Corners", params->m_showCorners))
			params->m_showCorners = !params->m_showCorners;
		if (imguiCheck("Show Collision Segs", params->m_showCollisionSegments))
			params->m_showCollisionSegments = !params->m_showCollisionSegments;
		if (imguiCheck("Show Path", params->m_showPath))
			params->m_showPath = !params->m_showPath;
		if (imguiCheck("Show VO", params->m_showVO))
			params->m_showVO = !params->m_showVO;
		if (imguiCheck("Show Path Optimization", params->m_showOpt))
			params->m_showOpt = !params->m_showOpt;
		if (imguiCheck("Show Neighbours", params->m_showNeis))
			params->m_showNeis = !params->m_showNeis;
		imguiUnindent();
	}
		
	if (imguiCollapse("Debug Draw", 0, params->m_expandDebugDraw))
		params->m_expandDebugDraw = !params->m_expandDebugDraw;
	
	if (params->m_expandDebugDraw)
	{
		imguiIndent();
		if (imguiCheck("Show Labels", params->m_showLabels))
			params->m_showLabels = !params->m_showLabels;
		if (imguiCheck("Show Prox Grid", params->m_showGrid))
			params->m_showGrid = !params->m_showGrid;
		if (imguiCheck("Show Nodes", params->m_showNodes))
			params->m_showNodes = !params->m_showNodes;
		if (imguiCheck("Show Perf Graph", params->m_showPerfGraph))
			params->m_showPerfGraph = !params->m_showPerfGraph;
		if (imguiCheck("Show Detail All", params->m_showDetailAll))
			params->m_showDetailAll = !params->m_showDetailAll;
		imguiUnindent();
	}
}
Example #13
0
File: hdr.cpp Project: Bewolf2/bgfx
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;
}
Example #14
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;
}
Example #15
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|BGFX_CLEAR_DEPTH
		, 0x303030ff
		, 1.0f
		, 0
		);

	bgfx::UniformHandle s_texColor   = bgfx::createUniform("s_texColor",   bgfx::UniformType::Int1);
	bgfx::UniformHandle s_texStipple = bgfx::createUniform("s_texStipple", bgfx::UniformType::Int1);
	bgfx::UniformHandle u_stipple    = bgfx::createUniform("u_stipple",    bgfx::UniformType::Vec4);

	bgfx::ProgramHandle program = loadProgram("vs_tree", "fs_tree");

	bgfx::TextureHandle textureLeafs = loadTexture("leafs1.dds");
	bgfx::TextureHandle textureBark  = loadTexture("bark1.dds");

	bgfx::TextureHandle textureStipple;

	const bgfx::Memory* stippleTex = bgfx::alloc(8*4);
	memset(stippleTex->data, 0, stippleTex->size);

	for (uint32_t ii = 0; ii < 32; ++ii)
	{
		stippleTex->data[knightTour[ii].m_y * 8 + knightTour[ii].m_x] = ii*4;
	}

	textureStipple = bgfx::createTexture2D(8, 4, 1
			, bgfx::TextureFormat::R8
			, BGFX_TEXTURE_MAG_POINT|BGFX_TEXTURE_MIN_POINT
			, stippleTex
			);

	Mesh* meshTop[3] =
	{
		meshLoad("meshes/tree1b_lod0_1.bin"),
		meshLoad("meshes/tree1b_lod1_1.bin"),
		meshLoad("meshes/tree1b_lod2_1.bin"),
	};

	Mesh* meshTrunk[3] =
	{
		meshLoad("meshes/tree1b_lod0_2.bin"),
		meshLoad("meshes/tree1b_lod1_2.bin"),
		meshLoad("meshes/tree1b_lod2_2.bin"),
	};

	// Imgui.
	imguiCreate();

	const uint64_t stateCommon = 0
		| BGFX_STATE_RGB_WRITE
		| BGFX_STATE_ALPHA_WRITE
		| BGFX_STATE_DEPTH_TEST_LESS
		| BGFX_STATE_CULL_CCW
		| BGFX_STATE_MSAA
		;

	const uint64_t stateTransparent = stateCommon
		| BGFX_STATE_BLEND_ALPHA
		;

	const uint64_t stateOpaque = stateCommon
		| BGFX_STATE_DEPTH_WRITE
		;

	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;

		// Set view and projection matrix for view 0.
		const bgfx::HMD* hmd = bgfx::getHMD();
		if (NULL != hmd && 0 != (hmd->flags & BGFX_HMD_RENDERING))
		{
			float view[16];
			bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);

			float proj[16];
			bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f);

			bgfx::setViewTransform(0, view, proj);

			// Set view 0 default viewport.
			//
			// Use HMD's width/height since HMD's internal frame buffer size
			// might be much larger than window size.
			bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height);
		}
		else
		{
			float view[16];
			bx::mtxLookAt(view, eye, at);

			float proj[16];
			bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f);
			bgfx::setViewTransform(0, view, proj);

			// Set view 0 default viewport.
			bgfx::setViewRect(0, 0, 0, width, height);
		}

		float mtx[16];
		bx::mtxScale(mtx, 0.1f, 0.1f, 0.1f);

		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, s_texColor, textureBark);
		bgfx::setTexture(1, s_texStipple, textureStipple);
		bgfx::setUniform(u_stipple, stipple);
		meshSubmit(meshTrunk[mainLOD], 0, program, mtx, stateOpaque);

		bgfx::setTexture(0, s_texColor, textureLeafs);
		bgfx::setTexture(1, s_texStipple, textureStipple);
		bgfx::setUniform(u_stipple, stipple);
		meshSubmit(meshTop[mainLOD], 0, program, mtx, stateTransparent);

		if (transitions
		&& (transitionFrame != 0) )
		{
			bgfx::setTexture(0, s_texColor, textureBark);
			bgfx::setTexture(1, s_texStipple, textureStipple);
			bgfx::setUniform(u_stipple, stippleInv);
			meshSubmit(meshTrunk[targetLOD], 0, program, mtx, stateOpaque);

			bgfx::setTexture(0, s_texColor, textureLeafs);
			bgfx::setTexture(1, s_texStipple, textureStipple);
			bgfx::setUniform(u_stipple, stippleInv);
			meshSubmit(meshTop[targetLOD], 0, program, mtx, stateTransparent);
		}

		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();
	}

	imguiDestroy();

	for (uint32_t ii = 0; ii < 3; ++ii)
	{
		meshUnload(meshTop[ii]);
		meshUnload(meshTrunk[ii]);
	}

	// Cleanup.
	bgfx::destroyProgram(program);

	bgfx::destroyUniform(s_texColor);
	bgfx::destroyUniform(s_texStipple);
	bgfx::destroyUniform(u_stipple);

	bgfx::destroyTexture(textureStipple);
	bgfx::destroyTexture(textureLeafs);
	bgfx::destroyTexture(textureBark);

	// Shutdown bgfx.
	bgfx::shutdown();

	return 0;
}
Example #16
0
int main(int /*argc*/, char** /*argv*/)
{
	// Init SDL
	if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
	{
		printf("Could not initialise SDL\n");
		return -1;
	}
	
	// Center window
	char env[] = "SDL_VIDEO_CENTERED=1";
	putenv(env);

	// Init OpenGL
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
//#ifndef WIN32
	SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
	SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
//#endif

	const SDL_VideoInfo* vi = SDL_GetVideoInfo();

	bool presentationMode = false;

	int width, height;
	SDL_Surface* screen = 0;
	
	if (presentationMode)
	{
        width = 1700;
        height = 1000;
		screen = SDL_SetVideoMode(width, height, 0, SDL_OPENGL|SDL_FULLSCREEN);
	}
	else
	{	
        width = 1700;
        height = 1000;
		screen = SDL_SetVideoMode(width, height, 0, SDL_OPENGL);
	}
	
	if (!screen)
	{
		printf("Could not initialise SDL opengl\n");
		return -1;
	}

	glEnable(GL_MULTISAMPLE);

	SDL_WM_SetCaption("Recast Demo", 0);
	
	if (!imguiRenderGLInit("DroidSans.ttf"))
	{
		printf("Could not init GUI renderer.\n");
		SDL_Quit();
		return -1;
	}
	
	float t = 0.0f;
	float timeAcc = 0.0f;
	Uint32 lastTime = SDL_GetTicks();
	int mx = 0, my = 0;
	float rx = 45;
	float ry = -45;
	float moveW = 0, moveS = 0, moveA = 0, moveD = 0;
	float camx = 0, camy = 0, camz = 0, camr = 1000;
	float origrx = 0, origry = 0;
	int origx = 0, origy = 0;
	float scrollZoom = 0;
	bool rotate = false;
	bool movedDuringRotate = false;
	float rays[3], raye[3]; 
	bool mouseOverMenu = false;
	bool showMenu = !presentationMode;
	bool showLog = false;
	bool showTools = true;
	bool showLevels = false;
	bool showSample = false;
	bool showTestCases = false;

	int propScroll = 0;
	int logScroll = 0;
	int toolsScroll = 0;
	
	char sampleName[64] = "Choose Sample..."; 
	
	FileList files;
	char meshName[128] = "Choose Mesh...";
	
	float mpos[3] = {0,0,0};
	bool mposSet = false;
	
	SlideShow slideShow;
	slideShow.init("slides/");
	
	InputGeom* geom = 0;
	Sample* sample = 0;
	TestCase* test = 0;

	BuildContext ctx;
	
	glEnable(GL_CULL_FACE);
	
	float fogCol[4] = { 0.32f, 0.31f, 0.30f, 1.0f };
	glEnable(GL_FOG);
	glFogi(GL_FOG_MODE, GL_LINEAR);
	glFogf(GL_FOG_START, camr*0.1f);
	glFogf(GL_FOG_END, camr*1.25f);
	glFogfv(GL_FOG_COLOR, fogCol);
	
	glDepthFunc(GL_LEQUAL);
	
	bool done = false;
	while(!done)
	{
		// Handle input events.
		int mscroll = 0;
		bool processHitTest = false;
		bool processHitTestShift = false;
		SDL_Event event;
		
		while (SDL_PollEvent(&event))
		{
			switch (event.type)
			{
				case SDL_KEYDOWN:
					// Handle any key presses here.
					if (event.key.keysym.sym == SDLK_ESCAPE)
					{
						done = true;
					}
					else if (event.key.keysym.sym == SDLK_t)
					{
						showLevels = false;
						showSample = false;
						showTestCases = true;
						scanDirectory("Tests", ".txt", files);
					}
					else if (event.key.keysym.sym == SDLK_TAB)
					{
						showMenu = !showMenu;
					}
					else if (event.key.keysym.sym == SDLK_SPACE)
					{
						if (sample)
							sample->handleToggle();
					}
					else if (event.key.keysym.sym == SDLK_1)
					{
						if (sample)
							sample->handleStep();
					}
					else if (event.key.keysym.sym == SDLK_9)
					{
						if (geom)
							geom->save("geomset.txt");
					}
					else if (event.key.keysym.sym == SDLK_0)
					{
						delete geom;
						geom = new InputGeom;
						if (!geom || !geom->load(&ctx, "geomset.txt"))
						{
							delete geom;
							geom = 0;
							
							showLog = true;
							logScroll = 0;
							ctx.dumpLog("Geom load log %s:", meshName);
						}
						if (sample && geom)
						{
							sample->handleMeshChanged(geom);
						}
							
						if (geom || sample)
						{
							const float* bmin = 0;
							const float* bmax = 0;
							if (sample)
							{
								bmin = sample->getBoundsMin();
								bmax = sample->getBoundsMax();
							}
							else if (geom)
							{
								bmin = geom->getMeshBoundsMin();
								bmax = geom->getMeshBoundsMax();
							}
							// Reset camera and fog to match the mesh bounds.
							if (bmin && bmax)
							{
								camr = sqrtf(rcSqr(bmax[0]-bmin[0]) +
											 rcSqr(bmax[1]-bmin[1]) +
											 rcSqr(bmax[2]-bmin[2])) / 2;
								camx = (bmax[0] + bmin[0]) / 2 + camr;
								camy = (bmax[1] + bmin[1]) / 2 + camr;
								camz = (bmax[2] + bmin[2]) / 2 + camr;
								camr *= 3;
							}
							rx = 45;
							ry = -45;
							glFogf(GL_FOG_START, camr*0.2f);
							glFogf(GL_FOG_END, camr*1.25f);
						}
					}
					else if (event.key.keysym.sym == SDLK_RIGHT)
					{
						slideShow.nextSlide();
					}
					else if (event.key.keysym.sym == SDLK_LEFT)
					{
						slideShow.prevSlide();
					}
					break;
					
				case SDL_MOUSEBUTTONDOWN:
					if (event.button.button == SDL_BUTTON_RIGHT)
					{
						if (!mouseOverMenu)
						{
							// Rotate view
							rotate = true;
							movedDuringRotate = false;
							origx = mx;
							origy = my;
							origrx = rx;
							origry = ry;
						}
					}	
					else if (event.button.button == SDL_BUTTON_WHEELUP)
					{
						if (mouseOverMenu)
							mscroll--;
						else
							scrollZoom -= 1.0f;
					}
					else if (event.button.button == SDL_BUTTON_WHEELDOWN)
					{
						if (mouseOverMenu)
							mscroll++;
						else
							scrollZoom += 1.0f;
					}
					break;
					
				case SDL_MOUSEBUTTONUP:
					// Handle mouse clicks here.
					if (event.button.button == SDL_BUTTON_RIGHT)
					{
						rotate = false;
						if (!mouseOverMenu)
						{
							if (!movedDuringRotate)
							{
								processHitTest = true;
								processHitTestShift = true;
							}
						}
					}
					else if (event.button.button == SDL_BUTTON_LEFT)
					{
						if (!mouseOverMenu)
						{
							processHitTest = true;
							processHitTestShift = (SDL_GetModState() & KMOD_SHIFT) ? true : false;
						}
					}
					
					break;
					
				case SDL_MOUSEMOTION:
					mx = event.motion.x;
					my = height-1 - event.motion.y;
					if (rotate)
					{
						int dx = mx - origx;
						int dy = my - origy;
						rx = origrx - dy*0.25f;
						ry = origry + dx*0.25f;
						if (dx*dx+dy*dy > 3*3)
							movedDuringRotate = true;
					}
					break;
					
				case SDL_QUIT:
					done = true;
					break;
					
				default:
					break;
			}
		}

		unsigned char mbut = 0;
		if (SDL_GetMouseState(0,0) & SDL_BUTTON_LMASK)
			mbut |= IMGUI_MBUT_LEFT;
		if (SDL_GetMouseState(0,0) & SDL_BUTTON_RMASK)
			mbut |= IMGUI_MBUT_RIGHT;
		
		Uint32	time = SDL_GetTicks();
		float	dt = (time - lastTime) / 1000.0f;
		lastTime = time;
		
		t += dt;


		// Hit test mesh.
		if (processHitTest && geom && sample)
		{
			float hitt;
			bool hit = geom->raycastMesh(rays, raye, hitt);
			
			if (hit)
			{
				if (SDL_GetModState() & KMOD_CTRL)
				{
					// Marker
					mposSet = true;
					mpos[0] = rays[0] + (raye[0] - rays[0])*hitt;
					mpos[1] = rays[1] + (raye[1] - rays[1])*hitt;
					mpos[2] = rays[2] + (raye[2] - rays[2])*hitt;
				}
				else
				{
					float pos[3];
					pos[0] = rays[0] + (raye[0] - rays[0])*hitt;
					pos[1] = rays[1] + (raye[1] - rays[1])*hitt;
					pos[2] = rays[2] + (raye[2] - rays[2])*hitt;
					sample->handleClick(rays, pos, processHitTestShift);
				}
			}
			else
			{
				if (SDL_GetModState() & KMOD_CTRL)
				{
					// Marker
					mposSet = false;
				}
			}
		}
		
		// Update sample simulation.
		const float SIM_RATE = 20;
		const float DELTA_TIME = 1.0f/SIM_RATE;
		timeAcc = rcClamp(timeAcc+dt, -1.0f, 1.0f);
		int simIter = 0;
		while (timeAcc > DELTA_TIME)
		{
			timeAcc -= DELTA_TIME;
			if (simIter < 5)
			{
				if (sample)
					sample->handleUpdate(DELTA_TIME);
			}
			simIter++;
		}

		// Clamp the framerate so that we do not hog all the CPU.
		const float MIN_FRAME_TIME = 1.0f/40.0f;
		if (dt < MIN_FRAME_TIME)
		{
			int ms = (int)((MIN_FRAME_TIME - dt)*1000.0f);
			if (ms > 10) ms = 10;
			if (ms >= 0)
				SDL_Delay(ms);
		}
		
		
		// Update and render
		glViewport(0, 0, width, height);
		glClearColor(0.3f, 0.3f, 0.32f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glDisable(GL_TEXTURE_2D);
		
		// Render 3d
		glEnable(GL_DEPTH_TEST);
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(50.0f, (float)width/(float)height, 1.0f, camr);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		glRotatef(rx,1,0,0);
		glRotatef(ry,0,1,0);
		glTranslatef(-camx, -camy, -camz);
		
		// Get hit ray position and direction.
		GLdouble proj[16];
		GLdouble model[16];
		GLint view[4];
		glGetDoublev(GL_PROJECTION_MATRIX, proj);
		glGetDoublev(GL_MODELVIEW_MATRIX, model);
		glGetIntegerv(GL_VIEWPORT, view);
		GLdouble x, y, z;
		gluUnProject(mx, my, 0.0f, model, proj, view, &x, &y, &z);
		rays[0] = (float)x; rays[1] = (float)y; rays[2] = (float)z;
		gluUnProject(mx, my, 1.0f, model, proj, view, &x, &y, &z);
		raye[0] = (float)x; raye[1] = (float)y; raye[2] = (float)z;
		
		// Handle keyboard movement.
		Uint8* keystate = SDL_GetKeyState(NULL);
		moveW = rcClamp(moveW + dt * 4 * (keystate[SDLK_w] ? 1 : -1), 0.0f, 1.0f);
		moveS = rcClamp(moveS + dt * 4 * (keystate[SDLK_s] ? 1 : -1), 0.0f, 1.0f);
		moveA = rcClamp(moveA + dt * 4 * (keystate[SDLK_a] ? 1 : -1), 0.0f, 1.0f);
		moveD = rcClamp(moveD + dt * 4 * (keystate[SDLK_d] ? 1 : -1), 0.0f, 1.0f);
		
		float keybSpeed = 22.0f;
		if (SDL_GetModState() & KMOD_SHIFT)
			keybSpeed *= 4.0f;
		
		float movex = (moveD - moveA) * keybSpeed * dt;
		float movey = (moveS - moveW) * keybSpeed * dt;
		
		movey += scrollZoom * 2.0f;
		scrollZoom = 0;
		
		camx += movex * (float)model[0];
		camy += movex * (float)model[4];
		camz += movex * (float)model[8];
		
		camx += movey * (float)model[2];
		camy += movey * (float)model[6];
		camz += movey * (float)model[10];

		glEnable(GL_FOG);

		if (sample)
			sample->handleRender();
		if (test)
			test->handleRender();
		
		glDisable(GL_FOG);
		
		// Render GUI
		glDisable(GL_DEPTH_TEST);
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluOrtho2D(0, width, 0, height);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		
		mouseOverMenu = false;
		
		imguiBeginFrame(mx,my,mbut,mscroll);
		
		if (sample)
		{
			sample->handleRenderOverlay((double*)proj, (double*)model, (int*)view);
		}
		if (test)
		{
			if (test->handleRenderOverlay((double*)proj, (double*)model, (int*)view))
				mouseOverMenu = true;
		}

		// Help text.
		if (showMenu)
		{
			const char msg[] = "W/S/A/D: Move  RMB: Rotate";
			imguiDrawText(280, height-20, IMGUI_ALIGN_LEFT, msg, imguiRGBA(255,255,255,128));
		}
		
		if (showMenu)
		{
			if (imguiBeginScrollArea("Properties", width-250-10, 10, 250, height-20, &propScroll))
				mouseOverMenu = true;

			if (imguiCheck("Show Log", showLog))
				showLog = !showLog;
			if (imguiCheck("Show Tools", showTools))
				showTools = !showTools;

			imguiSeparator();
			imguiLabel("Sample");
			if (imguiButton(sampleName))
			{
				if (showSample)
				{
					showSample = false;
				}
				else
				{
					showSample = true;
					showLevels = false;
					showTestCases = false;
				}
			}
			
			imguiSeparator();
			imguiLabel("Input Mesh");
			if (imguiButton(meshName))
			{
				if (showLevels)
				{
					showLevels = false;
				}
				else
				{
					showSample = false;
					showTestCases = false;
					showLevels = true;
					scanDirectory("Meshes", ".obj", files);
				}
			}
			if (geom)
			{
				char text[64];
				snprintf(text, 64, "Verts: %.1fk  Tris: %.1fk",
						 geom->getMesh()->getVertCount()/1000.0f,
						 geom->getMesh()->getTriCount()/1000.0f);
				imguiValue(text);
			}
			imguiSeparator();

			if (geom && sample)
			{
				imguiSeparatorLine();
				
				sample->handleSettings();

				if (imguiButton("Build"))
				{
					ctx.resetLog();
					if (!sample->handleBuild())
					{
						showLog = true;
						logScroll = 0;
					}
					ctx.dumpLog("Build log %s:", meshName);
					
					// Clear test.
					delete test;
					test = 0;
				}

				imguiSeparator();
			}
			
			if (sample)
			{
				imguiSeparatorLine();
				sample->handleDebugMode();
			}

			imguiEndScrollArea();
		}
		
		// Sample selection dialog.
		if (showSample)
		{
			static int levelScroll = 0;
			if (imguiBeginScrollArea("Choose Sample", width-10-250-10-200, height-10-250, 200, 250, &levelScroll))
				mouseOverMenu = true;

			Sample* newSample = 0;
			for (int i = 0; i < g_nsamples; ++i)
			{
				if (imguiItem(g_samples[i].name))
				{
					newSample = g_samples[i].create();
					if (newSample)
						strcpy(sampleName, g_samples[i].name);
				}
			}
			if (newSample)
			{
				delete sample;
				sample = newSample;
				sample->setContext(&ctx);
				if (geom && sample)
				{
					sample->handleMeshChanged(geom);
				}
				showSample = false;
			}

			if (geom || sample)
			{
				const float* bmin = 0;
				const float* bmax = 0;
				if (sample)
				{
					bmin = sample->getBoundsMin();
					bmax = sample->getBoundsMax();
				}
				else if (geom)
				{
					bmin = geom->getMeshBoundsMin();
					bmax = geom->getMeshBoundsMax();
				}
				// Reset camera and fog to match the mesh bounds.
				if (bmin && bmax)
				{
					camr = sqrtf(rcSqr(bmax[0]-bmin[0]) +
								 rcSqr(bmax[1]-bmin[1]) +
								 rcSqr(bmax[2]-bmin[2])) / 2;
					camx = (bmax[0] + bmin[0]) / 2 + camr;
					camy = (bmax[1] + bmin[1]) / 2 + camr;
					camz = (bmax[2] + bmin[2]) / 2 + camr;
					camr *= 3;
				}
				rx = 45;
				ry = -45;
				glFogf(GL_FOG_START, camr*0.1f);
				glFogf(GL_FOG_END, camr*1.25f);
			}
			
			imguiEndScrollArea();
		}
		
		// Level selection dialog.
		if (showLevels)
		{
			static int levelScroll = 0;
			if (imguiBeginScrollArea("Choose Level", width-10-250-10-200, height-10-450, 200, 450, &levelScroll))
				mouseOverMenu = true;
			
			int levelToLoad = -1;
			for (int i = 0; i < files.size; ++i)
			{
				if (imguiItem(files.files[i]))
					levelToLoad = i;
			}
			
			if (levelToLoad != -1)
			{
				strncpy(meshName, files.files[levelToLoad], sizeof(meshName));
				meshName[sizeof(meshName)-1] = '\0';
				showLevels = false;
				
				delete geom;
				geom = 0;
				
				char path[256];
				strcpy(path, "Meshes/");
				strcat(path, meshName);
				
				geom = new InputGeom;
				if (!geom || !geom->loadMesh(&ctx, path))
				{
					delete geom;
					geom = 0;
					
					showLog = true;
					logScroll = 0;
					ctx.dumpLog("Geom load log %s:", meshName);
				}
				if (sample && geom)
				{
					sample->handleMeshChanged(geom);
				}

				if (geom || sample)
				{
					const float* bmin = 0;
					const float* bmax = 0;
					if (sample)
					{
						bmin = sample->getBoundsMin();
						bmax = sample->getBoundsMax();
					}
					else if (geom)
					{
						bmin = geom->getMeshBoundsMin();
						bmax = geom->getMeshBoundsMax();
					}
					// Reset camera and fog to match the mesh bounds.
					if (bmin && bmax)
					{
						camr = sqrtf(rcSqr(bmax[0]-bmin[0]) +
									 rcSqr(bmax[1]-bmin[1]) +
									 rcSqr(bmax[2]-bmin[2])) / 2;
						camx = (bmax[0] + bmin[0]) / 2 + camr;
						camy = (bmax[1] + bmin[1]) / 2 + camr;
						camz = (bmax[2] + bmin[2]) / 2 + camr;
						camr *= 3;
					}
					rx = 45;
					ry = -45;
					glFogf(GL_FOG_START, camr*0.1f);
					glFogf(GL_FOG_END, camr*1.25f);
				}
			}
			
			imguiEndScrollArea();
			
		}
		
		// Test cases
		if (showTestCases)
		{
			static int testScroll = 0;
			if (imguiBeginScrollArea("Choose Test To Run", width-10-250-10-200, height-10-450, 200, 450, &testScroll))
				mouseOverMenu = true;

			int testToLoad = -1;
			for (int i = 0; i < files.size; ++i)
			{
				if (imguiItem(files.files[i]))
					testToLoad = i;
			}
			
			if (testToLoad != -1)
			{
				char path[256];
				strcpy(path, "Tests/");
				strcat(path, files.files[testToLoad]);
				test = new TestCase;
				if (test)
				{
					// Load the test.
					if (!test->load(path))
					{
						delete test;
						test = 0;
					}

					// Create sample
					Sample* newSample = 0;
					for (int i = 0; i < g_nsamples; ++i)
					{
						if (strcmp(g_samples[i].name, test->getSampleName()) == 0)
						{
							newSample = g_samples[i].create();
							if (newSample) strcpy(sampleName, g_samples[i].name);
						}
					}
					if (newSample)
					{
						delete sample;
						sample = newSample;
						sample->setContext(&ctx);
						showSample = false;
					}

					// Load geom.
					strcpy(meshName, test->getGeomFileName());
					meshName[sizeof(meshName)-1] = '\0';
					
					delete geom;
					geom = 0;
					
					strcpy(path, "Meshes/");
					strcat(path, meshName);
					
					geom = new InputGeom;
					if (!geom || !geom->loadMesh(&ctx, path))
					{
						delete geom;
						geom = 0;
						showLog = true;
						logScroll = 0;
						ctx.dumpLog("Geom load log %s:", meshName);
					}
					if (sample && geom)
					{
						sample->handleMeshChanged(geom);
					}

					// This will ensure that tile & poly bits are updated in tiled sample.
					if (sample)
						sample->handleSettings();

					ctx.resetLog();
					if (sample && !sample->handleBuild())
					{
						ctx.dumpLog("Build log %s:", meshName);
					}
					
					if (geom || sample)
					{
						const float* bmin = 0;
						const float* bmax = 0;
						if (sample)
						{
							bmin = sample->getBoundsMin();
							bmax = sample->getBoundsMax();
						}
						else if (geom)
						{
							bmin = geom->getMeshBoundsMin();
							bmax = geom->getMeshBoundsMax();
						}
						// Reset camera and fog to match the mesh bounds.
						if (bmin && bmax)
						{
							camr = sqrtf(rcSqr(bmax[0]-bmin[0]) +
										 rcSqr(bmax[1]-bmin[1]) +
										 rcSqr(bmax[2]-bmin[2])) / 2;
							camx = (bmax[0] + bmin[0]) / 2 + camr;
							camy = (bmax[1] + bmin[1]) / 2 + camr;
							camz = (bmax[2] + bmin[2]) / 2 + camr;
							camr *= 3;
						}
						rx = 45;
						ry = -45;
						glFogf(GL_FOG_START, camr*0.2f);
						glFogf(GL_FOG_END, camr*1.25f);
					}
					
					// Do the tests.
					if (sample)
						test->doTests(sample->getNavMesh(), sample->getNavMeshQuery());
				}
			}				
				
			imguiEndScrollArea();
		}

		
		// Log
		if (showLog && showMenu)
		{
			if (imguiBeginScrollArea("Log", 250+20, 10, width - 300 - 250, 200, &logScroll))
				mouseOverMenu = true;
			for (int i = 0; i < ctx.getLogCount(); ++i)
				imguiLabel(ctx.getLogText(i));
			imguiEndScrollArea();
		}
		
		// Tools
		if (!showTestCases && showTools && showMenu) // && geom && sample)
		{
			if (imguiBeginScrollArea("Tools", 10, 10, 250, height-20, &toolsScroll))
				mouseOverMenu = true;

			if (sample)
				sample->handleTools();
			
			imguiEndScrollArea();
		}
		
		slideShow.updateAndDraw(dt, (float)width, (float)height);
		
		// Marker
		if (mposSet && gluProject((GLdouble)mpos[0], (GLdouble)mpos[1], (GLdouble)mpos[2],
								  model, proj, view, &x, &y, &z))
		{
			// Draw marker circle
			glLineWidth(5.0f);
			glColor4ub(240,220,0,196);
			glBegin(GL_LINE_LOOP);
			const float r = 25.0f;
			for (int i = 0; i < 20; ++i)
			{
				const float a = (float)i / 20.0f * RC_PI*2;
				const float fx = (float)x + cosf(a)*r;
				const float fy = (float)y + sinf(a)*r;
				glVertex2f(fx,fy);
			}
			glEnd();
			glLineWidth(1.0f);
		}
		
		imguiEndFrame();
		imguiRenderGLDraw();		
		
		glEnable(GL_DEPTH_TEST);
		SDL_GL_SwapBuffers();
	}
	
	imguiRenderGLDestroy();
	
	SDL_Quit();
	
	delete sample;
	delete geom;
	
	return 0;
}
Example #17
0
BX_NO_INLINE bool mainloop()
{
	if (!entry::processEvents(width, height, debug, reset, &mouseState) )
	{
		int64_t now = bx::getHPCounter();
		static int64_t last = now;
		const int64_t hpFreq = bx::getHPFrequency();
		const int64_t frameTime = now - last;
		last = now;
		const double freq = double(hpFreq);
		const double toMs = 1000.0/freq;

		deltaTimeNs += frameTime*1000000/hpFreq;

		if (deltaTimeNs > 1000000)
		{
			deltaTimeAvgNs = deltaTimeNs / bx::int64_max(1, numFrames);

			if (autoAdjust)
			{
				if (deltaTimeAvgNs < highwm)
				{
					dim = bx::uint32_min(dim + 2, 40);
				}
				else if (deltaTimeAvgNs > lowwm)
				{
					dim = bx::uint32_max(dim - 1, 2);
				}
			}

			deltaTimeNs = 0;
			numFrames = 0;
		}
		else
		{
			++numFrames;
		}

		float time = (float)( (now-timeOffset)/freq);

		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();

		transform = imguiChoose(transform
				, "Rotate"
				, "No fragments"
				);
		imguiSeparatorLine();

		if (imguiCheck("Auto adjust", autoAdjust) )
		{
			autoAdjust ^= true;
		}

		imguiSlider("Dim", dim, 5, 40);
		imguiLabel("Draw calls: %d", dim*dim*dim);
		imguiLabel("Avg Delta Time (1 second) [ms]: %0.4f", deltaTimeAvgNs/1000.0f);

		imguiEndScrollArea();
		imguiEndFrame();

		float at[3] = { 0.0f, 0.0f, 0.0f };
		float eye[3] = { 0.0f, 0.0f, -35.0f };

		float view[16];
		float proj[16];
		bx::mtxLookAt(view, eye, at);
		bx::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);

		// 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);

		// Use debug font to print information about this example.
		bgfx::dbgTextClear();
		bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/17-drawstress");
		bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Draw stress, maximizing number of draw calls.");
		bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: %7.3f[ms]", double(frameTime)*toMs);

		float mtxS[16];
		const float scale = 0 == transform ? 0.25f : 0.0f;
		bx::mtxScale(mtxS, scale, scale, scale);

		const float step = 0.6f;
		float pos[3];
		pos[0] = -step*dim / 2.0f;
		pos[1] = -step*dim / 2.0f;
		pos[2] = -15.0;

		for (uint32_t zz = 0; zz < uint32_t(dim); ++zz)
		{
			for (uint32_t yy = 0; yy < uint32_t(dim); ++yy)
			{
				for (uint32_t xx = 0; xx < uint32_t(dim); ++xx)
				{
					float mtxR[16];
					bx::mtxRotateXYZ(mtxR, time + xx*0.21f, time + yy*0.37f, time + yy*0.13f);

					float mtx[16];
					bx::mtxMul(mtx, mtxS, mtxR);

					mtx[12] = pos[0] + float(xx)*step;
					mtx[13] = pos[1] + float(yy)*step;
					mtx[14] = pos[2] + float(zz)*step;

					// 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);

					// 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();

		return false;
	}

	return true;
}
Example #18
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);

	const bgfx::RendererType::Enum renderer = bgfx::getRendererType();
	s_texelHalf = bgfx::RendererType::Direct3D9 == renderer ? 0.5f : 0.0f;
	s_originBottomLeft = bgfx::RendererType::OpenGL == renderer || bgfx::RendererType::OpenGLES == renderer;

	uint32_t oldWidth  = 0;
	uint32_t oldHeight = 0;
	uint32_t oldReset  = reset;
 
	float speed      = 0.37f;
	float middleGray = 0.18f;
	float white      = 1.1f;
	float treshold   = 1.5f;

	int32_t scrollArea = 0;

	float time = 0.0f;

	entry::MouseState mouseState;
	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.
		for (uint32_t ii = 0; ii < 6; ++ii)
		{
			bgfx::setViewRect(ii, 0, 0, width, height);
		}
		bgfx::setViewFrameBuffer(0, fbh);
		bgfx::setViewFrameBuffer(1, 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];

		bx::mtxIdentity(view);
		bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f);

		// Set view and projection matrix for view 0.
		for (uint32_t ii = 0; ii < 10; ++ii)
		{
			bgfx::setViewTransform(ii, view, proj);
		}

		float at[3] = { 0.0f, 1.0f, 0.0f };
		float eye[3] = { 0.0f, 1.0f, -2.5f };

		float mtx[16];
		bx::mtxRotateXY(mtx
			, 0.0f
			, time
			); 

		float temp[4];
		bx::vec3MulMtx(temp, eye, mtx);

		bx::mtxLookAt(view, temp, at);
		bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f);

		// Set view and projection matrix for view 1.
		bgfx::setViewTransform(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_originBottomLeft);
		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_originBottomLeft);
		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_originBottomLeft);
		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_originBottomLeft);
		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_originBottomLeft);
		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_originBottomLeft);
		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_originBottomLeft);
		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_originBottomLeft);
		bgfx::submit(9);

		// Advance to next frame. Rendering thread will be kicked to 
		// process submitted rendering primitives.
		bgfx::frame();
	}
Example #19
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|BGFX_CLEAR_DEPTH
		, 0x303030ff
		, 1.0f
		, 0
		);

	const bgfx::Caps* caps = bgfx::getCaps();
	const bool computeSupported  = !!(caps->supported & BGFX_CAPS_COMPUTE);
	const bool indirectSupported = !!(caps->supported & BGFX_CAPS_DRAW_INDIRECT);

	if (computeSupported)
	{
		// Imgui.
		imguiCreate();

		bgfx::VertexDecl quadVertexDecl;
		quadVertexDecl.begin()
			.add(bgfx::Attrib::Position, 2, bgfx::AttribType::Float)
			.end();

		// Create static vertex buffer.
		bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer(
				// Static data can be passed with bgfx::makeRef
				bgfx::makeRef(s_quadVertices, sizeof(s_quadVertices) )
				, quadVertexDecl
				);

		// Create static index buffer.
		bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(
				// Static data can be passed with bgfx::makeRef
				bgfx::makeRef(s_quadIndices, sizeof(s_quadIndices) )
				);

		// Create particle program from shaders.
		bgfx::ProgramHandle particleProgram = loadProgram("vs_particle", "fs_particle");

		// Setup compute buffers
		bgfx::VertexDecl computeVertexDecl;
		computeVertexDecl.begin()
			.add(bgfx::Attrib::TexCoord0, 4, bgfx::AttribType::Float)
			.end();

		const uint32_t threadGroupUpdateSize = 512;
		const uint32_t maxParticleCount = 32 * 1024;

		bgfx::DynamicVertexBufferHandle currPositionBuffer0 = bgfx::createDynamicVertexBuffer(1 << 15, computeVertexDecl, BGFX_BUFFER_COMPUTE_READ_WRITE);
		bgfx::DynamicVertexBufferHandle currPositionBuffer1 = bgfx::createDynamicVertexBuffer(1 << 15, computeVertexDecl, BGFX_BUFFER_COMPUTE_READ_WRITE);
		bgfx::DynamicVertexBufferHandle prevPositionBuffer0 = bgfx::createDynamicVertexBuffer(1 << 15, computeVertexDecl, BGFX_BUFFER_COMPUTE_READ_WRITE);
		bgfx::DynamicVertexBufferHandle prevPositionBuffer1 = bgfx::createDynamicVertexBuffer(1 << 15, computeVertexDecl, BGFX_BUFFER_COMPUTE_READ_WRITE);

		bgfx::UniformHandle u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4, 3);

		bgfx::ProgramHandle initInstancesProgram   = bgfx::createProgram(loadShader("cs_init_instances"), true);
		bgfx::ProgramHandle updateInstancesProgram = bgfx::createProgram(loadShader("cs_update_instances"), true);

		bgfx::ProgramHandle indirectProgram       = BGFX_INVALID_HANDLE;
		bgfx::IndirectBufferHandle indirectBuffer = BGFX_INVALID_HANDLE;

		if (indirectSupported)
		{
			indirectProgram = bgfx::createProgram(loadShader("cs_indirect"), true);
			indirectBuffer  = bgfx::createIndirectBuffer(2);
		}

		u_paramsDataStruct u_paramsData;
		InitializeParams(0, &u_paramsData);

		bgfx::setUniform(u_params, &u_paramsData, 3);
		bgfx::setBuffer(0, prevPositionBuffer0, bgfx::Access::Write);
		bgfx::setBuffer(1, currPositionBuffer0, bgfx::Access::Write);
		bgfx::dispatch(0, initInstancesProgram, maxParticleCount / threadGroupUpdateSize, 1, 1);

		float view[16];
		float initialPos[3] = { 0.0f, 0.0f, -45.0f };
		cameraCreate();
		cameraSetPosition(initialPos);
		cameraSetVerticalAngle(0.0f);
		cameraGetViewMtx(view);

		int32_t scrollArea = 0;

		bool useIndirect = false;

		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 float deltaTime = float(frameTime/freq);

			if (deltaTime > 1000.0)
			{
				abort();
			}

			// Set view 0 default viewport.
			bgfx::setViewRect(0, 0, 0, width, height);

			// Use debug font to print information about this example.
			bgfx::dbgTextClear();
			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/24-nbody");
			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: N-body simulation with compute shaders using buffers.");

			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)
					, mouseState.m_mz
					, width
					, height
					);
			imguiBeginScrollArea("Settings", width - width / 4 - 10, 10, width / 4, 500, &scrollArea);
			imguiSlider("Random seed", u_paramsData.baseSeed, 0, 100);
			int32_t shape = imguiChoose(u_paramsData.initialShape, "Point", "Sphere", "Box", "Donut");
			imguiSlider("Initial speed", u_paramsData.initialSpeed, 0.0f, 300.0f, 0.1f);
			bool defaults = imguiButton("Reset");
			imguiSeparatorLine();
			imguiSlider("Particle count (x512)", u_paramsData.dispatchSize, 1, 64);
			imguiSlider("Gravity", u_paramsData.gravity, 0.0f, 0.3f, 0.001f);
			imguiSlider("Damping", u_paramsData.damping, 0.0f, 1.0f, 0.01f);
			imguiSlider("Max acceleration", u_paramsData.maxAccel, 0.0f, 100.0f, 0.01f);
			imguiSlider("Time step", u_paramsData.timeStep, 0.0f, 0.02f, 0.0001f);
			imguiSeparatorLine();
			imguiSlider("Particle intensity", u_paramsData.particleIntensity, 0.0f, 1.0f, 0.001f);
			imguiSlider("Particle size", u_paramsData.particleSize, 0.0f, 1.0f, 0.001f);
			imguiSlider("Particle power", u_paramsData.particlePower, 0.001f, 16.0f, 0.01f);
			imguiSeparatorLine();
			if (imguiCheck("Use draw/dispatch indirect", useIndirect, indirectSupported) )
			{
				useIndirect = !useIndirect;
			}
			imguiEndScrollArea();
			imguiEndFrame();

			// Modify parameters and reset if shape is changed
			if (shape != u_paramsData.initialShape)
			{
				defaults = true;
				InitializeParams(shape, &u_paramsData);
			}

			if (defaults)
			{
				bgfx::setBuffer(0, prevPositionBuffer0, bgfx::Access::Write);
				bgfx::setBuffer(1, currPositionBuffer0, bgfx::Access::Write);
				bgfx::setUniform(u_params, &u_paramsData, 3);
				bgfx::dispatch(0, initInstancesProgram, maxParticleCount / threadGroupUpdateSize, 1, 1);
			}

			if (useIndirect)
			{
				bgfx::setUniform(u_params, &u_paramsData, 3);
				bgfx::setBuffer(0, indirectBuffer, bgfx::Access::Write);
				bgfx::dispatch(0, indirectProgram);
			}

			bgfx::setBuffer(0, prevPositionBuffer0, bgfx::Access::Read);
			bgfx::setBuffer(1, currPositionBuffer0, bgfx::Access::Read);
			bgfx::setBuffer(2, prevPositionBuffer1, bgfx::Access::Write);
			bgfx::setBuffer(3, currPositionBuffer1, bgfx::Access::Write);
			bgfx::setUniform(u_params, &u_paramsData, 3);

			if (useIndirect)
			{
				bgfx::dispatch(0, updateInstancesProgram, indirectBuffer, 1);
			}
			else
			{
				bgfx::dispatch(0, updateInstancesProgram, u_paramsData.dispatchSize, 1, 1);
			}

			bx::xchg(currPositionBuffer0, currPositionBuffer1);
			bx::xchg(prevPositionBuffer0, prevPositionBuffer1);

			// Update camera.
			cameraUpdate(deltaTime, mouseState);
			cameraGetViewMtx(view);

			// Set view and projection matrix for view 0.
			const bgfx::HMD* hmd = bgfx::getHMD();
			if (NULL != hmd && 0 != (hmd->flags & BGFX_HMD_RENDERING) )
			{
				float viewHead[16];
				float eye[3] = {};
				bx::mtxQuatTranslationHMD(viewHead, hmd->eye[0].rotation, eye);

				float tmp[16];
				bx::mtxMul(tmp, view, viewHead);

				float proj[16];
				bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 10000.0f);

				bgfx::setViewTransform(0, tmp, proj);

				// Set view 0 default viewport.
				//
				// Use HMD's width/height since HMD's internal frame buffer size
				// might be much larger than window size.
				bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height);
			}
			else
			{
				float proj[16];
				bx::mtxProj(proj, 90.0f, float(width)/float(height), 0.1f, 10000.0f);
				bgfx::setViewTransform(0, view, proj);

				// Set view 0 default viewport.
				bgfx::setViewRect(0, 0, 0, width, height);
			}

			// Set vertex and index buffer.
			bgfx::setVertexBuffer(vbh);
			bgfx::setIndexBuffer(ibh);
			bgfx::setInstanceDataBuffer(currPositionBuffer0, 0, u_paramsData.dispatchSize * threadGroupUpdateSize);

			// Set render states.
			bgfx::setState(0
					| BGFX_STATE_RGB_WRITE
					| BGFX_STATE_BLEND_ADD
					| BGFX_STATE_DEPTH_TEST_ALWAYS
					);

			// Submit primitive for rendering to view 0.
			if (useIndirect)
			{
				bgfx::submit(0, particleProgram, indirectBuffer, 0);
			}
			else
			{
				bgfx::submit(0, particleProgram);
			}

			// Advance to next frame. Rendering thread will be kicked to
			// process submitted rendering primitives.
			bgfx::frame();
		}

		// Cleanup.
		cameraDestroy();
		imguiDestroy();

		if (indirectSupported)
		{
			bgfx::destroyProgram(indirectProgram);
			bgfx::destroyIndirectBuffer(indirectBuffer);
		}


		bgfx::destroyUniform(u_params);
		bgfx::destroyDynamicVertexBuffer(currPositionBuffer0);
		bgfx::destroyDynamicVertexBuffer(currPositionBuffer1);
		bgfx::destroyDynamicVertexBuffer(prevPositionBuffer0);
		bgfx::destroyDynamicVertexBuffer(prevPositionBuffer1);
		bgfx::destroyProgram(updateInstancesProgram);
		bgfx::destroyProgram(initInstancesProgram);
		bgfx::destroyIndexBuffer(ibh);
		bgfx::destroyVertexBuffer(vbh);
		bgfx::destroyProgram(particleProgram);
	}
	else
	{
		int64_t timeOffset = bx::getHPCounter();

		entry::MouseState mouseState;
		while (!entry::processEvents(width, height, debug, reset, &mouseState) )
		{
			int64_t now = bx::getHPCounter();
			float time = (float)( (now - timeOffset)/double(bx::getHPFrequency() ) );

			bgfx::setViewRect(0, 0, 0, width, height);

			bgfx::dbgTextClear();
			bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/24-nbody");
			bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: N-body simulation with compute shaders using buffers.");

			bool blink = uint32_t(time*3.0f)&1;
			bgfx::dbgTextPrintf(0, 5, blink ? 0x1f : 0x01, " Compute is not supported by GPU. ");

			bgfx::touch(0);
			bgfx::frame();
		}
	}

	// Shutdown bgfx.
	bgfx::shutdown();

	return 0;
}