Esempio n. 1
0
    void submit(bgfx::ProgramHandle _program, float* _mtx, bool _blend)
    {
        for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it)
        {
            const Group& group = *it;

            // Set model matrix for rendering.
            bgfx::setTransform(_mtx);
            bgfx::setProgram(_program);
            bgfx::setIndexBuffer(group.m_ibh);
            bgfx::setVertexBuffer(group.m_vbh);

            // Set render states.
            bgfx::setState(0
                           |BGFX_STATE_RGB_WRITE
                           |BGFX_STATE_ALPHA_WRITE
                           |(_blend?0:BGFX_STATE_DEPTH_WRITE)
                           |BGFX_STATE_DEPTH_TEST_LESS
                           |BGFX_STATE_CULL_CCW
                           |BGFX_STATE_MSAA
                           |(_blend?BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA):0)
                          );

            // Submit primitive for rendering to view 0.
            bgfx::submit(0);
        }
    }
Esempio n. 2
0
	void render(ImDrawData* _drawData)
	{
		const ImGuiIO& io = ImGui::GetIO();
		const float width  = io.DisplaySize.x;
		const float height = io.DisplaySize.y;

		bgfx::setViewName(m_viewId, "ImGui");
		bgfx::setViewMode(m_viewId, bgfx::ViewMode::Sequential);

		const bgfx::HMD*  hmd  = bgfx::getHMD();
		const bgfx::Caps* caps = bgfx::getCaps();
		if (NULL != hmd && 0 != (hmd->flags & BGFX_HMD_RENDERING) )
		{
			float proj[16];
			bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f, bgfx::getCaps()->homogeneousDepth);

			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], viewOffset, viewOffset + viewWidth, height, 0.0f, 0.0f, 1000.0f, offset0, caps->homogeneousDepth);
			bx::mtxOrtho(ortho[1], viewOffset, viewOffset + viewWidth, height, 0.0f, 0.0f, 1000.0f, offset1, caps->homogeneousDepth);
			bgfx::setViewTransform(m_viewId, NULL, ortho[0], BGFX_VIEW_STEREO, ortho[1]);
			bgfx::setViewRect(m_viewId, 0, 0, hmd->width, hmd->height);
		}
		else
		{
			float ortho[16];
			bx::mtxOrtho(ortho, 0.0f, width, height, 0.0f, 0.0f, 1000.0f, 0.0f, caps->homogeneousDepth);
			bgfx::setViewTransform(m_viewId, NULL, ortho);
			bgfx::setViewRect(m_viewId, 0, 0, uint16_t(width), uint16_t(height) );
		}

		// Render command lists
		for (int32_t ii = 0, num = _drawData->CmdListsCount; ii < num; ++ii)
		{
			bgfx::TransientVertexBuffer tvb;
			bgfx::TransientIndexBuffer tib;

			const ImDrawList* drawList = _drawData->CmdLists[ii];
			uint32_t numVertices = (uint32_t)drawList->VtxBuffer.size();
			uint32_t numIndices  = (uint32_t)drawList->IdxBuffer.size();

			if (!checkAvailTransientBuffers(numVertices, m_decl, numIndices) )
			{
				// not enough space in transient buffer just quit drawing the rest...
				break;
			}

			bgfx::allocTransientVertexBuffer(&tvb, numVertices, m_decl);
			bgfx::allocTransientIndexBuffer(&tib, numIndices);

			ImDrawVert* verts = (ImDrawVert*)tvb.data;
			bx::memCopy(verts, drawList->VtxBuffer.begin(), numVertices * sizeof(ImDrawVert) );

			ImDrawIdx* indices = (ImDrawIdx*)tib.data;
			bx::memCopy(indices, drawList->IdxBuffer.begin(), numIndices * sizeof(ImDrawIdx) );

			uint32_t offset = 0;
			for (const ImDrawCmd* cmd = drawList->CmdBuffer.begin(), *cmdEnd = drawList->CmdBuffer.end(); cmd != cmdEnd; ++cmd)
			{
				if (cmd->UserCallback)
				{
					cmd->UserCallback(drawList, cmd);
				}
				else if (0 != cmd->ElemCount)
				{
					uint64_t state = 0
						| BGFX_STATE_RGB_WRITE
						| BGFX_STATE_ALPHA_WRITE
						| BGFX_STATE_MSAA
						;

					bgfx::TextureHandle th = m_texture;
					bgfx::ProgramHandle program = m_program;

					if (NULL != cmd->TextureId)
					{
						union { ImTextureID ptr; struct { bgfx::TextureHandle handle; uint8_t flags; uint8_t mip; } s; } texture = { cmd->TextureId };
						state |= 0 != (IMGUI_FLAGS_ALPHA_BLEND & texture.s.flags)
							? BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA)
							: BGFX_STATE_NONE
							;
						th = texture.s.handle;
						if (0 != texture.s.mip)
						{
							const float lodEnabled[4] = { float(texture.s.mip), 1.0f, 0.0f, 0.0f };
							bgfx::setUniform(u_imageLodEnabled, lodEnabled);
							program = m_imageProgram;
						}
					}
					else
					{
						state |= BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA);
					}

					const uint16_t xx = uint16_t(bx::fmax(cmd->ClipRect.x, 0.0f) );
					const uint16_t yy = uint16_t(bx::fmax(cmd->ClipRect.y, 0.0f) );
					bgfx::setScissor(xx, yy
							, uint16_t(bx::fmin(cmd->ClipRect.z, 65535.0f)-xx)
							, uint16_t(bx::fmin(cmd->ClipRect.w, 65535.0f)-yy)
							);

					bgfx::setState(state);
					bgfx::setTexture(0, s_tex, th);
					bgfx::setVertexBuffer(0, &tvb, 0, numVertices);
					bgfx::setIndexBuffer(&tib, offset, cmd->ElemCount);
					bgfx::submit(cmd->ViewId, program);
				}

				offset += cmd->ElemCount;
			}
		}
	}
Esempio n. 3
0
	void render(ImDrawData* draw_data)
	{
		const float width  = ImGui::GetIO().DisplaySize.x;
		const float height = ImGui::GetIO().DisplaySize.y;

		float ortho[16];
		bx::mtxOrtho(ortho, 0.0f, width, height, 0.0f, -1.0f, 1.0f);

		bgfx::setViewTransform(m_viewId, NULL, ortho);

		// Render command lists
		for (int32_t ii = 0; ii < draw_data->CmdListsCount; ++ii)
		{
			bgfx::TransientVertexBuffer tvb;
			bgfx::TransientIndexBuffer tib;

			const ImDrawList* cmd_list   = draw_data->CmdLists[ii];
			uint32_t vtx_size = (uint32_t)cmd_list->VtxBuffer.size();
			uint32_t idx_size = (uint32_t)cmd_list->IdxBuffer.size();

			if (!bgfx::checkAvailTransientVertexBuffer(vtx_size, m_decl) || !bgfx::checkAvailTransientIndexBuffer(idx_size) )
			{
				// not enough space in transient buffer just quit drawing the rest...
				break;
			}

			bgfx::allocTransientVertexBuffer(&tvb, vtx_size, m_decl);
			bgfx::allocTransientIndexBuffer(&tib, idx_size);

			ImDrawVert* verts = (ImDrawVert*)tvb.data;
			memcpy(verts, cmd_list->VtxBuffer.begin(), vtx_size * sizeof(ImDrawVert) );

			ImDrawIdx* indices = (ImDrawIdx*)tib.data;
			memcpy(indices, cmd_list->IdxBuffer.begin(), idx_size * sizeof(ImDrawIdx) );

			uint32_t elem_offset = 0;
			const ImDrawCmd* pcmd_begin = cmd_list->CmdBuffer.begin();
			const ImDrawCmd* pcmd_end   = cmd_list->CmdBuffer.end();
			for (const ImDrawCmd* pcmd = pcmd_begin; pcmd != pcmd_end; pcmd++)
			{
				if (pcmd->UserCallback)
				{
					pcmd->UserCallback(cmd_list, pcmd);
					elem_offset += pcmd->ElemCount;
					continue;
				}
				if (0 == pcmd->ElemCount)
				{
					continue;
				}

				bgfx::setState(0
					| BGFX_STATE_RGB_WRITE
					| BGFX_STATE_ALPHA_WRITE
					| BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA)
					| BGFX_STATE_MSAA
					);
				bgfx::setScissor(uint16_t(bx::fmax(pcmd->ClipRect.x, 0.0f) )
					, uint16_t(bx::fmax(pcmd->ClipRect.y, 0.0f) )
					, uint16_t(bx::fmin(pcmd->ClipRect.z, 65535.0f)-bx::fmax(pcmd->ClipRect.x, 0.0f) )
					, uint16_t(bx::fmin(pcmd->ClipRect.w, 65535.0f)-bx::fmax(pcmd->ClipRect.y, 0.0f) )
					);
				union { void* ptr; bgfx::TextureHandle handle; } texture = { pcmd->TextureId };

				bgfx::setTexture(0, s_tex, 0 != texture.handle.idx
					? texture.handle
					: m_texture
					);

				bgfx::setVertexBuffer(&tvb, 0, vtx_size);
				bgfx::setIndexBuffer(&tib, elem_offset, pcmd->ElemCount);
				bgfx::setProgram(m_program);
				bgfx::submit(m_viewId);

				elem_offset += pcmd->ElemCount;
			}
		}
	}
Esempio n. 4
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;
}
Esempio n. 5
0
	void render(ImDrawData* _drawData)
	{
		const ImGuiIO& io = ImGui::GetIO();
		const float width  = io.DisplaySize.x;
		const float height = io.DisplaySize.y;

		{
			float ortho[16];
			bx::mtxOrtho(ortho, 0.0f, width, height, 0.0f, -1.0f, 1.0f);
			bgfx::setViewTransform(m_viewId, NULL, ortho);
		}

#if USE_ENTRY
		for (uint32_t ii = 1; ii < BX_COUNTOF(m_window); ++ii)
		{
			Window& window = m_window[ii];
			if (bgfx::isValid(window.m_fbh) )
			{
				const uint8_t viewId = window.m_viewId;
				bgfx::setViewClear(viewId
					, BGFX_CLEAR_COLOR|BGFX_CLEAR_DEPTH
					, 0x303030ff
					, 1.0f
					, 0
					);
				bgfx::setViewFrameBuffer(viewId, window.m_fbh);
				bgfx::setViewRect(viewId
					, 0
					, 0
					, window.m_state.m_width
					, window.m_state.m_height
					);
				float ortho[16];
				bx::mtxOrtho(ortho
					, 0.0f
					, float(window.m_state.m_width)
					, float(window.m_state.m_height)
					, 0.0f
					, -1.0f
					, 1.0f
					);
				bgfx::setViewTransform(viewId
					, NULL
					, ortho
					);
			}
		}
#endif // USE_ENTRY

		// Render command lists
		for (int32_t ii = 0, num = _drawData->CmdListsCount; ii < num; ++ii)
		{
			bgfx::TransientVertexBuffer tvb;
			bgfx::TransientIndexBuffer tib;

			const ImDrawList* drawList = _drawData->CmdLists[ii];
			uint32_t numVertices = (uint32_t)drawList->VtxBuffer.size();
			uint32_t numIndices  = (uint32_t)drawList->IdxBuffer.size();

			if (!bgfx::checkAvailTransientVertexBuffer(numVertices, m_decl)
			||  !bgfx::checkAvailTransientIndexBuffer(numIndices) )
			{
				// not enough space in transient buffer just quit drawing the rest...
				break;
			}

			bgfx::allocTransientVertexBuffer(&tvb, numVertices, m_decl);
			bgfx::allocTransientIndexBuffer(&tib, numIndices);

			ImDrawVert* verts = (ImDrawVert*)tvb.data;
			memcpy(verts, drawList->VtxBuffer.begin(), numVertices * sizeof(ImDrawVert) );

			ImDrawIdx* indices = (ImDrawIdx*)tib.data;
			memcpy(indices, drawList->IdxBuffer.begin(), numIndices * sizeof(ImDrawIdx) );

			uint32_t offset = 0;
			for (const ImDrawCmd* cmd = drawList->CmdBuffer.begin(), *cmdEnd = drawList->CmdBuffer.end(); cmd != cmdEnd; ++cmd)
			{
				if (cmd->UserCallback)
				{
					cmd->UserCallback(drawList, cmd);
				}
				else if (0 != cmd->ElemCount)
				{
					uint64_t state = 0
						| BGFX_STATE_RGB_WRITE
						| BGFX_STATE_ALPHA_WRITE
						| BGFX_STATE_MSAA
						;

					bgfx::TextureHandle th = m_texture;
					bgfx::ProgramHandle program = m_program;

					if (NULL != cmd->TextureId)
					{
						union { ImTextureID ptr; struct { bgfx::TextureHandle handle; uint8_t flags; uint8_t mip; } s; } texture = { cmd->TextureId };
						state |= 0 != (IMGUI_FLAGS_ALPHA_BLEND & texture.s.flags)
							? BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA)
							: BGFX_STATE_NONE
							;
						th = texture.s.handle;
						if (0 != texture.s.mip)
						{
							extern bgfx::ProgramHandle imguiGetImageProgram(uint8_t _mip);
							program = imguiGetImageProgram(texture.s.mip);
						}
					}
					else
					{
						state |= BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA);
					}

					const uint16_t xx = uint16_t(bx::fmax(cmd->ClipRect.x, 0.0f) );
					const uint16_t yy = uint16_t(bx::fmax(cmd->ClipRect.y, 0.0f) );
					bgfx::setScissor(xx, yy
							, uint16_t(bx::fmin(cmd->ClipRect.z, 65535.0f)-xx)
							, uint16_t(bx::fmin(cmd->ClipRect.w, 65535.0f)-yy)
							);

					bgfx::setState(state);
					bgfx::setTexture(0, s_tex, th);
					bgfx::setVertexBuffer(&tvb, 0, numVertices);
					bgfx::setIndexBuffer(&tib, offset, cmd->ElemCount);
					bgfx::submit(cmd->ViewId, program);
				}

				offset += cmd->ElemCount;
			}
		}
	}
Esempio n. 6
0
void QuadRenderer::submit()
{
    if (quadCount <= 0)
    {
        return;
    }

    numFrameSubmit++;

    if (Texture::sTextureInfos[currentTexture].handle.idx != MARKEDTEXTURE)
    {
        // On iPad 1, the PosColorTex shader, which multiplies texture color with
        // vertex color, is 5x slower than PosTex, which just draws the texture
        // unmodified. So we do this.
        if(sTinted)
            bgfx::setProgram(sProgramPosColorTex);
        else
            bgfx::setProgram(sProgramPosTex);

        lmAssert(sIndexBufferHandle.idx != bgfx::invalidHandle, "No index buffer!");
        bgfx::setIndexBuffer(sIndexBufferHandle, currentIndexBufferIdx, (quadCount * 6));
        bgfx::setVertexBuffer(vertexBuffers[currentVertexBufferIdx], MAXBATCHQUADS * 4);

        // set U and V wrap modes (repeat / mirror / clamp)
        uint32_t textureFlags = BGFX_TEXTURE_W_CLAMP;
        ///U
        switch(Texture::sTextureInfos[currentTexture].wrapU)
        {
            case TEXTUREINFO_WRAP_REPEAT:
                textureFlags |= BGFX_TEXTURE_NONE;
                break;
            case TEXTUREINFO_WRAP_MIRROR:
                textureFlags |= BGFX_TEXTURE_U_MIRROR;
                break;
            case TEXTUREINFO_WRAP_CLAMP:
                textureFlags |= BGFX_TEXTURE_U_CLAMP;
                break;
        }
        ///V
        switch(Texture::sTextureInfos[currentTexture].wrapV)
        {
            case TEXTUREINFO_WRAP_REPEAT:
                textureFlags |= BGFX_TEXTURE_NONE;
                break;
            case TEXTUREINFO_WRAP_MIRROR:
                textureFlags |= BGFX_TEXTURE_V_MIRROR;
                break;
            case TEXTUREINFO_WRAP_CLAMP:
                textureFlags |= BGFX_TEXTURE_V_CLAMP;
                break;
        }

        // set smoothing mode, bgfx default is bilinear
        switch (Texture::sTextureInfos[currentTexture].smoothing)
        {
            // use nearest neighbor 
            case TEXTUREINFO_SMOOTHING_NONE:
                textureFlags |= BGFX_TEXTURE_MIN_POINT;
                textureFlags |= BGFX_TEXTURE_MAG_POINT;
                textureFlags |= BGFX_TEXTURE_MIP_POINT;
                break;
        }   
        
        bgfx::setTexture(0, sUniformTexColor, Texture::sTextureInfos[currentTexture].handle, textureFlags);

        // 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_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA)
                       );

        bgfx::submit(Graphics::getView());


        currentIndexBufferIdx += quadCount * 6;
    }

    quadCount = 0;
}
Esempio n. 7
0
	void render(ImDrawList** const _lists, int _count)
	{
		const float width  = ImGui::GetIO().DisplaySize.x;
		const float height = ImGui::GetIO().DisplaySize.y;

		float ortho[16];
		bx::mtxOrtho(ortho, 0.0f, width, height, 0.0f, -1.0f, 1.0f);

		bgfx::setViewTransform(m_viewId, NULL, ortho);

		// Render command lists
		for (int32_t ii = 0; ii < _count; ++ii)
		{
			bgfx::TransientVertexBuffer tvb;

			uint32_t vtx_size = 0;

			const ImDrawList* cmd_list   = _lists[ii];
			const ImDrawVert* vtx_buffer = cmd_list->vtx_buffer.begin();

			const ImDrawCmd* pcmd_begin = cmd_list->commands.begin();
			const ImDrawCmd* pcmd_end   = cmd_list->commands.end();
			for (const ImDrawCmd* pcmd = pcmd_begin; pcmd != pcmd_end; pcmd++)
			{
				vtx_size += (uint32_t)pcmd->vtx_count;
			}

			if (!bgfx::checkAvailTransientVertexBuffer(vtx_size, m_decl))
			{
				// not enough space in transient buffer just quit drawing the rest...
				break;
			}

			bgfx::allocTransientVertexBuffer(&tvb, vtx_size, m_decl);

			ImDrawVert* verts = (ImDrawVert*)tvb.data;
			memcpy(verts, vtx_buffer, vtx_size * sizeof(ImDrawVert));

			uint32_t vtx_offset = 0;
			for (const ImDrawCmd* pcmd = pcmd_begin; pcmd != pcmd_end; pcmd++)
			{
				bgfx::setState(0
					| BGFX_STATE_RGB_WRITE
					| BGFX_STATE_ALPHA_WRITE
					| BGFX_STATE_BLEND_FUNC(BGFX_STATE_BLEND_SRC_ALPHA, BGFX_STATE_BLEND_INV_SRC_ALPHA)
					| BGFX_STATE_MSAA
					);
				bgfx::setScissor(uint16_t(pcmd->clip_rect.x)
						, uint16_t(pcmd->clip_rect.y)
						, uint16_t(pcmd->clip_rect.z-pcmd->clip_rect.x)
						, uint16_t(pcmd->clip_rect.w-pcmd->clip_rect.y)
						);
				union { void* ptr; bgfx::TextureHandle handle; } texture = { pcmd->texture_id };

				bgfx::setTexture(0, s_tex, 0 != texture.handle.idx
					? texture.handle
					: m_texture
					);

				bgfx::setVertexBuffer(&tvb, vtx_offset, pcmd->vtx_count);
				bgfx::setProgram(m_program);
				bgfx::submit(m_viewId);

				vtx_offset += pcmd->vtx_count;
			}
		}
	}