Ejemplo n.º 1
0
bool compileHLSLShaderDx9(bx::CommandLine& _cmdLine, const std::string& _code, bx::WriterI* _writer)
{
	BX_TRACE("DX9");

	const char* profile = _cmdLine.findOption('p', "profile");
	if (NULL == profile)
	{
		fprintf(stderr, "Shader profile must be specified.\n");
		return false;
	}

	bool debug = _cmdLine.hasArg('\0', "debug");

	uint32_t flags = 0;
	flags |= debug ? D3DXSHADER_DEBUG : 0;
	flags |= _cmdLine.hasArg('\0', "avoid-flow-control") ? D3DXSHADER_AVOID_FLOW_CONTROL : 0;
	flags |= _cmdLine.hasArg('\0', "no-preshader") ? D3DXSHADER_NO_PRESHADER : 0;
	flags |= _cmdLine.hasArg('\0', "partial-precision") ? D3DXSHADER_PARTIALPRECISION : 0;
	flags |= _cmdLine.hasArg('\0', "prefer-flow-control") ? D3DXSHADER_PREFER_FLOW_CONTROL : 0;
	flags |= _cmdLine.hasArg('\0', "backwards-compatibility") ? D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY : 0;

	bool werror = _cmdLine.hasArg('\0', "Werror");

	uint32_t optimization = 3;
	if (_cmdLine.hasArg(optimization, 'O') )
	{
		optimization = bx::uint32_min(optimization, BX_COUNTOF(s_optimizationLevelDx9)-1);
		flags |= s_optimizationLevelDx9[optimization];
	}
	else
	{
		flags |= D3DXSHADER_SKIPOPTIMIZATION;
	}

	BX_TRACE("Profile: %s", profile);
	BX_TRACE("Flags: 0x%08x", flags);

	LPD3DXBUFFER code;
	LPD3DXBUFFER errorMsg;
	LPD3DXCONSTANTTABLE constantTable;

	HRESULT hr;

	// Output preprocessed shader so that HLSL can be debugged via GPA
	// or PIX. Compiling through memory won't embed preprocessed shader
	// file path.
	if (debug)
	{
		std::string hlslfp = _cmdLine.findOption('o');
		hlslfp += ".hlsl";
		writeFile(hlslfp.c_str(), _code.c_str(), (int32_t)_code.size() );

		hr = D3DXCompileShaderFromFileA(hlslfp.c_str()
			, NULL
			, NULL
			, "main"
			, profile
			, flags
			, &code
			, &errorMsg
			, &constantTable
			);
	}
	else
	{
		hr = D3DXCompileShader(_code.c_str()
			, (uint32_t)_code.size()
			, NULL
			, NULL
			, "main"
			, profile
			, flags
			, &code
			, &errorMsg
			, &constantTable
			);
	}

	if (FAILED(hr)
	|| (werror && NULL != errorMsg) )
	{
		const char* log = (const char*)errorMsg->GetBufferPointer();

		char source[1024];
		int32_t line = 0;
		int32_t column = 0;
		int32_t start = 0;
		int32_t end = INT32_MAX;

		if (3 == sscanf(log, "%[^(](%u,%u):", source, &line, &column)
		&&  0 != line)
		{
			start = bx::uint32_imax(1, line-10);
			end = start + 20;
		}

		printCode(_code.c_str(), line, start, end);
		fprintf(stderr, "Error: 0x%08x %s\n", (uint32_t)hr, log);
		errorMsg->Release();
		return false;
	}

	UniformArray uniforms;

	if (NULL != constantTable)
	{
		D3DXCONSTANTTABLE_DESC desc;
		hr = constantTable->GetDesc(&desc);
		if (FAILED(hr) )
		{
			fprintf(stderr, "Error 0x%08x\n", (uint32_t)hr);
			return false;
		}

		BX_TRACE("Creator: %s 0x%08x", desc.Creator, (uint32_t /*mingw warning*/)desc.Version);
		BX_TRACE("Num constants: %d", desc.Constants);
		BX_TRACE("#   cl ty RxC   S  By Name");

		for (uint32_t ii = 0; ii < desc.Constants; ++ii)
		{
			D3DXHANDLE handle = constantTable->GetConstant(NULL, ii);
			D3DXCONSTANT_DESC constDesc;
			uint32_t count;
			constantTable->GetConstantDesc(handle, &constDesc, &count);
			BX_TRACE("%3d %2d %2d [%dx%d] %d %3d %s[%d] c%d (%d)"
				, ii
				, constDesc.Class
				, constDesc.Type
				, constDesc.Rows
				, constDesc.Columns
				, constDesc.StructMembers
				, constDesc.Bytes
				, constDesc.Name
				, constDesc.Elements
				, constDesc.RegisterIndex
				, constDesc.RegisterCount
				);

			UniformType::Enum type = findUniformTypeDx9(constDesc);
			if (UniformType::Count != type)
			{
				Uniform un;
				un.name = '$' == constDesc.Name[0] ? constDesc.Name+1 : constDesc.Name;
				un.type = type;
				un.num = constDesc.Elements;
				un.regIndex = constDesc.RegisterIndex;
				un.regCount = constDesc.RegisterCount;
				uniforms.push_back(un);
			}
		}
	}

	uint16_t count = (uint16_t)uniforms.size();
	bx::write(_writer, count);

	uint32_t fragmentBit = profile[0] == 'p' ? BGFX_UNIFORM_FRAGMENTBIT : 0;
	for (UniformArray::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
	{
		const Uniform& un = *it;
		uint8_t nameSize = (uint8_t)un.name.size();
		bx::write(_writer, nameSize);
		bx::write(_writer, un.name.c_str(), nameSize);
		uint8_t type = un.type|fragmentBit;
		bx::write(_writer, type);
		bx::write(_writer, un.num);
		bx::write(_writer, un.regIndex);
		bx::write(_writer, un.regCount);

		BX_TRACE("%s, %s, %d, %d, %d"
			, un.name.c_str()
			, getUniformTypeName(un.type)
			, un.num
			, un.regIndex
			, un.regCount
			);
	}

	uint16_t shaderSize = (uint16_t)code->GetBufferSize();
	bx::write(_writer, shaderSize);
	bx::write(_writer, code->GetBufferPointer(), shaderSize);
	uint8_t nul = 0;
	bx::write(_writer, nul);

	if (_cmdLine.hasArg('\0', "disasm") )
	{
		LPD3DXBUFFER disasm;
		D3DXDisassembleShader( (const DWORD*)code->GetBufferPointer()
			, false
			, NULL
			, &disasm
			);

		if (NULL != disasm)
		{
			std::string disasmfp = _cmdLine.findOption('o');
			disasmfp += ".disasm";

			writeFile(disasmfp.c_str(), disasm->GetBufferPointer(), disasm->GetBufferSize() );
			disasm->Release();
		}
	}

	if (NULL != code)
	{
		code->Release();
	}

	if (NULL != errorMsg)
	{
		errorMsg->Release();
	}

	if (NULL != constantTable)
	{
		constantTable->Release();
	}

	return true;
}
Ejemplo n.º 2
0
int _main_(int /*_argc*/, char** /*_argv*/)
{
	PosColorTexCoord0Vertex::init();

	uint32_t width = 1280;
	uint32_t height = 720;
	uint32_t debug = BGFX_DEBUG_TEXT;
	uint32_t reset = BGFX_RESET_VSYNC;

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

	// Enable debug text.
	bgfx::setDebug(debug);

	// Set view 0 clear state.
	bgfx::setViewClear(0
		, BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT
		, 0x303030ff
		, 1.0f
		, 0
		);

	bgfx::TextureHandle uffizi = loadTexture("uffizi.dds", BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_W_CLAMP);

	bgfx::ProgramHandle skyProgram     = loadProgram("vs_hdr_skybox",  "fs_hdr_skybox");
	bgfx::ProgramHandle lumProgram     = loadProgram("vs_hdr_lum",     "fs_hdr_lum");
	bgfx::ProgramHandle lumAvgProgram  = loadProgram("vs_hdr_lumavg",  "fs_hdr_lumavg");
	bgfx::ProgramHandle blurProgram    = loadProgram("vs_hdr_blur",    "fs_hdr_blur");
	bgfx::ProgramHandle brightProgram  = loadProgram("vs_hdr_bright",  "fs_hdr_bright");
	bgfx::ProgramHandle meshProgram    = loadProgram("vs_hdr_mesh",    "fs_hdr_mesh");
	bgfx::ProgramHandle tonemapProgram = loadProgram("vs_hdr_tonemap", "fs_hdr_tonemap");

	bgfx::UniformHandle u_time      = bgfx::createUniform("u_time",     bgfx::UniformType::Uniform1f);
	bgfx::UniformHandle u_texCube   = bgfx::createUniform("u_texCube",  bgfx::UniformType::Uniform1i);
	bgfx::UniformHandle u_texColor  = bgfx::createUniform("u_texColor", bgfx::UniformType::Uniform1i);
	bgfx::UniformHandle u_texLum    = bgfx::createUniform("u_texLum",   bgfx::UniformType::Uniform1i);
	bgfx::UniformHandle u_texBlur   = bgfx::createUniform("u_texBlur",  bgfx::UniformType::Uniform1i);
	bgfx::UniformHandle u_mtx       = bgfx::createUniform("u_mtx",      bgfx::UniformType::Uniform4x4fv);
	bgfx::UniformHandle u_tonemap   = bgfx::createUniform("u_tonemap",  bgfx::UniformType::Uniform4fv);
	bgfx::UniformHandle u_offset    = bgfx::createUniform("u_offset",   bgfx::UniformType::Uniform4fv, 16);

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

	bgfx::FrameBufferHandle fbh;
	bgfx::TextureHandle fbtextures[] =
	{
		bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT|BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP),
		bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_BUFFER_ONLY),
	};
	fbh = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);

	bgfx::FrameBufferHandle lum[5];
	lum[0] = bgfx::createFrameBuffer(128, 128, bgfx::TextureFormat::BGRA8);
	lum[1] = bgfx::createFrameBuffer( 64,  64, bgfx::TextureFormat::BGRA8);
	lum[2] = bgfx::createFrameBuffer( 16,  16, bgfx::TextureFormat::BGRA8);
	lum[3] = bgfx::createFrameBuffer(  4,   4, bgfx::TextureFormat::BGRA8);
	lum[4] = bgfx::createFrameBuffer(  1,   1, bgfx::TextureFormat::BGRA8);

	bgfx::FrameBufferHandle bright;
	bright = bgfx::createFrameBuffer(width/2, height/2, bgfx::TextureFormat::BGRA8);

	bgfx::FrameBufferHandle blur;
	blur = bgfx::createFrameBuffer(width/8, height/8, bgfx::TextureFormat::BGRA8);

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

	float speed      = 0.37f;
	float middleGray = 0.18f;
	float white      = 1.1f;
	float treshold   = 1.5f;

	int32_t scrollArea = 0;

	uint32_t oldWidth = 0;
	uint32_t oldHeight = 0;
	uint32_t oldReset = reset;

	entry::MouseState mouseState;

	float time = 0.0f;

	while (!entry::processEvents(width, height, debug, reset, &mouseState) )
	{
		if (oldWidth  != width
		||  oldHeight != height
		||  oldReset  != reset)
		{
			// Recreate variable size render targets when resolution changes.
			oldWidth  = width;
			oldHeight = height;
			oldReset  = reset;

			uint32_t msaa = (reset&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT;

			bgfx::destroyFrameBuffer(fbh);
			bgfx::destroyFrameBuffer(bright);
			bgfx::destroyFrameBuffer(blur);

			fbtextures[0] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::BGRA8, ( (msaa+1)<<BGFX_TEXTURE_RT_MSAA_SHIFT)|BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP);
			fbtextures[1] = bgfx::createTexture2D(width, height, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_BUFFER_ONLY|( (msaa+1)<<BGFX_TEXTURE_RT_MSAA_SHIFT) );
			fbh = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);

			bright = bgfx::createFrameBuffer(width/2, height/2, bgfx::TextureFormat::BGRA8);
			blur   = bgfx::createFrameBuffer(width/8, height/8, bgfx::TextureFormat::BGRA8);
		}

		imguiBeginFrame(mouseState.m_mx
			, mouseState.m_my
			, (mouseState.m_buttons[entry::MouseButton::Left  ] ? IMGUI_MBUT_LEFT  : 0)
			| (mouseState.m_buttons[entry::MouseButton::Right ] ? IMGUI_MBUT_RIGHT : 0)
			, 0
			, width
			, height
			);

		imguiBeginScrollArea("Settings", width - width / 5 - 10, 10, width / 5, height / 3, &scrollArea);
		imguiSeparatorLine();

		imguiSlider("Speed", &speed, 0.0f, 1.0f, 0.01f);
		imguiSeparator();

		imguiSlider("Middle gray", &middleGray, 0.1f, 1.0f, 0.01f);
		imguiSlider("White point", &white, 0.1f, 2.0f, 0.01f);
		imguiSlider("Treshold", &treshold, 0.1f, 2.0f, 0.01f);

		imguiEndScrollArea();
		imguiEndFrame();

		// This dummy draw call is here to make sure that view 0 is cleared
		// if no other draw calls are submitted to view 0.
		bgfx::submit(0);

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

		time += (float)(frameTime*speed/freq);

		bgfx::setUniform(u_time, &time);

		// Use debug font to print information about this example.
		bgfx::dbgTextClear();
		bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/09-hdr");
		bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Using multiple views and render targets.");
		bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);

		// Set views.
		bgfx::setViewRectMask(0x1f, 0, 0, width, height);
		bgfx::setViewFrameBufferMask(0x3, fbh);

		bgfx::setViewRect(2, 0, 0, 128, 128);
		bgfx::setViewFrameBuffer(2, lum[0]);

		bgfx::setViewRect(3, 0, 0, 64, 64);
		bgfx::setViewFrameBuffer(3, lum[1]);

		bgfx::setViewRect(4, 0, 0, 16, 16);
		bgfx::setViewFrameBuffer(4, lum[2]);

		bgfx::setViewRect(5, 0, 0, 4, 4);
		bgfx::setViewFrameBuffer(5, lum[3]);

		bgfx::setViewRect(6, 0, 0, 1, 1);
		bgfx::setViewFrameBuffer(6, lum[4]);

		bgfx::setViewRect(7, 0, 0, width/2, height/2);
		bgfx::setViewFrameBuffer(7, bright);

		bgfx::setViewRect(8, 0, 0, width/8, height/8);
		bgfx::setViewFrameBuffer(8, blur);

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

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

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

		// Set view and projection matrix for view 0.
		bgfx::setViewTransformMask(0
				|(1<<0)
				|(1<<2)
				|(1<<3)
				|(1<<4)
				|(1<<5)
				|(1<<6)
				|(1<<7)
				|(1<<8)
				|(1<<9)
				, view
				, proj
				);

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

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

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

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

		// Set view and projection matrix for view 1.
		bgfx::setViewTransformMask(1<<1, view, proj);

		bgfx::setUniform(u_mtx, mtx);

		// Render skybox into view 0.
		bgfx::setTexture(0, u_texCube, uffizi);
		bgfx::setProgram(skyProgram);
		bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
		screenSpaceQuad( (float)width, (float)height, true);
		bgfx::submit(0);

		// Render mesh into view 1
		bgfx::setTexture(0, u_texCube, uffizi);
		meshSubmit(mesh, 1, meshProgram, NULL);

		// Calculate luminance.
		setOffsets2x2Lum(u_offset, 128, 128);
		bgfx::setTexture(0, u_texColor, fbtextures[0]);
		bgfx::setProgram(lumProgram);
		bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
		screenSpaceQuad(128.0f, 128.0f, s_flipV);
		bgfx::submit(2);

		// Downscale luminance 0.
		setOffsets4x4Lum(u_offset, 128, 128);
		bgfx::setTexture(0, u_texColor, lum[0]);
		bgfx::setProgram(lumAvgProgram);
		bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
		screenSpaceQuad(64.0f, 64.0f, s_flipV);
		bgfx::submit(3);

		// Downscale luminance 1.
		setOffsets4x4Lum(u_offset, 64, 64);
		bgfx::setTexture(0, u_texColor, lum[1]);
		bgfx::setProgram(lumAvgProgram);
		bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
		screenSpaceQuad(16.0f, 16.0f, s_flipV);
		bgfx::submit(4);

		// Downscale luminance 2.
		setOffsets4x4Lum(u_offset, 16, 16);
		bgfx::setTexture(0, u_texColor, lum[2]);
		bgfx::setProgram(lumAvgProgram);
		bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
		screenSpaceQuad(4.0f, 4.0f, s_flipV);
		bgfx::submit(5);

		// Downscale luminance 3.
		setOffsets4x4Lum(u_offset, 4, 4);
		bgfx::setTexture(0, u_texColor, lum[3]);
		bgfx::setProgram(lumAvgProgram);
		bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
		screenSpaceQuad(1.0f, 1.0f, s_flipV);
		bgfx::submit(6);

		float tonemap[4] = { middleGray, square(white), treshold, 0.0f };
		bgfx::setUniform(u_tonemap, tonemap);

		// Bright pass treshold is tonemap[3].
		setOffsets4x4Lum(u_offset, width/2, height/2);
		bgfx::setTexture(0, u_texColor, fbtextures[0]);
		bgfx::setTexture(1, u_texLum, lum[4]);
		bgfx::setProgram(brightProgram);
		bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
		screenSpaceQuad( (float)width/2.0f, (float)height/2.0f, s_flipV);
		bgfx::submit(7);

		// Blur bright pass vertically.
		bgfx::setTexture(0, u_texColor, bright);
		bgfx::setProgram(blurProgram);
		bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
		screenSpaceQuad( (float)width/8.0f, (float)height/8.0f, s_flipV);
		bgfx::submit(8);

		// Blur bright pass horizontally, do tonemaping and combine.
		bgfx::setTexture(0, u_texColor, fbtextures[0]);
		bgfx::setTexture(1, u_texLum, lum[4]);
		bgfx::setTexture(2, u_texBlur, blur);
		bgfx::setProgram(tonemapProgram);
		bgfx::setState(BGFX_STATE_RGB_WRITE|BGFX_STATE_ALPHA_WRITE);
		screenSpaceQuad( (float)width, (float)height, s_flipV);
		bgfx::submit(9);

		// Advance to next frame. Rendering thread will be kicked to 
		// process submitted rendering primitives.
		bgfx::frame();
	}
Ejemplo n.º 3
0
		"Attrib::Tangent",
		"Attrib::Bitangent",
		"Attrib::Color0",
		"Attrib::Color1",
		"Attrib::Indices",
		"Attrib::Weights",
		"Attrib::TexCoord0",
		"Attrib::TexCoord1",
		"Attrib::TexCoord2",
		"Attrib::TexCoord3",
		"Attrib::TexCoord4",
		"Attrib::TexCoord5",
		"Attrib::TexCoord6",
		"Attrib::TexCoord7",
	};
	BX_STATIC_ASSERT(BX_COUNTOF(s_attrName) == Attrib::Count);

	const char* getAttribName(Attrib::Enum _attr)
	{
		return s_attrName[_attr];
	}

	void dump(const VertexDecl& _decl)
	{
		if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
		{
			dbgPrintf("vertexdecl %08x (%08x), stride %d\n"
				, _decl.m_hash
				, bx::hashMurmur2A(_decl.m_attributes)
				, _decl.m_stride
				);
Ejemplo n.º 4
0
Archivo: Tcl.cpp Proyecto: wibbe/zum
  void initialize()
  {
    interpreter_ = Jim_CreateInterp();
    Jim_RegisterCoreCommands(interpreter_);

    // Register extensions
    ::Jim_clockInit(interpreter_);
    ::Jim_regexpInit(interpreter_);

    // Register built in commands
    for (auto * cmd : builtInProcs())
      Jim_CreateCommand(interpreter_, cmd->name(), cmdProc, cmd, nullptr);

    for (auto * cmd : builtInSubCmdProcs())
      Jim_CreateCommand(interpreter_, cmd->name(), subCmdProc, cmd, nullptr);

    // Register built in variables
    for (auto * var : builtInVariables())
      Jim_SetGlobalVariableStr(interpreter_, var->name(), var->defaultValue());

#if DEBUG
    // Use the file from the source directory
    Jim_EvalFileGlobal(interpreter_, "../src/ScriptingLib.tcl");
#else
    Jim_EvalSource(interpreter_, __FILE__, __LINE__, std::string((char *)&ScriptingLib[0], BX_COUNTOF(ScriptingLib)).c_str());
#endif


    std::string configFile = "";
#if BX_PLATFORM_LINUX || BX_PLATFORM_OSX
    // Try to load the config file
    char * home = getenv("HOME");
    if (home)
      configFile = std::string(home) + "/." + CONFIG_FILE;
    else
      configFile = "~/." + CONFIG_FILE;
#else
    char pwd[1024];
    configFile = std::string(bx::pwd(pwd, 1024)) + "/" + CONFIG_FILE;
#endif

    logInfo("Loading config file: ", configFile);
    Jim_EvalFileGlobal(interpreter_, configFile.c_str());
  }
Ejemplo n.º 5
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 * (sin(light/float(numLights) * bx::piHalf ) * 0.5f + 0.5f);
				lightPosRadius.m_center[0] = sin( ( (lightTime + light*0.47f) + bx::piHalf*1.37f ) )*offset;
				lightPosRadius.m_center[1] = cos( ( (lightTime + light*0.69f) + bx::piHalf*1.49f ) )*offset;
				lightPosRadius.m_center[2] = sin( ( (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;
}
Ejemplo n.º 6
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
		);

	// Get renderer capabilities info.
	const bgfx::Caps* caps = bgfx::getCaps();
	bool instancingSupported = 0 != (caps->supported & BGFX_CAPS_INSTANCING);

	// Create vertex stream declaration.
	PosNormalTangentTexcoordVertex::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 u_texColor  = bgfx::createUniform("u_texColor",  bgfx::UniformType::Uniform1iv);
	bgfx::UniformHandle u_texNormal = bgfx::createUniform("u_texNormal", bgfx::UniformType::Uniform1iv);

	uint16_t numLights = 4;
	bgfx::UniformHandle u_lightPosRadius = bgfx::createUniform("u_lightPosRadius", bgfx::UniformType::Uniform4fv, numLights);
	bgfx::UniformHandle u_lightRgbInnerR = bgfx::createUniform("u_lightRgbInnerR", bgfx::UniformType::Uniform4fv, numLights);

	// Create program from shaders.
	bgfx::ProgramHandle program = loadProgram(instancingSupported ? "vs_bump_instanced" : "vs_bump", "fs_bump");

	// Load diffuse texture.
	bgfx::TextureHandle textureColor = loadTexture("fieldstone-rgba.dds");

	// Load normal texture.
	bgfx::TextureHandle textureNormal = loadTexture("fieldstone-n.dds");

	int64_t timeOffset = bx::getHPCounter();

	while (!entry::processEvents(width, height, debug, reset) )
	{
		// Set view 0 default viewport.
		bgfx::setViewRect(0, 0, 0, width, height);

		// This dummy draw call is here to make sure that view 0 is cleared
		// if no other draw calls are submitted to view 0.
		bgfx::submit(0);

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

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

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

		float at[3] = { 0.0f, 0.0f, 0.0f };
		float eye[3] = { 0.0f, 0.0f, -7.0f };
		
		float view[16];
		float proj[16];
		bx::mtxLookAt(view, eye, at);
		bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f);

		float lightPosRadius[4][4];
		for (uint32_t ii = 0; ii < numLights; ++ii)
		{
			lightPosRadius[ii][0] = sin( (time*(0.1f + ii*0.17f) + float(ii*M_PI_2)*1.37f ) )*3.0f;
			lightPosRadius[ii][1] = cos( (time*(0.2f + ii*0.29f) + float(ii*M_PI_2)*1.49f ) )*3.0f;
			lightPosRadius[ii][2] = -2.5f;
			lightPosRadius[ii][3] = 3.0f;
		}

		bgfx::setUniform(u_lightPosRadius, lightPosRadius, numLights);

		float lightRgbInnerR[4][4] =
		{
			{ 1.0f, 0.7f, 0.2f, 0.8f },
			{ 0.7f, 0.2f, 1.0f, 0.8f },
			{ 0.2f, 1.0f, 0.7f, 0.8f },
			{ 1.0f, 0.4f, 0.2f, 0.8f },
		};

		bgfx::setUniform(u_lightRgbInnerR, lightRgbInnerR, numLights);

		// Set view and projection matrix for view 0.
		bgfx::setViewTransform(0, view, proj);

		const uint16_t instanceStride = 64;
		const uint16_t numInstances = 3;

		if (instancingSupported)
		{
			// Write instance data for 3x3 cubes.
			for (uint32_t yy = 0; yy < 3; ++yy)
			{
				const bgfx::InstanceDataBuffer* idb = bgfx::allocInstanceDataBuffer(numInstances, instanceStride);
				if (NULL != idb)
				{
					uint8_t* data = idb->data;

					for (uint32_t xx = 0; xx < 3; ++xx)
					{
						float* mtx = (float*)data;
						bx::mtxRotateXY(mtx, time*0.023f + xx*0.21f, time*0.03f + yy*0.37f);
						mtx[12] = -3.0f + float(xx)*3.0f;
						mtx[13] = -3.0f + float(yy)*3.0f;
						mtx[14] = 0.0f;

						data += instanceStride;
					}

					// Set instance data buffer.
					bgfx::setInstanceDataBuffer(idb, numInstances);

					// Set vertex and fragment shaders.
					bgfx::setProgram(program);

					// Set vertex and index buffer.
					bgfx::setVertexBuffer(vbh);
					bgfx::setIndexBuffer(ibh);

					// Bind textures.
					bgfx::setTexture(0, u_texColor, textureColor);
					bgfx::setTexture(1, u_texNormal, textureNormal);

					// Set render states.
					bgfx::setState(0
						| BGFX_STATE_RGB_WRITE
						| BGFX_STATE_ALPHA_WRITE
						| BGFX_STATE_DEPTH_WRITE
						| BGFX_STATE_DEPTH_TEST_LESS
						| BGFX_STATE_MSAA
						);

					// Submit primitive for rendering to view 0.
					bgfx::submit(0);
				}
			}
		}
		else
		{
			for (uint32_t yy = 0; yy < 3; ++yy)
			{
				for (uint32_t xx = 0; xx < 3; ++xx)
				{
					float mtx[16];
					bx::mtxRotateXY(mtx, time*0.023f + xx*0.21f, time*0.03f + yy*0.37f);
					mtx[12] = -3.0f + float(xx)*3.0f;
					mtx[13] = -3.0f + float(yy)*3.0f;
					mtx[14] = 0.0f;

					// Set transform for draw call.
					bgfx::setTransform(mtx);

					// Set vertex and fragment shaders.
					bgfx::setProgram(program);

					// Set vertex and index buffer.
					bgfx::setVertexBuffer(vbh);
					bgfx::setIndexBuffer(ibh);

					// Bind textures.
					bgfx::setTexture(0, u_texColor, textureColor);
					bgfx::setTexture(1, u_texNormal, textureNormal);

					// Set render states.
					bgfx::setState(0
						| BGFX_STATE_RGB_WRITE
						| BGFX_STATE_ALPHA_WRITE
						| BGFX_STATE_DEPTH_WRITE
						| BGFX_STATE_DEPTH_TEST_LESS
						| BGFX_STATE_MSAA
						);

					// Submit primitive for rendering to view 0.
					bgfx::submit(0);
				}
			}
		}

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

	// Cleanup.
	bgfx::destroyIndexBuffer(ibh);
	bgfx::destroyVertexBuffer(vbh);
	bgfx::destroyProgram(program);
	bgfx::destroyTexture(textureColor);
	bgfx::destroyTexture(textureNormal);
	bgfx::destroyUniform(u_texColor);
	bgfx::destroyUniform(u_texNormal);
	bgfx::destroyUniform(u_lightPosRadius);
	bgfx::destroyUniform(u_lightRgbInnerR);

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

	return 0;
}
Ejemplo n.º 7
0
int _main_(int /*_argc*/, char** /*_argv*/)
{
	uint32_t width = 1280;
	uint32_t height = 720;
	uint32_t debug = BGFX_DEBUG_TEXT;
	uint32_t reset = BGFX_RESET_VSYNC;

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

	// Enable debug text.
	bgfx::setDebug(debug);

	// Setup root path for binary shaders. Shader binaries are different
	// for each renderer.
	switch (bgfx::getRendererType() )
	{
	default:
	case bgfx::RendererType::Direct3D9:
		s_shaderPath = "shaders/dx9/";
		s_texelHalf = 0.5f;
		break;

	case bgfx::RendererType::Direct3D11:
		s_shaderPath = "shaders/dx11/";
		break;

	case bgfx::RendererType::OpenGL:
		s_shaderPath = "shaders/glsl/";
		s_flipV = true;
		break;

	case bgfx::RendererType::OpenGLES2:
	case bgfx::RendererType::OpenGLES3:
		s_shaderPath = "shaders/gles/";
		s_flipV = true;
		break;
	}

	// Uniforms.
	u_shadowMap = bgfx::createUniform("u_shadowMap", bgfx::UniformType::Uniform1iv);

	bgfx::UniformHandle u_lightPos = bgfx::createUniform("u_lightPos", bgfx::UniformType::Uniform4fv);
	bgfx::UniformHandle u_lightMtx = bgfx::createUniform("u_lightMtx", bgfx::UniformType::Uniform4x4fv);

	// Programs.
	bgfx::ProgramHandle progPackDepth = loadProgram("vs_smsimple_packdepth", "fs_smsimple_packdepth");
	bgfx::ProgramHandle progDraw      = loadProgram("vs_smsimple_draw",      "fs_smsimple_draw");

	// Vertex declarations.
	bgfx::VertexDecl PosNormalDecl;
	PosNormalDecl.begin();
	PosNormalDecl.add(bgfx::Attrib::Position,  3, bgfx::AttribType::Float);
	PosNormalDecl.add(bgfx::Attrib::Normal,    4, bgfx::AttribType::Uint8, true, true);
	PosNormalDecl.end();

	// Meshes.
	Mesh bunnyMesh;
	Mesh cubeMesh;
	Mesh hollowcubeMesh;
	Mesh hplaneMesh;
	bunnyMesh.load("meshes/bunny.bin");
	cubeMesh.load("meshes/cube.bin");
	hollowcubeMesh.load("meshes/hollowcube.bin");
	hplaneMesh.load(s_hplaneVertices, s_numHPlaneVertices, PosNormalDecl, s_planeIndices, s_numPlaneIndices);

	// Render targets.
	uint16_t shadowMapSize = 512;

	bgfx::TextureHandle fbtextures[] =
	{
		bgfx::createTexture2D(shadowMapSize, shadowMapSize, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT),
		bgfx::createTexture2D(shadowMapSize, shadowMapSize, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_BUFFER_ONLY),
	};
	s_shadowMapFB = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);

	// Set view and projection matrices.
	float view[16];
	float proj[16];

	const float eye[3] = { 0.0f, 30.0f, -60.0f };
	const float at[3]  = { 0.0f, 5.0f, 0.0f };
	mtxLookAt(view, eye, at);

	const float aspect = float(int32_t(width) ) / float(int32_t(height) );
	mtxProj(proj, 60.0f, aspect, 0.1f, 1000.0f);

	// Time acumulators.
	float timeAccumulatorLight = 0.0f;
	float timeAccumulatorScene = 0.0f;

	entry::MouseState mouseState;
	while (!entry::processEvents(width, height, debug, reset, &mouseState) )
	{
		// Time.
		int64_t now = bx::getHPCounter();
		static int64_t last = now;
		const int64_t frameTime = now - last;
		last = now;
		const double freq = double(bx::getHPFrequency() );
		const double toMs = 1000.0/freq;
		const float deltaTime = float(frameTime/freq);

		// Update time accumulators.
		timeAccumulatorLight += deltaTime;
		timeAccumulatorScene += deltaTime;

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

		// Setup lights.
		float lightPos[4];
		lightPos[0] = -cos(timeAccumulatorLight);
		lightPos[1] = -1.0f;
		lightPos[2] = -sin(timeAccumulatorLight);
		lightPos[3] = 0.0f;

		bgfx::setUniform(u_lightPos, lightPos);

		// Setup instance matrices.
		float mtxFloor[16];
		mtxScaleRotateTranslate(mtxFloor
			, 30.0f //scaleX
			, 30.0f //scaleY
			, 30.0f //scaleZ
			, 0.0f  //rotX
			, 0.0f  //rotY
			, 0.0f  //rotZ
			, 0.0f  //translateX
			, 0.0f  //translateY
			, 0.0f  //translateZ
			);

		float mtxBunny[16];
		mtxScaleRotateTranslate(mtxBunny
			, 5.0f
			, 5.0f
			, 5.0f
			, 0.0f
			, float(M_PI) - timeAccumulatorScene
			, 0.0f
			, 15.0f
			, 5.0f
			, 0.0f
			);

		float mtxHollowcube[16];
		mtxScaleRotateTranslate(mtxHollowcube
			, 2.5f
			, 2.5f
			, 2.5f
			, 0.0f
			, 1.56f - timeAccumulatorScene
			, 0.0f
			, 0.0f
			, 10.0f
			, 0.0f
			);

		float mtxCube[16];
		mtxScaleRotateTranslate(mtxCube
			, 2.5f
			, 2.5f
			, 2.5f
			, 0.0f
			, 1.56f - timeAccumulatorScene
			, 0.0f
			, -15.0f
			, 5.0f
			, 0.0f
			);

		// Define matrices.
		float screenView[16];
		float screenProj[16];
		mtxIdentity(screenView);
		mtxOrtho(screenProj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f);

		float lightView[16];
		float lightProj[16];

		const float eye[3] =
		{
			-lightPos[0],
			-lightPos[1],
			-lightPos[2],
		};
		const float at[3] = { 0.0f, 0.0f, 0.0f };
		mtxLookAt(lightView, eye, at);

		const float area = 30.0f;
		mtxOrtho(lightProj, -area, area, -area, area, -100.0f, 100.0f);

		bgfx::setViewRect(RENDER_SHADOW_PASS_ID, 0, 0, shadowMapSize, shadowMapSize);
		bgfx::setViewRect(RENDER_SCENE_PASS_ID, 0, 0, width, height);

		bgfx::setViewTransform(RENDER_SHADOW_PASS_ID, lightView, lightProj);
		bgfx::setViewTransform(RENDER_SCENE_PASS_ID, view, proj);

		bgfx::setViewFrameBuffer(RENDER_SHADOW_PASS_ID, s_shadowMapFB);

		// Clear backbuffer and shadowmap framebuffer at beginning.
		bgfx::setViewClearMask(0x3, BGFX_CLEAR_COLOR_BIT | BGFX_CLEAR_DEPTH_BIT, 0x303030ff, 1.0f, 0);
		bgfx::submitMask(0x3);

		// Render.

		{ // Craft shadow map.

			hplaneMesh.submit(RENDER_SHADOW_PASS_ID, mtxFloor, progPackDepth);
			bunnyMesh.submit(RENDER_SHADOW_PASS_ID, mtxBunny, progPackDepth);
			hollowcubeMesh.submit(RENDER_SHADOW_PASS_ID, mtxHollowcube, progPackDepth);
			cubeMesh.submit(RENDER_SHADOW_PASS_ID, mtxCube, progPackDepth);
		}

		{ // Draw Scene.

			float mtxShadow[16]; //lightviewProjCrop
			float lightMtx[16];  //modelLightviewProjCrop

			const float s = (s_flipV) ? 1.0f : -1.0f; //sign

			const float mtxCrop[16] =
			{
				0.5f,   0.0f, 0.0f, 0.0f,
				0.0f, s*0.5f, 0.0f, 0.0f,
				0.0f,   0.0f, 0.5f, 0.0f,
				0.5f,   0.5f, 0.5f, 1.0f,
			};

			float mtxTmp[16];
			mtxMul(mtxTmp, lightProj, mtxCrop);
			mtxMul(mtxShadow, lightView, mtxTmp);

			// Floor.
			mtxMul(lightMtx, mtxFloor, mtxShadow);
			bgfx::setUniform(u_lightMtx, lightMtx);
			hplaneMesh.submit(RENDER_SCENE_PASS_ID, mtxFloor, progDraw);

			// Bunny.
			mtxMul(lightMtx, mtxBunny, mtxShadow);
			bgfx::setUniform(u_lightMtx, lightMtx);
			bunnyMesh.submit(RENDER_SCENE_PASS_ID, mtxBunny, progDraw);

			// Hollow cube.
			mtxMul(lightMtx, mtxHollowcube, mtxShadow);
			bgfx::setUniform(u_lightMtx, lightMtx);
			hollowcubeMesh.submit(RENDER_SCENE_PASS_ID, mtxHollowcube, progDraw);

			// Cube.
			mtxMul(lightMtx, mtxCube, mtxShadow);
			bgfx::setUniform(u_lightMtx, lightMtx);
			cubeMesh.submit(RENDER_SCENE_PASS_ID, mtxCube, progDraw);
		}

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

	}

	bunnyMesh.unload();
	cubeMesh.unload();
	hollowcubeMesh.unload();
	hplaneMesh.unload();

	bgfx::destroyProgram(progPackDepth);
	bgfx::destroyProgram(progDraw);

	bgfx::destroyFrameBuffer(s_shadowMapFB);

	bgfx::destroyUniform(u_shadowMap);
	bgfx::destroyUniform(u_lightPos);
	bgfx::destroyUniform(u_lightMtx);

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

	return 0;
}
Ejemplo n.º 8
0
uint32_t objToBin(const uint8_t* _objData
                  , bx::WriterSeekerI* _writer
                  , uint32_t _packUv
                  , uint32_t _packNormal
                  , bool _ccw
                  , bool _flipV
                  , bool _hasTangent
                  , float _scale
                 )
{
    int64_t parseElapsed = -bx::getHPCounter();
    int64_t triReorderElapsed = 0;

    const int64_t begin = _writer->seek();

    Vector3Array positions;
    Vector3Array normals;
    Vector3Array texcoords;
    Index3Map indexMap;
    TriangleArray triangles;
    BgfxGroupArray groups;

    uint32_t num = 0;

    MeshGroup group;
    group.m_startTriangle = 0;
    group.m_numTriangles = 0;
    group.m_name = "";
    group.m_material = "";

    char commandLine[2048];
    uint32_t len = sizeof(commandLine);
    int argc;
    char* argv[64];
    const char* next = (const char*)_objData;
    do
    {
        next = bx::tokenizeCommandLine(next, commandLine, len, argc, argv, BX_COUNTOF(argv), '\n');
        if (0 < argc)
        {
            if (0 == strcmp(argv[0], "#") )
            {
                if (2 < argc
                        &&  0 == strcmp(argv[2], "polygons") )
                {
                }
            }
            else if (0 == strcmp(argv[0], "f") )
            {
                Triangle triangle;
                memset(&triangle, 0, sizeof(Triangle) );

                const int numNormals   = (int)normals.size();
                const int numTexcoords = (int)texcoords.size();
                const int numPositions = (int)positions.size();
                for (uint32_t edge = 0, numEdges = argc-1; edge < numEdges; ++edge)
                {
                    Index3 index;
                    index.m_texcoord = 0;
                    index.m_normal = 0;
                    index.m_vertexIndex = -1;

                    char* vertex = argv[edge+1];
                    char* texcoord = strchr(vertex, '/');
                    if (NULL != texcoord)
                    {
                        *texcoord++ = '\0';

                        char* normal = strchr(texcoord, '/');
                        if (NULL != normal)
                        {
                            *normal++ = '\0';
                            const int nn = atoi(normal);
                            index.m_normal = (nn < 0) ? nn+numNormals : nn-1;
                        }

                        const int tex = atoi(texcoord);
                        index.m_texcoord = (tex < 0) ? tex+numTexcoords : tex-1;
                    }

                    const int pos = atoi(vertex);
                    index.m_position = (pos < 0) ? pos+numPositions : pos-1;

                    uint64_t hash0 = index.m_position;
                    uint64_t hash1 = uint64_t(index.m_texcoord)<<20;
                    uint64_t hash2 = uint64_t(index.m_normal)<<40;
                    uint64_t hash = hash0^hash1^hash2;

                    CS_STL::pair<Index3Map::iterator, bool> result = indexMap.insert(CS_STL::make_pair(hash, index) );
                    if (!result.second)
                    {
                        Index3& oldIndex = result.first->second;
                        BX_UNUSED(oldIndex);
                        BX_CHECK(oldIndex.m_position == index.m_position
                                 && oldIndex.m_texcoord == index.m_texcoord
                                 && oldIndex.m_normal == index.m_normal
                                 , "Hash collision!"
                                );
                    }

                    switch (edge)
                    {
                    case 0:
                    case 1:
                    case 2:
                        triangle.m_index[edge] = hash;
                        if (2 == edge)
                        {
                            if (_ccw)
                            {
                                std::swap(triangle.m_index[1], triangle.m_index[2]);
                            }
                            triangles.push_back(triangle);
                        }
                        break;

                    default:
                        if (_ccw)
                        {
                            triangle.m_index[2] = triangle.m_index[1];
                            triangle.m_index[1] = hash;
                        }
                        else
                        {
                            triangle.m_index[1] = triangle.m_index[2];
                            triangle.m_index[2] = hash;
                        }
                        triangles.push_back(triangle);
                        break;
                    }
                }
            }
            else if (0 == strcmp(argv[0], "g") )
            {
                if (1 >= argc)
                {
                    CS_PRINT("Error parsing *.obj file.\n");
                    return 0;
                }
                group.m_name = argv[1];
            }
            else if (*argv[0] == 'v')
            {
                group.m_numTriangles = (uint32_t)(triangles.size() ) - group.m_startTriangle;
                if (0 < group.m_numTriangles)
                {
                    groups.push_back(group);
                    group.m_startTriangle = (uint32_t)(triangles.size() );
                    group.m_numTriangles = 0;
                }

                if (0 == strcmp(argv[0], "vn") )
                {
                    Vector3 normal;
                    normal.x = (float)atof(argv[1]);
                    normal.y = (float)atof(argv[2]);
                    normal.z = (float)atof(argv[3]);

                    normals.push_back(normal);
                }
                else if (0 == strcmp(argv[0], "vp") )
                {
                    static bool once = true;
                    if (once)
                    {
                        once = false;
                        CS_PRINT("warning: 'parameter space vertices' are unsupported.\n");
                    }
                }
                else if (0 == strcmp(argv[0], "vt") )
                {
                    Vector3 texcoord;
                    texcoord.x = (float)atof(argv[1]);
                    texcoord.y = 0.0f;
                    texcoord.z = 0.0f;
                    switch (argc)
                    {
                    case 4:
                        texcoord.z = (float)atof(argv[3]);
                    // fallthrough
                    case 3:
                        texcoord.y = (float)atof(argv[2]);
                        break;

                    default:
                        break;
                    }

                    texcoords.push_back(texcoord);
                }
                else
                {
                    float px = (float)atof(argv[1]);
                    float py = (float)atof(argv[2]);
                    float pz = (float)atof(argv[3]);
                    float pw = 1.0f;
                    if (argc > 4)
                    {
                        pw = (float)atof(argv[4]);
                    }

                    float invW = _scale/pw;
                    px *= invW;
                    py *= invW;
                    pz *= invW;

                    Vector3 pos;
                    pos.x = px;
                    pos.y = py;
                    pos.z = pz;

                    positions.push_back(pos);
                }
            }
            else if (0 == strcmp(argv[0], "usemtl") )
            {
                std::string material(argv[1]);

                if (material != group.m_material)
                {
                    group.m_numTriangles = (uint32_t)(triangles.size() ) - group.m_startTriangle;
                    if (0 < group.m_numTriangles)
                    {
                        groups.push_back(group);
                        group.m_startTriangle = (uint32_t)(triangles.size() );
                        group.m_numTriangles = 0;
                    }
                }

                group.m_material = material;
            }
// unsupported tags
//              else if (0 == strcmp(argv[0], "mtllib") )
//              {
//              }
//              else if (0 == strcmp(argv[0], "o") )
//              {
//              }
//              else if (0 == strcmp(argv[0], "s") )
//              {
//              }
        }

        ++num;
    }
    while ('\0' != *next);

    group.m_numTriangles = (uint32_t)(triangles.size() ) - group.m_startTriangle;
    if (0 < group.m_numTriangles)
    {
        groups.push_back(group);
        group.m_startTriangle = (uint32_t)(triangles.size() );
        group.m_numTriangles = 0;
    }

    int64_t now = bx::getHPCounter();
    parseElapsed += now;
    int64_t convertElapsed = -now;

    std::sort(groups.begin(), groups.end(), GroupSortByMaterial() );

    bool hasColor = false;
    bool hasNormal;
    bool hasTexcoord;
    {
        Index3Map::const_iterator it = indexMap.begin();
        hasNormal   = 0 != it->second.m_normal;
        hasTexcoord = 0 != it->second.m_texcoord;

        if (!hasTexcoord
                &&  texcoords.size() == positions.size() )
        {
            hasTexcoord = true;

            for (Index3Map::iterator it = indexMap.begin(), itEnd = indexMap.end(); it != itEnd; ++it)
            {
                it->second.m_texcoord = it->second.m_position;
            }
        }

        if (!hasNormal
                &&  normals.size() == positions.size() )
        {
            hasNormal = true;

            for (Index3Map::iterator it = indexMap.begin(), itEnd = indexMap.end(); it != itEnd; ++it)
            {
                it->second.m_normal = it->second.m_position;
            }
        }
    }

    bgfx::VertexDecl decl;
    decl.begin();
    decl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);

    if (hasColor)
    {
        decl.add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true);
    }

    if (hasTexcoord)
    {
        switch (_packUv)
        {
        default:
        case 0:
            decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
            break;

        case 1:
            decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Half);
            break;
        }
    }

    if (hasNormal)
    {
        _hasTangent &= hasTexcoord;

        switch (_packNormal)
        {
        default:
        case 0:
            decl.add(bgfx::Attrib::Normal, 3, bgfx::AttribType::Float);
            if (_hasTangent)
            {
                decl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Float);
            }
            break;

        case 1:
            decl.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true, true);
            if (_hasTangent)
            {
                decl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Uint8, true, true);
            }
            break;
        }
    }
    decl.end();

    uint32_t stride = decl.getStride();
    uint8_t* vertexData = new uint8_t[triangles.size() * 3 * stride];
    uint16_t* indexData = new uint16_t[triangles.size() * 3];
    int32_t numVertices = 0;
    int32_t numIndices = 0;
    int32_t numPrimitives = 0;

    uint8_t* vertices = vertexData;
    uint16_t* indices = indexData;

    std::string material = groups.begin()->m_material;

    BgfxPrimitiveArray primitives;

    Primitive prim;
    prim.m_startVertex = 0;
    prim.m_startIndex  = 0;

    uint32_t positionOffset = decl.getOffset(bgfx::Attrib::Position);
    uint32_t color0Offset   = decl.getOffset(bgfx::Attrib::Color0);

    uint32_t ii = 0;
    for (BgfxGroupArray::const_iterator groupIt = groups.begin(); groupIt != groups.end(); ++groupIt, ++ii)
    {
        for (uint32_t tri = groupIt->m_startTriangle, end = tri + groupIt->m_numTriangles; tri < end; ++tri)
        {
            if (material != groupIt->m_material
                    ||  65533 < numVertices)
            {
                prim.m_numVertices = numVertices - prim.m_startVertex;
                prim.m_numIndices = numIndices - prim.m_startIndex;
                if (0 < prim.m_numVertices)
                {
                    primitives.push_back(prim);
                }

                triReorderElapsed -= bx::getHPCounter();
                for (BgfxPrimitiveArray::const_iterator primIt = primitives.begin(); primIt != primitives.end(); ++primIt)
                {
                    const Primitive& prim = *primIt;
                    triangleReorder(indexData + prim.m_startIndex, prim.m_numIndices, numVertices, 32);
                }
                triReorderElapsed += bx::getHPCounter();

                if (_hasTangent)
                {
                    calculateTangents(vertexData, numVertices, decl, indexData, numIndices);
                }

                write(_writer
                      , vertexData
                      , numVertices
                      , decl
                      , indexData
                      , numIndices
                      , material.c_str()
                      , primitives.data()
                      , (uint32_t)primitives.size()
                     );
                primitives.clear();

                for (Index3Map::iterator indexIt = indexMap.begin(); indexIt != indexMap.end(); ++indexIt)
                {
                    indexIt->second.m_vertexIndex = -1;
                }

                vertices = vertexData;
                indices = indexData;
                numVertices = 0;
                numIndices = 0;
                prim.m_startVertex = 0;
                prim.m_startIndex = 0;
                ++numPrimitives;

                material = groupIt->m_material;
            }

            Triangle& triangle = triangles[tri];
            for (uint32_t edge = 0; edge < 3; ++edge)
            {
                uint64_t hash = triangle.m_index[edge];
                Index3& index = indexMap[hash];
                if (index.m_vertexIndex == -1)
                {
                    index.m_vertexIndex = numVertices++;

                    float* position = (float*)(vertices + positionOffset);
                    memcpy(position, &positions[index.m_position], 3*sizeof(float) );

                    if (hasColor)
                    {
                        uint32_t* color0 = (uint32_t*)(vertices + color0Offset);
                        *color0 = rgbaToAbgr(numVertices%255, numIndices%255, 0, 0xff);
                    }

                    if (hasTexcoord)
                    {
                        float uv[2];
                        memcpy(uv, &texcoords[index.m_texcoord], 2*sizeof(float) );

                        if (_flipV)
                        {
                            uv[1] = -uv[1];
                        }

                        bgfx::vertexPack(uv, true, bgfx::Attrib::TexCoord0, decl, vertices);
                    }

                    if (hasNormal)
                    {
                        float normal[4];
                        bx::vec3Norm(normal, (float*)&normals[index.m_normal]);
                        bgfx::vertexPack(normal, true, bgfx::Attrib::Normal, decl, vertices);
                    }

                    vertices += stride;
                }

                *indices++ = (uint16_t)index.m_vertexIndex;
                ++numIndices;
            }
        }

        if (0 < numVertices)
        {
            prim.m_numVertices = numVertices - prim.m_startVertex;
            prim.m_numIndices = numIndices - prim.m_startIndex;
            bx::strlcpy(prim.m_name, groupIt->m_name.c_str(), 128);
            primitives.push_back(prim);
            prim.m_startVertex = numVertices;
            prim.m_startIndex = numIndices;
        }

        //CS_PRINT("%3d: s %5d, n %5d, %s\n"
        //    , ii
        //    , groupIt->m_startTriangle
        //    , groupIt->m_numTriangles
        //    , groupIt->m_material.c_str()
        //    );
    }

    if (0 < primitives.size() )
    {
        triReorderElapsed -= bx::getHPCounter();
        for (BgfxPrimitiveArray::const_iterator primIt = primitives.begin(); primIt != primitives.end(); ++primIt)
        {
            const Primitive& prim = *primIt;
            triangleReorder(indexData + prim.m_startIndex, prim.m_numIndices, numVertices, 32);
        }
        triReorderElapsed += bx::getHPCounter();

        if (_hasTangent)
        {
            calculateTangents(vertexData, numVertices, decl, indexData, numIndices);
        }

        write(_writer, vertexData, numVertices, decl, indexData, numIndices, material.c_str(), primitives.data(), (uint32_t)primitives.size());
    }

    delete [] indexData;
    delete [] vertexData;

    now = bx::getHPCounter();
    convertElapsed += now;

    const int64_t end = _writer->seek();
    const uint32_t dataSize = uint32_t(end-begin);
    CS_PRINT("size: %u\n", dataSize);

    CS_PRINT("parse %f [s]\ntri reorder %f [s]\nconvert %f [s]\n# %d, g %d, p %d, v %d, i %d\n"
             , double(parseElapsed)/bx::getHPFrequency()
             , double(triReorderElapsed)/bx::getHPFrequency()
             , double(convertElapsed)/bx::getHPFrequency()
             , num
             , uint32_t(groups.size() )
             , numPrimitives
             , numVertices
             , numIndices
            );

    return dataSize;
}
Ejemplo n.º 9
0
	void GlContext::create(uint32_t _width, uint32_t _height)
	{
		BX_UNUSED(_width, _height);
		XLockDisplay(s_display);

		int major, minor;
		bool version = glXQueryVersion(s_display, &major, &minor);
		BGFX_FATAL(version, Fatal::UnableToInitialize, "Failed to query GLX version");
		BGFX_FATAL( (major == 1 && minor >= 2) || major > 1
				, Fatal::UnableToInitialize
				, "GLX version is not >=1.2 (%d.%d)."
				, major
				, minor
				);

		int32_t screen = DefaultScreen(s_display);

		const char* extensions = glXQueryExtensionsString(s_display, screen);
		BX_TRACE("GLX extensions:");
		dumpExtensions(extensions);

		const int attrsGlx[] =
		{
			GLX_RENDER_TYPE, GLX_RGBA_BIT,
			GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
			GLX_DOUBLEBUFFER, true,
			GLX_RED_SIZE, 8,
			GLX_BLUE_SIZE, 8,
			GLX_GREEN_SIZE, 8,
//			GLX_ALPHA_SIZE, 8,
			GLX_DEPTH_SIZE, 24,
			GLX_STENCIL_SIZE, 8,
			0,
		};

		// Find suitable config
		GLXFBConfig bestConfig = NULL;

		int numConfigs;
		GLXFBConfig* configs = glXChooseFBConfig(s_display, screen, attrsGlx, &numConfigs);

		BX_TRACE("glX num configs %d", numConfigs);

		XVisualInfo* visualInfo = NULL;
		for (int ii = 0; ii < numConfigs; ++ii)
		{
			visualInfo = glXGetVisualFromFBConfig(s_display, configs[ii]);
			if (NULL != visualInfo)
			{
				BX_TRACE("---");
				bool valid = true;
				for (uint32_t attr = 6; attr < BX_COUNTOF(attrsGlx)-1 && attrsGlx[attr] != None; attr += 2)
				{
					int value;
					glXGetFBConfigAttrib(s_display, configs[ii], attrsGlx[attr], &value);
					BX_TRACE("glX %d/%d %2d: %4x, %8x (%8x%s)"
							, ii
							, numConfigs
							, attr/2
							, attrsGlx[attr]
							, value
							, attrsGlx[attr + 1]
							, value < attrsGlx[attr + 1] ? " *" : ""
							);

					if (value < attrsGlx[attr + 1])
					{
						valid = false;
#if !BGFX_CONFIG_DEBUG
						break;
#endif // BGFX_CONFIG_DEBUG
					}
				}

				if (valid)
				{
					bestConfig = configs[ii];
					BX_TRACE("Best config %d.", ii);
					break;
				}
			}

			XFree(visualInfo);
			visualInfo = NULL;
		}

		XFree(configs);
		BGFX_FATAL(visualInfo, Fatal::UnableToInitialize, "Failed to find a suitable X11 display configuration.");

		BX_TRACE("Create GL 2.1 context.");
		m_context = glXCreateContext(s_display, visualInfo, 0, GL_TRUE);
		BGFX_FATAL(NULL != m_context, Fatal::UnableToInitialize, "Failed to create GL 2.1 context.");

		XFree(visualInfo);

#if BGFX_CONFIG_RENDERER_OPENGL >= 31
		glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress( (const GLubyte*)"glXCreateContextAttribsARB");

		if (NULL != glXCreateContextAttribsARB)
		{
			BX_TRACE("Create GL 3.1 context.");
			const int contextAttrs[] =
			{
				GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
				GLX_CONTEXT_MINOR_VERSION_ARB, 1,
				GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
				0,
			};

			GLXContext context = glXCreateContextAttribsARB(s_display, bestConfig, 0, true, contextAttrs);

			if (NULL != context)
			{
				glXDestroyContext(s_display, m_context);
				m_context = context;
			}
		}
#else
		BX_UNUSED(bestConfig);
#endif // BGFX_CONFIG_RENDERER_OPENGL >= 31

		XUnlockDisplay(s_display);

		import();

		glXMakeCurrent(s_display, s_window, m_context);

		glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddress( (const GLubyte*)"glXSwapIntervalEXT");
		if (NULL != glXSwapIntervalEXT)
		{
			BX_TRACE("Using glXSwapIntervalEXT.");
			glXSwapIntervalEXT(s_display, s_window, 0);
		}
		else
		{
			glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress( (const GLubyte*)"glXSwapIntervalMESA");
			if (NULL != glXSwapIntervalMESA)
			{
				BX_TRACE("Using glXSwapIntervalMESA.");
				glXSwapIntervalMESA(0);
			}
			else
			{
				glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)glXGetProcAddress( (const GLubyte*)"glXSwapIntervalSGI");
				if (NULL != glXSwapIntervalSGI)
				{
					BX_TRACE("Using glXSwapIntervalSGI.");
					glXSwapIntervalSGI(0);
				}
			}
		}

		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		glXSwapBuffers(s_display, s_window);
	}
Ejemplo n.º 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 view 0 clear state.
	bgfx::setViewClear(0
		, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
		, 0x303030ff
		, 1.0f
		, 0
		);

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

	// Load some TTF files.
	const char* fontFilePath[7] =
	{
		"font/droidsans.ttf",
		"font/chp-fire.ttf",
		"font/bleeding_cowboys.ttf",
		"font/mias_scribblings.ttf",
		"font/ruritania.ttf",
		"font/signika-regular.ttf",
		"font/five_minutes.otf",
	};

	const uint32_t numFonts = BX_COUNTOF(fontFilePath);

	TrueTypeHandle fontFiles[numFonts];
	FontHandle fonts[numFonts];
	for (uint32_t ii = 0; ii < numFonts; ++ii)
	{
		// Instantiate a usable font.
		fontFiles[ii] = loadTtf(fontManager, fontFilePath[ii]);
		fonts[ii] = fontManager->createFontByPixelSize(fontFiles[ii], 0, 32);

		// Preload glyphs and blit them to atlas.
		fontManager->preloadGlyph(fonts[ii], L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ. \n");

		// You can unload the truetype files at this stage, but in that
		// case, the set of glyph's will be limited to the set of preloaded
		// glyph.
		fontManager->destroyTtf(fontFiles[ii]);
	}

	TrueTypeHandle fontAwesomeTtf = loadTtf(fontManager, "font/fontawesome-webfont.ttf");

	// This font doesn't have any preloaded glyph's but the truetype file
	// is loaded so glyph will be generated as needed.
	FontHandle fontAwesome72 = fontManager->createFontByPixelSize(fontAwesomeTtf, 0, 72);

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

	// This font doesn't have any preloaded glyph's but the truetype file
	// is loaded so glyph will be generated as needed.
	FontHandle visitor10 = fontManager->createFontByPixelSize(visitorTtf, 0, 10);

	//create a static text buffer compatible with alpha font
	//a static text buffer content cannot be modified after its first submit.
	TextBufferHandle staticText = textBufferManager->createTextBuffer(FONT_TYPE_ALPHA, BufferType::Static);

	// The pen position represent the top left of the box of the first line
	// of text.
	textBufferManager->setPenPosition(staticText, 24.0f, 100.0f);

	for (uint32_t ii = 0; ii < numFonts; ++ii)
	{
		// Add some text to the buffer.
		// The position of the pen is adjusted when there is an endline.
		textBufferManager->appendText(staticText, fonts[ii], L"The quick brown fox jumps over the lazy dog\n");
	}

	// Now write some styled text.

	// Setup style colors.
	textBufferManager->setBackgroundColor(staticText, 0x551111ff);
	textBufferManager->setUnderlineColor(staticText, 0xff2222ff);
	textBufferManager->setOverlineColor(staticText, 0x2222ffff);
	textBufferManager->setStrikeThroughColor(staticText, 0x22ff22ff);

	// Background.
	textBufferManager->setStyle(staticText, STYLE_BACKGROUND);
	textBufferManager->appendText(staticText, fonts[0], L"The quick ");

	// Strike-through.
	textBufferManager->setStyle(staticText, STYLE_STRIKE_THROUGH);
	textBufferManager->appendText(staticText, fonts[0], L"brown fox ");

	// Overline.
	textBufferManager->setStyle(staticText, STYLE_OVERLINE);
	textBufferManager->appendText(staticText, fonts[0], L"jumps over ");

	// Underline.
	textBufferManager->setStyle(staticText, STYLE_UNDERLINE);
	textBufferManager->appendText(staticText, fonts[0], L"the lazy ");

	// Background + strike-through.
	textBufferManager->setStyle(staticText, STYLE_BACKGROUND | STYLE_STRIKE_THROUGH);
	textBufferManager->appendText(staticText, fonts[0], L"dog\n");

	textBufferManager->setStyle(staticText, STYLE_NORMAL);
	textBufferManager->appendText(staticText, fontAwesome72, L"\xf011 \xf02e \xf061 \xf087 \xf0d9 \xf099 \xf05c \xf021 \xf113\n");

	// Create a transient buffer for real-time data.
	TextBufferHandle transientText = textBufferManager->createTextBuffer(FONT_TYPE_ALPHA, BufferType::Transient);

	while (!entry::processEvents(width, height, debug, reset) )
	{
		// 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::touch(0);

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

		// Use debug font to print information about this example.
		bgfx::dbgTextClear();
		bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/10-font");
		bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Use the font system to display text and styled text.");
		bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);

		// Use transient text to display debug information.
		wchar_t fpsText[64];
		bx::swnprintf(fpsText, BX_COUNTOF(fpsText), L"Frame: % 7.3f[ms]", double(frameTime) * toMs);

		textBufferManager->clearTextBuffer(transientText);
		textBufferManager->setPenPosition(transientText, width - 150.0f, 10.0f);
		textBufferManager->appendText(transientText, visitor10, L"Transient\n");
		textBufferManager->appendText(transientText, visitor10, L"text buffer\n");
		textBufferManager->appendText(transientText, visitor10, fpsText);

		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 offsetx = width/2.0f;
			bx::mtxOrtho(ortho[0], centering, offsetx + centering, height + centering, centering, -1.0f, 1.0f, offset0);
			bx::mtxOrtho(ortho[1], centering, offsetx + centering, 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);
		}

		// Submit the debug text.
		textBufferManager->submitTextBuffer(transientText, 0);

		// Submit the static text.
		textBufferManager->submitTextBuffer(staticText, 0);

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

	fontManager->destroyTtf(fontAwesomeTtf);
	fontManager->destroyTtf(visitorTtf);

	// Destroy the fonts.
	fontManager->destroyFont(fontAwesome72);
	fontManager->destroyFont(visitor10);
	for (uint32_t ii = 0; ii < numFonts; ++ii)
	{
		fontManager->destroyFont(fonts[ii]);
	}

	textBufferManager->destroyTextBuffer(staticText);
	textBufferManager->destroyTextBuffer(transientText);

	delete textBufferManager;
	delete fontManager;

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

	return 0;
}
Ejemplo n.º 11
0
namespace window {

struct Window
{
	float aspectRatio;
	bool isFullscreen;
	int refreshRate;
	int width = 0, height = 0;
};

static Window s_window;
static SDL_Window *SDL_window = NULL;
static float displayAspect = 0.0f;

struct VideoMode
{
	const char *description;
	int width, height;
	float pixelAspect;
};

static VideoMode r_vidModes[] =
{
	{ "Mode  0: 320x240",		320,	240,	1 },
	{ "Mode  1: 400x300",		400,	300,	1 },
	{ "Mode  2: 512x384",		512,	384,	1 },
	{ "Mode  3: 640x480",		640,	480,	1 },
	{ "Mode  4: 800x600",		800,	600,	1 },
	{ "Mode  5: 960x720",		960,	720,	1 },
	{ "Mode  6: 1024x768",		1024,	768,	1 },
	{ "Mode  7: 1152x864",		1152,	864,	1 },
	{ "Mode  8: 1280x1024",		1280,	1024,	1 },
	{ "Mode  9: 1600x1200",		1600,	1200,	1 },
	{ "Mode 10: 2048x1536",		2048,	1536,	1 },
	{ "Mode 11: 856x480 (wide)",856,	480,	1 }
};

static int s_numVidModes = BX_COUNTOF(r_vidModes);

enum class SetModeResult
{
	OK,
	InvalidFullScreen,
	InvalidMode,
	Unknown
};

static bool GetModeInfo(int mode)
{
	if (mode < -1)
		return false;
	if (mode >= s_numVidModes)
		return false;

	float pixelAspect;

	if (mode == -1)
	{
		s_window.width = g_cvars.customwidth.getInt();
		s_window.height = g_cvars.customheight.getInt();
		pixelAspect = g_cvars.customPixelAspect.getFloat();
	}
	else
	{
		const VideoMode &vm = r_vidModes[mode];
		s_window.width  = vm.width;
		s_window.height = vm.height;
		pixelAspect = vm.pixelAspect;
	}

	s_window.aspectRatio = s_window.width / (s_window.height * pixelAspect);
	return true;
}

static SetModeResult SetMode(int mode, bool fullscreen, bool noborder)
{
	interface::Printf("Initializing display\n");
	Uint32 flags = SDL_WINDOW_SHOWN;

	if (g_cvars.allowResize.getBool())
		flags |= SDL_WINDOW_RESIZABLE;

	SDL_Surface *icon = NULL;
	
#ifdef USE_ICON
	icon = SDL_CreateRGBSurfaceFrom(
			(void *)CLIENT_WINDOW_ICON.pixel_data,
			CLIENT_WINDOW_ICON.width,
			CLIENT_WINDOW_ICON.height,
			CLIENT_WINDOW_ICON.bytes_per_pixel * 8,
			CLIENT_WINDOW_ICON.bytes_per_pixel * CLIENT_WINDOW_ICON.width,
#ifdef Q3_LITTLE_ENDIAN
			0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
#else
			0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
#endif
			);
#endif

	// If a window exists, note its display index
	int display = 0;

	if (SDL_window != NULL)
		display = SDL_GetWindowDisplayIndex(SDL_window);

	SDL_DisplayMode desktopMode;

	// Get the display aspect ratio
	if (SDL_GetDesktopDisplayMode(display, &desktopMode) == 0)
	{
		displayAspect = desktopMode.w / (float)desktopMode.h;
		interface::Printf("Display aspect: %.3f\n", displayAspect);
	}
	else
	{
		memset(&desktopMode, 0, sizeof(SDL_DisplayMode));
		interface::Printf("Cannot determine display aspect, assuming 1.333\n");
	}

	interface::Printf("...setting mode %d:", mode );

	if (mode == -2)
	{
		// use desktop video resolution
		if( desktopMode.h > 0 )
		{
			s_window.width = desktopMode.w;
			s_window.height = desktopMode.h;
		}
		else
		{
			s_window.width = 640;
			s_window.height = 480;
			interface::Printf("Cannot determine display resolution, assuming 640x480\n");
		}

		s_window.aspectRatio = s_window.width / (float)s_window.height;
	}
	else if (!GetModeInfo(mode))
	{
		interface::Printf(" invalid mode\n");
		return SetModeResult::InvalidMode;
	}

	interface::Printf(" %d %d\n", s_window.width, s_window.height);

	// Center window
	int x = SDL_WINDOWPOS_UNDEFINED, y = SDL_WINDOWPOS_UNDEFINED;

	if (SDL_window != NULL)
	{
		SDL_GetWindowPosition(SDL_window, &x, &y);
		interface::PrintDeveloperf("Existing window at %dx%d before being destroyed\n", x, y);
		SDL_DestroyWindow(SDL_window);
		SDL_window = NULL;
	}

	if (fullscreen)
	{
		flags |= SDL_WINDOW_FULLSCREEN;
		s_window.isFullscreen = true;
	}
	else
	{
		if (noborder)
			flags |= SDL_WINDOW_BORDERLESS;

		s_window.isFullscreen = false;
	}

	if (g_cvars.centerWindow.getBool() && !s_window.isFullscreen)
	{
		x = y = SDL_WINDOWPOS_CENTERED;
	}
	
	if ((SDL_window = SDL_CreateWindow(CLIENT_WINDOW_TITLE, x, y, s_window.width, s_window.height, flags)) == 0)
	{
		interface::PrintDeveloperf("SDL_CreateWindow failed: %s\n", SDL_GetError());
		goto finished;
	}

	if (fullscreen)
	{
		SDL_DisplayMode mode;
		mode.format = SDL_PIXELFORMAT_RGB24;
		mode.w = s_window.width;
		mode.h = s_window.height;
		mode.refresh_rate = s_window.refreshRate = interface::Cvar_GetInteger("r_displayRefresh");
		mode.driverdata = NULL;

		if (SDL_SetWindowDisplayMode(SDL_window, &mode) < 0)
		{
			interface::PrintDeveloperf("SDL_SetWindowDisplayMode failed: %s\n", SDL_GetError());
			goto finished;
		}
	}

	SDL_SetWindowIcon(SDL_window, icon);

finished:
	SDL_FreeSurface(icon);

	if (!SDL_window)
	{
		interface::Printf("Couldn't get a visual\n");
		return SetModeResult::InvalidMode;
	}

	return SetModeResult::OK;
}

static bool StartDriverAndSetMode(int mode, bool fullscreen, bool noborder)
{
	if (!SDL_WasInit(SDL_INIT_VIDEO))
	{
		if (SDL_Init(SDL_INIT_VIDEO) == -1)
		{
			interface::Printf("SDL_Init( SDL_INIT_VIDEO ) FAILED (%s)\n", SDL_GetError());
			return false;
		}

		const char *driverName = SDL_GetCurrentVideoDriver();
		interface::Printf("SDL using driver \"%s\"\n", driverName);
		interface::Cvar_Set("r_sdlDriver", driverName);
	}

	if (fullscreen && interface::Cvar_GetInteger("in_nograb"))
	{
		interface::Printf("Fullscreen not allowed with in_nograb 1\n");
		interface::Cvar_Set( "r_fullscreen", "0" );
		g_cvars.fullscreen.clearModified();
		fullscreen = false;
	}
	
	switch (SetMode(mode, fullscreen, noborder))
	{
	case SetModeResult::InvalidFullScreen:
		interface::Printf("...WARNING: fullscreen unavailable in this mode\n");
		return false;
	case SetModeResult::InvalidMode:
		interface::Printf("...WARNING: could not set the given mode (%d)\n", mode);
		return false;
	default:
		break;
	}

	return true;
}

float GetAspectRatio()
{
	return s_window.aspectRatio;
}

int GetRefreshRate()
{
	return s_window.refreshRate;
}

int GetWidth()
{
	return s_window.width;
}

int GetHeight()
{
	return s_window.height;
}

int IsFullscreen()
{
	return s_window.isFullscreen;
}

void Initialize()
{
	if (interface::Cvar_GetInteger("com_abnormalExit"))
	{
		interface::Cvar_Set("r_mode", util::VarArgs("%d", R_MODE_FALLBACK));
		interface::Cvar_Set("r_fullscreen", "0");
		interface::Cvar_Set("r_centerWindow", "0");
		interface::Cvar_Set("com_abnormalExit", "0");
	}

	// Create the window and set up the context
	if (StartDriverAndSetMode(g_cvars.mode.getInt(), g_cvars.fullscreen.getBool(), g_cvars.noborder.getBool()))
		goto success;

	if (g_cvars.noborder.getBool())
	{
		// Try again with a window border
		if (StartDriverAndSetMode(g_cvars.mode.getInt(), g_cvars.fullscreen.getBool(), false))
			goto success;
	}

	// Finally, try the default screen resolution
	if (g_cvars.mode.getInt() != R_MODE_FALLBACK)
	{
		interface::Printf("Setting r_mode %d failed, falling back on r_mode %d\n", g_cvars.mode.getInt(), R_MODE_FALLBACK);

		if (StartDriverAndSetMode(R_MODE_FALLBACK, false, false))
			goto success;
	}

	// Nothing worked, give up
	interface::FatalError("Could not load OpenGL subsystem");

success:
	// This depends on SDL_INIT_VIDEO, hence having it here
	interface::IN_Init(SDL_window);

	SDL_SysWMinfo wmi;
	SDL_VERSION(&wmi.version);
	
	if (SDL_GetWindowWMInfo(SDL_window, &wmi) == SDL_FALSE)
	{
		interface::FatalError("SDL_GetWindowWMInfo: %s", SDL_GetError());
	}

	bgfx::PlatformData pd = {};
#ifdef WIN32
	pd.nwh = wmi.info.win.window;
#else
	pd.ndt = wmi.info.x11.display;
	pd.nwh = (void*)(uintptr_t)wmi.info.x11.window;
#endif
	bgfx::setPlatformData(pd);
}

void SetGamma(const uint8_t *red, const uint8_t *green, const uint8_t *blue)
{
	uint16_t table[3][256];

	for (int i = 0; i < 256; i++)
	{
		table[0][i] = (((uint16_t)red[i]) << 8) | red[i];
		table[1][i] = (((uint16_t)green[i]) << 8) | green[i];
		table[2][i] = (((uint16_t)blue[i]) << 8) | blue[i];
	}

#ifdef _WIN32
	// Win2K and newer put this odd restriction on gamma ramps...
	for (int j = 0; j < 3; j++)
	{
		for (int i = 0; i < 128; i++)
		{
			if (table[j][i] >((128 + i) << 8))
				table[j][i] = (128 + i) << 8;
		}

		if (table[j][127] > 254 << 8)
			table[j][127] = 254 << 8;
	}
#endif

	// enforce constantly increasing
	for (int j = 0; j < 3; j++)
	{
		for (int i = 1; i < 256; i++)
		{
			if (table[j][i] < table[j][i - 1])
				table[j][i] = table[j][i - 1];
		}
	}

	if (SDL_SetWindowGammaRamp(SDL_window, table[0], table[1], table[2]) < 0)
	{
		interface::PrintWarningf("SDL_SetWindowGammaRamp() failed: %s\n", SDL_GetError());
	}
}


void Shutdown()
{
	interface::IN_Shutdown();
	SDL_QuitSubSystem(SDL_INIT_VIDEO);
}

} // namespace window
Ejemplo n.º 12
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);

	bgfx::RendererType::Enum renderer = bgfx::getRendererType();
	bool flipV = false
		|| renderer == bgfx::RendererType::OpenGL
		|| renderer == bgfx::RendererType::OpenGLES
		;

	// Enable debug text.
	bgfx::setDebug(debug);

	// Uniforms.
	bgfx::UniformHandle u_shadowMap = bgfx::createUniform("u_shadowMap", bgfx::UniformType::Int1);
	bgfx::UniformHandle u_lightPos  = bgfx::createUniform("u_lightPos",  bgfx::UniformType::Vec4);
	bgfx::UniformHandle u_lightMtx  = bgfx::createUniform("u_lightMtx",  bgfx::UniformType::Mat4);

	// Vertex declarations.
	bgfx::VertexDecl PosNormalDecl;
	PosNormalDecl.begin()
		.add(bgfx::Attrib::Position,  3, bgfx::AttribType::Float)
		.add(bgfx::Attrib::Normal,    4, bgfx::AttribType::Uint8, true, true)
		.end();

	// Meshes.
	Mesh* bunny      = meshLoad("meshes/bunny.bin");
	Mesh* cube       = meshLoad("meshes/cube.bin");
	Mesh* hollowcube = meshLoad("meshes/hollowcube.bin");

	bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer(
			  bgfx::makeRef(s_hplaneVertices, sizeof(s_hplaneVertices) )
			, PosNormalDecl
			);

	bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(
			bgfx::makeRef(s_planeIndices, sizeof(s_planeIndices) )
			);

	// Render targets.
	uint16_t shadowMapSize = 512;

	// Get renderer capabilities info.
	const bgfx::Caps* caps = bgfx::getCaps();
	// Shadow samplers are supported at least partially supported if texture
	// compare less equal feature is supported.
	bool shadowSamplerSupported = 0 != (caps->supported & BGFX_CAPS_TEXTURE_COMPARE_LEQUAL);

	bgfx::ProgramHandle progShadow;
	bgfx::ProgramHandle progMesh;
	bgfx::TextureHandle shadowMapTexture;
	bgfx::FrameBufferHandle shadowMapFB;

	if (shadowSamplerSupported)
	{
		// Depth textures and shadow samplers are supported.
		progShadow = loadProgram("vs_sms_shadow", "fs_sms_shadow");
		progMesh   = loadProgram("vs_sms_mesh",   "fs_sms_mesh");

		shadowMapTexture = bgfx::createTexture2D(shadowMapSize, shadowMapSize, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_COMPARE_LEQUAL);
		bgfx::TextureHandle fbtextures[] = { shadowMapTexture };
		shadowMapFB = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
	}
	else
	{
		// Depth textures and shadow samplers are not supported. Use float
		// depth packing into color buffer instead.
		progShadow = loadProgram("vs_sms_shadow_pd", "fs_sms_shadow_pd");
		progMesh   = loadProgram("vs_sms_mesh",      "fs_sms_mesh_pd");

		shadowMapTexture = bgfx::createTexture2D(shadowMapSize, shadowMapSize, 1, bgfx::TextureFormat::BGRA8, BGFX_TEXTURE_RT);
		bgfx::TextureHandle fbtextures[] =
		{
			shadowMapTexture,
			bgfx::createTexture2D(shadowMapSize, shadowMapSize, 1, bgfx::TextureFormat::D16, BGFX_TEXTURE_RT_BUFFER_ONLY),
		};
		shadowMapFB = bgfx::createFrameBuffer(BX_COUNTOF(fbtextures), fbtextures, true);
	}

	MeshState* state[2];
	state[0] = meshStateCreate();
	state[0]->m_state = 0
				| BGFX_STATE_RGB_WRITE
				| BGFX_STATE_ALPHA_WRITE
				| BGFX_STATE_DEPTH_WRITE
				| BGFX_STATE_DEPTH_TEST_LESS
				| BGFX_STATE_CULL_CCW
				| BGFX_STATE_MSAA
				;
	state[0]->m_program = progShadow;
	state[0]->m_viewId  = RENDER_SHADOW_PASS_ID;
	state[0]->m_numTextures = 0;

	state[1] = meshStateCreate();
	state[1]->m_state = 0
				| BGFX_STATE_RGB_WRITE
				| BGFX_STATE_ALPHA_WRITE
				| BGFX_STATE_DEPTH_WRITE
				| BGFX_STATE_DEPTH_TEST_LESS
				| BGFX_STATE_CULL_CCW
				| BGFX_STATE_MSAA
				;
	state[1]->m_program = progMesh;
	state[1]->m_viewId  = RENDER_SCENE_PASS_ID;
	state[1]->m_numTextures = 1;
	state[1]->m_textures[0].m_flags = UINT32_MAX;
	state[1]->m_textures[0].m_stage = 0;
	state[1]->m_textures[0].m_sampler = u_shadowMap;
	state[1]->m_textures[0].m_texture = shadowMapTexture;

	// Set view and projection matrices.
	float view[16];
	float proj[16];

	float eye[3] = { 0.0f, 30.0f, -60.0f };
	float at[3]  = { 0.0f,  5.0f,   0.0f };
	bx::mtxLookAt(view, eye, at);

	const float aspect = float(int32_t(width) ) / float(int32_t(height) );
	bx::mtxProj(proj, 60.0f, aspect, 0.1f, 1000.0f, flipV);

	// Time acumulators.
	float timeAccumulatorLight = 0.0f;
	float timeAccumulatorScene = 0.0f;

	entry::MouseState mouseState;
	while (!entry::processEvents(width, height, debug, reset, &mouseState) )
	{
		// Time.
		int64_t now = bx::getHPCounter();
		static int64_t last = now;
		const int64_t frameTime = now - last;
		last = now;
		const double freq = double(bx::getHPFrequency() );
		const double toMs = 1000.0/freq;
		const float deltaTime = float(frameTime/freq);

		// Update time accumulators.
		timeAccumulatorLight += deltaTime;
		timeAccumulatorScene += deltaTime;

		// Use debug font to print information about this example.
		bgfx::dbgTextClear();
		bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/15-shadowmaps-simple");
		bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Shadow maps example (technique: %s).", shadowSamplerSupported ? "depth texture and shadow samplers" : "shadow depth packed into color texture");
		bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);

		// Setup lights.
		float lightPos[4];
		lightPos[0] = -cosf(timeAccumulatorLight);
		lightPos[1] = -1.0f;
		lightPos[2] = -sinf(timeAccumulatorLight);
		lightPos[3] = 0.0f;

		bgfx::setUniform(u_lightPos, lightPos);

		// Setup instance matrices.
		float mtxFloor[16];
		bx::mtxSRT(mtxFloor
			, 30.0f, 30.0f, 30.0f
			, 0.0f, 0.0f, 0.0f
			, 0.0f, 0.0f, 0.0f
			);

		float mtxBunny[16];
		bx::mtxSRT(mtxBunny
			, 5.0f, 5.0f, 5.0f
			, 0.0f, bx::pi - timeAccumulatorScene, 0.0f
			, 15.0f, 5.0f, 0.0f
			);

		float mtxHollowcube[16];
		bx::mtxSRT(mtxHollowcube
			, 2.5f, 2.5f, 2.5f
			, 0.0f, 1.56f - timeAccumulatorScene, 0.0f
			, 0.0f, 10.0f, 0.0f
			);

		float mtxCube[16];
		bx::mtxSRT(mtxCube
			, 2.5f, 2.5f, 2.5f
			, 0.0f, 1.56f - timeAccumulatorScene, 0.0f
			, -15.0f, 5.0f, 0.0f
			);

		// Define matrices.
		float lightView[16];
		float lightProj[16];

		eye[0] = -lightPos[0];
		eye[1] = -lightPos[1];
		eye[2] = -lightPos[2];

		at[0] = 0.0f;
		at[1] = 0.0f;
		at[2] = 0.0f;

		bx::mtxLookAt(lightView, eye, at);

		const float area = 30.0f;
		bx::mtxOrtho(lightProj, -area, area, -area, area, -100.0f, 100.0f);

		bgfx::setViewRect(RENDER_SHADOW_PASS_ID, 0, 0, shadowMapSize, shadowMapSize);
		bgfx::setViewFrameBuffer(RENDER_SHADOW_PASS_ID, shadowMapFB);
		bgfx::setViewTransform(RENDER_SHADOW_PASS_ID, lightView, lightProj);

		bgfx::setViewRect(RENDER_SCENE_PASS_ID, 0, 0, width, height);
		bgfx::setViewTransform(RENDER_SCENE_PASS_ID, view, proj);

		// Clear backbuffer and shadowmap framebuffer at beginning.
		bgfx::setViewClear(RENDER_SHADOW_PASS_ID
			, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
			, 0x303030ff, 1.0f, 0
			);

		bgfx::setViewClear(RENDER_SCENE_PASS_ID
			, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH
			, 0x303030ff, 1.0f, 0
			);

		// Render.
		float mtxShadow[16];
		float lightMtx[16];

		const float sy = flipV ? 0.5f : -0.5f;
		const float mtxCrop[16] =
		{
			0.5f, 0.0f, 0.0f, 0.0f,
			0.0f,   sy, 0.0f, 0.0f,
			0.0f, 0.0f, 0.5f, 0.0f,
			0.5f, 0.5f, 0.5f, 1.0f,
		};

		float mtxTmp[16];
		bx::mtxMul(mtxTmp,    lightProj, mtxCrop);
		bx::mtxMul(mtxShadow, lightView, mtxTmp);

		// Floor.
		bx::mtxMul(lightMtx, mtxFloor, mtxShadow);
		uint32_t cached = bgfx::setTransform(mtxFloor);
		for (uint32_t pass = 0; pass < 2; ++pass)
		{
			const MeshState& st = *state[pass];
			bgfx::setTransform(cached);
			for (uint8_t tex = 0; tex < st.m_numTextures; ++tex)
			{
				const MeshState::Texture& texture = st.m_textures[tex];
				bgfx::setTexture(texture.m_stage
						, texture.m_sampler
						, texture.m_texture
						, texture.m_flags
						);
			}
			bgfx::setUniform(u_lightMtx, lightMtx);
			bgfx::setIndexBuffer(ibh);
			bgfx::setVertexBuffer(vbh);
			bgfx::setState(st.m_state);
			bgfx::submit(st.m_viewId, st.m_program);
		}

		// Bunny.
		bx::mtxMul(lightMtx, mtxBunny, mtxShadow);
		bgfx::setUniform(u_lightMtx, lightMtx);
		meshSubmit(bunny, &state[0], 1, mtxBunny);
		bgfx::setUniform(u_lightMtx, lightMtx);
		meshSubmit(bunny, &state[1], 1, mtxBunny);

		// Hollow cube.
		bx::mtxMul(lightMtx, mtxHollowcube, mtxShadow);
		bgfx::setUniform(u_lightMtx, lightMtx);
		meshSubmit(hollowcube, &state[0], 1, mtxHollowcube);
		bgfx::setUniform(u_lightMtx, lightMtx);
		meshSubmit(hollowcube, &state[1], 1, mtxHollowcube);

		// Cube.
		bx::mtxMul(lightMtx, mtxCube, mtxShadow);
		bgfx::setUniform(u_lightMtx, lightMtx);
		meshSubmit(cube, &state[0], 1, mtxCube);
		bgfx::setUniform(u_lightMtx, lightMtx);
		meshSubmit(cube, &state[1], 1, mtxCube);

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

	meshUnload(bunny);
	meshUnload(cube);
	meshUnload(hollowcube);

	meshStateDestroy(state[0]);
	meshStateDestroy(state[1]);

	bgfx::destroyVertexBuffer(vbh);
	bgfx::destroyIndexBuffer(ibh);

	bgfx::destroyProgram(progShadow);
	bgfx::destroyProgram(progMesh);

	bgfx::destroyFrameBuffer(shadowMapFB);

	bgfx::destroyUniform(u_shadowMap);
	bgfx::destroyUniform(u_lightPos);
	bgfx::destroyUniform(u_lightMtx);

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

	return 0;
}
Ejemplo n.º 13
0
PP_EXPORT int32_t PPP_InitializeModule(PP_Module /*_module*/, PPB_GetInterface /*_interface*/)
{
	DBG("PPAPI version: %d", PPAPI_RELEASE);
	runAllTests(BX_COUNTOF(s_argv), s_argv);
	return PP_ERROR_NOINTERFACE;
}
Ejemplo n.º 14
0
namespace visef
{
    static const char* s_scancodeNames[] = {
        "A",
        "B",
        "C",
        "D",
        "E",
        "F",
        "G",
        "H",
        "I",
        "J",
        "K",
        "L",
        "M",
        "N",
        "O",
        "P",
        "Q",
        "R",
        "S",
        "T",
        "U",
        "V",
        "W",
        "X",
        "Y",
        "Z",
        "0",
        "1",
        "2",
        "3",
        "4",
        "5",
        "6",
        "7",
        "8",
        "9",
        "F1",
        "F2",
        "F3",
        "F4",
        "F5",
        "F6",
        "F7",
        "F8",
        "F9",
        "F10",
        "F11",
        "F12",
        "F13",
        "F14",
        "F15",
        "F16",
        "F17",
        "F18",
        "F19",
        "F20",
        "F21",
        "F22",
        "F23",
        "F24",
        "Keypad 0",
        "Keypad 1",
        "Keypad 2",
        "Keypad 3",
        "Keypad 4",
        "Keypad 5",
        "Keypad 6",
        "Keypad 7",
        "Keypad 8",
        "Keypad 9",
        "Escape",
        "Left Control",
        "Left Shift",
        "Left Alt",
        "Left System",
        "Right Control",
        "Right Shift",
        "Right Alt",
        "Right System",
        "Menu",
        "Return",
        "Tab",
        "Backspace",
        "Space",
        "Up",
        "Down",
        "Left",
        "Right",
        "Insert",
        "Delete",
        "Home",
        "End",
        "PageUp",
        "PageDown",
        "Print",
        "Plus",
        "Minus",
        "LeftBracket",
        "RightBracket",
        "Semicolon",
        "Quote",
        "Comma",
        "Period",
        "Slash",
        "Backslash",
        "Tilde",
        "CapsLock",
        "ScrollLock",
        "Multiply",
        "Divide",
        "Pause",
        "Add",
        "Subtract",
        "Numlock",
        "Application"
    };

    static_assert(BX_COUNTOF(s_scancodeNames) == Key::Count, "Invalid amount of scan codes");

    const char* getKeyName(uint8_t key)
    {
        VE_ASSERT(key < Key::Count, "Key out of bounds");
        return s_scancodeNames[key];
    }

    InputDevice::InputDevice(uint8_t numKeys) :
        m_numButtons(numKeys)
    {
        VE_ASSERT(numKeys < MaxKeys, "Too many keys");
        memset(m_state, 0, sizeof(m_state));
        memset(m_lastState, 0, sizeof(m_lastState));
    }

    InputDevice::~InputDevice() {}

    void InputDevice::update()
    {
        memcpy(m_lastState, m_state, sizeof(uint8_t) * m_numButtons);
    }

    bool InputDevice::isPressed(uint8_t key) const
    {
        VE_ASSERT(key < m_numButtons, "Key out of bounds");
        // ~0 = 1, ~1 = 0
        // if m_lastState == 0 && m_state == 1
        return (~m_lastState[key] & m_state[key]) != 0;
    }

    bool InputDevice::isReleased(uint8_t key) const
    {
        VE_ASSERT(key < m_numButtons, "Key out of bounds");
        // ~0 = 1, ~1 = 0
        // if m_lastState == 1 && m_state == 0
        return (m_lastState[key] & ~m_state[key]) != 0;
    }

    void InputDevice::setKeyState(uint8_t key, bool state)
    {
        VE_ASSERT(key < m_numButtons, "Key out of bounds");
        m_state[key] = state;
    }
}
Ejemplo n.º 15
0
void drawBlendish(struct NVGcontext* _vg, float _x, float _y, float _w, float _h, float _t)
{
	float x = _x;
	float y = _y;

	bndBackground(_vg, _x - 10.0f, _y - 10.0f, _w, _h);

	bndToolButton(_vg, x, y, 120.0f, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_DEFAULT, BND_ICONID(6, 3), "Default");
	y += 25.0f;
	bndToolButton(_vg, x, y, 120.0f, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_HOVER, BND_ICONID(6, 3), "Hovered");
	y += 25.0f;
	bndToolButton(_vg, x, y, 120.0f, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_ACTIVE, BND_ICONID(6, 3), "Active");

	y += 40.0f;
	bndRadioButton(_vg, x, y, 80.0f, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_DEFAULT, -1, "Default");
	y += 25.0f;
	bndRadioButton(_vg, x, y, 80.0f, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_HOVER, -1, "Hovered");
	y += 25.0f;
	bndRadioButton(_vg, x, y, 80.0f, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_ACTIVE, -1, "Active");

	y += 25.0f;
	bndLabel(_vg, x, y, 120.0f, BND_WIDGET_HEIGHT, -1, "Label:");
	y += BND_WIDGET_HEIGHT;
	bndChoiceButton(_vg, x, y, 80.0f, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_DEFAULT, -1, "Default");
	y += 25.0f;
	bndChoiceButton(_vg, x, y, 80.0f, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_HOVER, -1, "Hovered");
	y += 25.0f;
	bndChoiceButton(_vg, x, y, 80.0f, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_ACTIVE, -1, "Active");

	y += 25.0f;
	float ry = y;
	float rx = x;

	y = _y;
	x += 130.0f;
	bndOptionButton(_vg, x, y, 120.0f, BND_WIDGET_HEIGHT, BND_DEFAULT, "Default");
	y += 25.0f;
	bndOptionButton(_vg, x, y, 120.0f, BND_WIDGET_HEIGHT, BND_HOVER, "Hovered");
	y += 25.0f;
	bndOptionButton(_vg, x, y, 120.0f, BND_WIDGET_HEIGHT, BND_ACTIVE, "Active");

	y += 40.0f;
	bndNumberField(_vg, x, y, 120.0f, BND_WIDGET_HEIGHT, BND_CORNER_DOWN, BND_DEFAULT, "Top", "100");
	y += BND_WIDGET_HEIGHT - 2.0f;
	bndNumberField(_vg, x, y, 120.0f, BND_WIDGET_HEIGHT, BND_CORNER_ALL, BND_DEFAULT, "Center", "100");
	y += BND_WIDGET_HEIGHT - 2.0f;
	bndNumberField(_vg, x, y, 120.0f, BND_WIDGET_HEIGHT, BND_CORNER_TOP, BND_DEFAULT, "Bottom", "100");

	float mx = x - 30.0f;
	float my = y - 12.0f;
	float mw = 120.0f;
	bndMenuBackground(_vg, mx, my, mw, 120.0f, BND_CORNER_TOP);
	bndMenuLabel(_vg, mx, my, mw, BND_WIDGET_HEIGHT, -1, "Menu Title");
	my += BND_WIDGET_HEIGHT - 2.0f;
	bndMenuItem(_vg, mx, my, mw, BND_WIDGET_HEIGHT, BND_DEFAULT, BND_ICONID(17, 3), "Default");
	my += BND_WIDGET_HEIGHT - 2.0f;
	bndMenuItem(_vg, mx, my, mw, BND_WIDGET_HEIGHT, BND_HOVER, BND_ICONID(18, 3), "Hovered");
	my += BND_WIDGET_HEIGHT - 2.0f;
	bndMenuItem(_vg, mx, my, mw, BND_WIDGET_HEIGHT, BND_ACTIVE, BND_ICONID(19, 3), "Active");

	y = _y;
	x += 130.0f;
	float ox = x;
	bndNumberField(_vg, x, y, 120.0f, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_DEFAULT, "Default", "100");
	y += 25.0f;
	bndNumberField(_vg, x, y, 120.0f, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_HOVER, "Hovered", "100");
	y += 25.0f;
	bndNumberField(_vg, x, y, 120.0f, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_ACTIVE, "Active", "100");

	y += 40.0f;
	bndRadioButton(_vg, x, y, 60.0f, BND_WIDGET_HEIGHT, BND_CORNER_RIGHT, BND_DEFAULT, -1, "One");
	x += 60.0f - 1.0f;
	bndRadioButton(_vg, x, y, 60.0f, BND_WIDGET_HEIGHT, BND_CORNER_ALL, BND_DEFAULT, -1, "Two");
	x += 60.0f - 1.0f;
	bndRadioButton(_vg, x, y, 60.0f, BND_WIDGET_HEIGHT, BND_CORNER_ALL, BND_DEFAULT, -1, "Three");
	x += 60.0f - 1.0f;
	bndRadioButton(_vg, x, y, 60.0f, BND_WIDGET_HEIGHT, BND_CORNER_LEFT, BND_ACTIVE, -1, "Butts");

	x = ox;
	y += 40.0f;
	float progress_value = fmodf(_t / 10.0f, 1.0f);
	char progress_label[32];
	bx::snprintf(progress_label, BX_COUNTOF(progress_label), "%d%%", int(progress_value * 100 + 0.5f) );
	bndSlider(_vg, x, y, 240, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_DEFAULT, progress_value, "Default", progress_label);
	y += 25.0f;
	bndSlider(_vg, x, y, 240, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_HOVER, progress_value, "Hovered", progress_label);
	y += 25.0f;
	bndSlider(_vg, x, y, 240, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_ACTIVE, progress_value, "Active", progress_label);

	float rw = x + 240.0f - rx;
	float s_offset = sinf(_t / 2.0f) * 0.5f + 0.5f;
	float s_size = cosf(_t / 3.11f) * 0.5f + 0.5f;

	bndScrollBar(_vg, rx, ry, rw, BND_SCROLLBAR_HEIGHT, BND_DEFAULT, s_offset, s_size);
	ry += 20.0f;
	bndScrollBar(_vg, rx, ry, rw, BND_SCROLLBAR_HEIGHT, BND_HOVER, s_offset, s_size);
	ry += 20.0f;
	bndScrollBar(_vg, rx, ry, rw, BND_SCROLLBAR_HEIGHT, BND_ACTIVE, s_offset, s_size);

	const char edit_text[] = "The quick brown fox";
	int textlen = int(strlen(edit_text) + 1);
	int t = int(_t * 2);
	int idx1 = (t / textlen) % textlen;
	int idx2 = idx1 + (t % (textlen - idx1) );

	ry += 25.0f;
	bndTextField(_vg, rx, ry, 240.0f, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_DEFAULT, -1, edit_text, idx1, idx2);
	ry += 25.0f;
	bndTextField(_vg, rx, ry, 240.0f, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_HOVER, -1, edit_text, idx1, idx2);
	ry += 25.0f;
	bndTextField(_vg, rx, ry, 240.0f, BND_WIDGET_HEIGHT, BND_CORNER_NONE, BND_ACTIVE, -1, edit_text, idx1, idx2);

	rx += rw + 20.0f;
	ry = _y;
	bndScrollBar(_vg, rx, ry, BND_SCROLLBAR_WIDTH, 240.0f, BND_DEFAULT, s_offset, s_size);
	rx += 20.0f;
	bndScrollBar(_vg, rx, ry, BND_SCROLLBAR_WIDTH, 240.0f, BND_HOVER, s_offset, s_size);
	rx += 20.0f;
	bndScrollBar(_vg, rx, ry, BND_SCROLLBAR_WIDTH, 240.0f, BND_ACTIVE, s_offset, s_size);

	x = ox;
	y += 40.0f;
	bndToolButton(_vg, x, y, BND_TOOL_WIDTH, BND_WIDGET_HEIGHT, BND_CORNER_RIGHT, BND_DEFAULT, BND_ICONID(0, 10), NULL);
	x += BND_TOOL_WIDTH - 1;
	bndToolButton(_vg, x, y, BND_TOOL_WIDTH, BND_WIDGET_HEIGHT, BND_CORNER_ALL, BND_DEFAULT, BND_ICONID(1, 10), NULL);
	x += BND_TOOL_WIDTH - 1;
	bndToolButton(_vg, x, y, BND_TOOL_WIDTH, BND_WIDGET_HEIGHT, BND_CORNER_ALL, BND_DEFAULT, BND_ICONID(2, 10), NULL);
	x += BND_TOOL_WIDTH - 1;
	bndToolButton(_vg, x, y, BND_TOOL_WIDTH, BND_WIDGET_HEIGHT, BND_CORNER_ALL, BND_DEFAULT, BND_ICONID(3, 10), NULL);
	x += BND_TOOL_WIDTH - 1;
	bndToolButton(_vg, x, y, BND_TOOL_WIDTH, BND_WIDGET_HEIGHT, BND_CORNER_ALL, BND_DEFAULT, BND_ICONID(4, 10), NULL);
	x += BND_TOOL_WIDTH - 1;
	bndToolButton(_vg, x, y, BND_TOOL_WIDTH, BND_WIDGET_HEIGHT, BND_CORNER_LEFT, BND_DEFAULT, BND_ICONID(5, 10), NULL);
	x += BND_TOOL_WIDTH - 1;
	x += 5.0f;
	bndRadioButton(_vg, x, y, BND_TOOL_WIDTH, BND_WIDGET_HEIGHT, BND_CORNER_RIGHT, BND_DEFAULT, BND_ICONID(0, 11), NULL);
	x += BND_TOOL_WIDTH - 1;
	bndRadioButton(_vg, x, y, BND_TOOL_WIDTH, BND_WIDGET_HEIGHT, BND_CORNER_ALL, BND_DEFAULT, BND_ICONID(1, 11), NULL);
	x += BND_TOOL_WIDTH - 1;
	bndRadioButton(_vg, x, y, BND_TOOL_WIDTH, BND_WIDGET_HEIGHT, BND_CORNER_ALL, BND_DEFAULT, BND_ICONID(2, 11), NULL);
	x += BND_TOOL_WIDTH - 1;
	bndRadioButton(_vg, x, y, BND_TOOL_WIDTH, BND_WIDGET_HEIGHT, BND_CORNER_ALL, BND_DEFAULT, BND_ICONID(3, 11), NULL);
	x += BND_TOOL_WIDTH - 1;
	bndRadioButton(_vg, x, y, BND_TOOL_WIDTH, BND_WIDGET_HEIGHT, BND_CORNER_ALL, BND_ACTIVE, BND_ICONID(4, 11), NULL);
	x += BND_TOOL_WIDTH - 1;
	bndRadioButton(_vg, x, y, BND_TOOL_WIDTH, BND_WIDGET_HEIGHT, BND_CORNER_LEFT, BND_DEFAULT, BND_ICONID(5, 11), NULL);
}
Ejemplo n.º 16
0
bool compileHLSLShaderDx11(bx::CommandLine& _cmdLine, const std::string& _code, bx::WriterI* _writer)
{
	BX_TRACE("DX11");

	const char* profile = _cmdLine.findOption('p', "profile");
	if (NULL == profile)
	{
		fprintf(stderr, "Shader profile must be specified.\n");
		return false;
	}

	bool debug = _cmdLine.hasArg('\0', "debug");

	uint32_t flags = D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
	flags |= debug ? D3DCOMPILE_DEBUG : 0;
	flags |= _cmdLine.hasArg('\0', "avoid-flow-control") ? D3DCOMPILE_AVOID_FLOW_CONTROL : 0;
	flags |= _cmdLine.hasArg('\0', "no-preshader") ? D3DCOMPILE_NO_PRESHADER : 0;
	flags |= _cmdLine.hasArg('\0', "partial-precision") ? D3DCOMPILE_PARTIAL_PRECISION : 0;
	flags |= _cmdLine.hasArg('\0', "prefer-flow-control") ? D3DCOMPILE_PREFER_FLOW_CONTROL : 0;
	flags |= _cmdLine.hasArg('\0', "backwards-compatibility") ? D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY : 0;

	bool werror = _cmdLine.hasArg('\0', "Werror");

	if (werror)
	{
		flags |= D3DCOMPILE_WARNINGS_ARE_ERRORS;
	}

	uint32_t optimization = 3;
	if (_cmdLine.hasArg(optimization, 'O') )
	{
		optimization = bx::uint32_min(optimization, BX_COUNTOF(s_optimizationLevelDx11)-1);
		flags |= s_optimizationLevelDx11[optimization];
	}
	else
	{
		flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
	}

	BX_TRACE("Profile: %s", profile);
	BX_TRACE("Flags: 0x%08x", flags);

	ID3DBlob* code;
	ID3DBlob* errorMsg;

	// Output preprocessed shader so that HLSL can be debugged via GPA
	// or PIX. Compiling through memory won't embed preprocessed shader
	// file path.
	std::string hlslfp;

	if (debug)
	{
		hlslfp = _cmdLine.findOption('o');
		hlslfp += ".hlsl";
		writeFile(hlslfp.c_str(), _code.c_str(), (int32_t)_code.size() );
	}

	HRESULT hr = D3DCompile(_code.c_str()
		, _code.size()
		, hlslfp.c_str()
		, NULL
		, NULL
		, "main"
		, profile
		, flags
		, 0
		, &code
		, &errorMsg
		);
	if (FAILED(hr)
	|| (werror && NULL != errorMsg) )
	{
		const char* log = (char*)errorMsg->GetBufferPointer();

		int32_t line = 0;
		int32_t column = 0;
		int32_t start = 0;
		int32_t end = INT32_MAX;

		if (2 == sscanf(log, "(%u,%u):", &line, &column)
		&&  0 != line)
		{
			start = bx::uint32_imax(1, line-10);
			end = start + 20;
		}

		printCode(_code.c_str(), line, start, end);
		fprintf(stderr, "Error: 0x%08x %s\n", (uint32_t)hr, log);
		errorMsg->Release();
		return false;
	}

	UniformArray uniforms;

	ID3D11ShaderReflection* reflect = NULL;
	hr = D3DReflect(code->GetBufferPointer()
		, code->GetBufferSize()
		, IID_ID3D11ShaderReflection
		, (void**)&reflect
		);
	if (FAILED(hr) )
	{
		fprintf(stderr, "Error: 0x%08x\n", (uint32_t)hr);
		return false;
	}

	D3D11_SHADER_DESC desc;
	hr = reflect->GetDesc(&desc);
	if (FAILED(hr) )
	{
		fprintf(stderr, BX_FILE_LINE_LITERAL "Error: 0x%08x\n", (uint32_t)hr);
		return false;
	}

	BX_TRACE("Creator: %s 0x%08x", desc.Creator, desc.Version);
	BX_TRACE("Num constant buffers: %d", desc.ConstantBuffers);

	BX_TRACE("Input:");
	uint8_t numAttrs = 0;
	uint16_t attrs[bgfx::Attrib::Count];

	if (profile[0] == 'v') // Only care about input semantic on vertex shaders
	{
		for (uint32_t ii = 0; ii < desc.InputParameters; ++ii)
		{
			D3D11_SIGNATURE_PARAMETER_DESC spd;
			reflect->GetInputParameterDesc(ii, &spd);
			BX_TRACE("\t%2d: %s%d, vt %d, ct %d, mask %x, reg %d"
				, ii
				, spd.SemanticName
				, spd.SemanticIndex
				, spd.SystemValueType
				, spd.ComponentType
				, spd.Mask
				, spd.Register
				);

			const RemapInputSemantic& ris = findInputSemantic(spd.SemanticName, spd.SemanticIndex);
			if (ris.m_attr != bgfx::Attrib::Count)
			{
				attrs[numAttrs] = bgfx::attribToId(ris.m_attr);
				++numAttrs;
			}
		}
	}

	BX_TRACE("Output:");
	for (uint32_t ii = 0; ii < desc.OutputParameters; ++ii)
	{
		D3D11_SIGNATURE_PARAMETER_DESC spd;
		reflect->GetOutputParameterDesc(ii, &spd);
		BX_TRACE("\t%2d: %s%d, %d, %d", ii, spd.SemanticName, spd.SemanticIndex, spd.SystemValueType, spd.ComponentType);
	}

	uint16_t size = 0;

	for (uint32_t ii = 0; ii < bx::uint32_min(1, desc.ConstantBuffers); ++ii)
	{
		ID3D11ShaderReflectionConstantBuffer* cbuffer = reflect->GetConstantBufferByIndex(ii);
		D3D11_SHADER_BUFFER_DESC bufferDesc;
		hr = cbuffer->GetDesc(&bufferDesc);

		size = (uint16_t)bufferDesc.Size;

		if (SUCCEEDED(hr) )
		{
			BX_TRACE("%s, %d, vars %d, size %d"
				, bufferDesc.Name
				, bufferDesc.Type
				, bufferDesc.Variables
				, bufferDesc.Size
				);

			for (uint32_t jj = 0; jj < bufferDesc.Variables; ++jj)
			{
				ID3D11ShaderReflectionVariable* var = cbuffer->GetVariableByIndex(jj);
				ID3D11ShaderReflectionType* type = var->GetType();
				D3D11_SHADER_VARIABLE_DESC varDesc;
				hr = var->GetDesc(&varDesc);
				if (SUCCEEDED(hr) )
				{
					D3D11_SHADER_TYPE_DESC constDesc;
					hr = type->GetDesc(&constDesc);
					if (SUCCEEDED(hr) )
					{
						UniformType::Enum uniformType = findUniformTypeDx11(constDesc);

						if (UniformType::Count != uniformType
						&&  0 != (varDesc.uFlags & D3D_SVF_USED) )
						{
							Uniform un;
							un.name = varDesc.Name;
							un.type = uniformType;
							un.num = constDesc.Elements;
							un.regIndex = varDesc.StartOffset;
							un.regCount = BX_ALIGN_16(varDesc.Size)/16;
							uniforms.push_back(un);

							BX_TRACE("\t%s, %d, size %d, flags 0x%08x, %d"
								, varDesc.Name
								, varDesc.StartOffset
								, varDesc.Size
								, varDesc.uFlags
								, uniformType
								);
						}
						else
						{
							BX_TRACE("\t%s, unknown type", varDesc.Name);
						}
					}
				}
			}
		}
	}

	BX_TRACE("Bound:");
	for (uint32_t ii = 0; ii < desc.BoundResources; ++ii)
	{
		D3D11_SHADER_INPUT_BIND_DESC bindDesc;

		hr = reflect->GetResourceBindingDesc(ii, &bindDesc);
		if (SUCCEEDED(hr) )
		{
			//			if (bindDesc.Type == D3D_SIT_SAMPLER)
			{
				BX_TRACE("\t%s, %d, %d, %d"
					, bindDesc.Name
					, bindDesc.Type
					, bindDesc.BindPoint
					, bindDesc.BindCount
					);
			}
		}
	}

	uint16_t count = (uint16_t)uniforms.size();
	bx::write(_writer, count);

	uint32_t fragmentBit = profile[0] == 'p' ? BGFX_UNIFORM_FRAGMENTBIT : 0;
	for (UniformArray::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
	{
		const Uniform& un = *it;
		uint8_t nameSize = (uint8_t)un.name.size();
		bx::write(_writer, nameSize);
		bx::write(_writer, un.name.c_str(), nameSize);
		uint8_t type = un.type|fragmentBit;
		bx::write(_writer, type);
		bx::write(_writer, un.num);
		bx::write(_writer, un.regIndex);
		bx::write(_writer, un.regCount);

		BX_TRACE("%s, %s, %d, %d, %d"
			, un.name.c_str()
			, getUniformTypeName(un.type)
			, un.num
			, un.regIndex
			, un.regCount
			);
	}

	{
		ID3DBlob* stripped;
		hr = D3DStripShader(code->GetBufferPointer()
			, code->GetBufferSize()
			, D3DCOMPILER_STRIP_REFLECTION_DATA
			| D3DCOMPILER_STRIP_TEST_BLOBS
			, &stripped
			);

		if (SUCCEEDED(hr) )
		{
			code->Release();
			code = stripped;
		}
	}

	uint16_t shaderSize = (uint16_t)code->GetBufferSize();
	bx::write(_writer, shaderSize);
	bx::write(_writer, code->GetBufferPointer(), shaderSize);
	uint8_t nul = 0;
	bx::write(_writer, nul);

	bx::write(_writer, numAttrs);
	bx::write(_writer, attrs, numAttrs*sizeof(uint16_t) );

	bx::write(_writer, size);

	if (_cmdLine.hasArg('\0', "disasm") )
	{
		ID3DBlob* disasm;
		D3DDisassemble(code->GetBufferPointer()
			, code->GetBufferSize()
			, 0
			, NULL
			, &disasm
			);

		if (NULL != disasm)
		{
			std::string disasmfp = _cmdLine.findOption('o');
			disasmfp += ".disasm";

			writeFile(disasmfp.c_str(), disasm->GetBufferPointer(), (uint32_t)disasm->GetBufferSize() );
			disasm->Release();
		}
	}

	if (NULL != reflect)
	{
		reflect->Release();
	}

	if (NULL != errorMsg)
	{
		errorMsg->Release();
	}

	code->Release();

	return true;
}
Ejemplo n.º 17
0
void ANativeActivity_onCreate(ANativeActivity*, void*, size_t)
{
	exit(runAllTests(BX_COUNTOF(s_argv), s_argv) );
}
Ejemplo n.º 18
0
	void create(float _fontSize, bx::AllocatorI* _allocator)
	{
		m_viewId = 255;
		m_allocator = _allocator;
		m_lastScroll = 0;
		m_last = bx::getHPCounter();

		ImGuiIO& io = ImGui::GetIO();
		io.RenderDrawListsFn = renderDrawLists;
		if (NULL != m_allocator)
		{
			io.MemAllocFn = memAlloc;
			io.MemFreeFn  = memFree;
		}

		io.DisplaySize = ImVec2(1280.0f, 720.0f);
		io.DeltaTime   = 1.0f / 60.0f;
		io.IniFilename = NULL;

		setupStyle(true);

#if defined(SCI_NAMESPACE)
		io.KeyMap[ImGuiKey_Tab]        = (int)entry::Key::Tab;
		io.KeyMap[ImGuiKey_LeftArrow]  = (int)entry::Key::Left;
		io.KeyMap[ImGuiKey_RightArrow] = (int)entry::Key::Right;
		io.KeyMap[ImGuiKey_UpArrow]    = (int)entry::Key::Up;
		io.KeyMap[ImGuiKey_DownArrow]  = (int)entry::Key::Down;
		io.KeyMap[ImGuiKey_Home]       = (int)entry::Key::Home;
		io.KeyMap[ImGuiKey_End]        = (int)entry::Key::End;
		io.KeyMap[ImGuiKey_Delete]     = (int)entry::Key::Delete;
		io.KeyMap[ImGuiKey_Backspace]  = (int)entry::Key::Backspace;
		io.KeyMap[ImGuiKey_Enter]      = (int)entry::Key::Return;
		io.KeyMap[ImGuiKey_Escape]     = (int)entry::Key::Esc;
		io.KeyMap[ImGuiKey_A]          = (int)entry::Key::KeyA;
		io.KeyMap[ImGuiKey_C]          = (int)entry::Key::KeyC;
		io.KeyMap[ImGuiKey_V]          = (int)entry::Key::KeyV;
		io.KeyMap[ImGuiKey_X]          = (int)entry::Key::KeyX;
		io.KeyMap[ImGuiKey_Y]          = (int)entry::Key::KeyY;
		io.KeyMap[ImGuiKey_Z]          = (int)entry::Key::KeyZ;
#endif // defined(SCI_NAMESPACE)

		const bgfx::Memory* vsmem;
		const bgfx::Memory* fsmem;

		switch (bgfx::getRendererType() )
		{
		case bgfx::RendererType::Direct3D9:
			vsmem = bgfx::makeRef(vs_ocornut_imgui_dx9, sizeof(vs_ocornut_imgui_dx9) );
			fsmem = bgfx::makeRef(fs_ocornut_imgui_dx9, sizeof(fs_ocornut_imgui_dx9) );
			break;

		case bgfx::RendererType::Direct3D11:
		case bgfx::RendererType::Direct3D12:
			vsmem = bgfx::makeRef(vs_ocornut_imgui_dx11, sizeof(vs_ocornut_imgui_dx11) );
			fsmem = bgfx::makeRef(fs_ocornut_imgui_dx11, sizeof(fs_ocornut_imgui_dx11) );
			break;

		case bgfx::RendererType::Metal:
			vsmem = bgfx::makeRef(vs_ocornut_imgui_mtl, sizeof(vs_ocornut_imgui_mtl) );
			fsmem = bgfx::makeRef(fs_ocornut_imgui_mtl, sizeof(fs_ocornut_imgui_mtl) );
			break;

		default:
			vsmem = bgfx::makeRef(vs_ocornut_imgui_glsl, sizeof(vs_ocornut_imgui_glsl) );
			fsmem = bgfx::makeRef(fs_ocornut_imgui_glsl, sizeof(fs_ocornut_imgui_glsl) );
			break;
		}

		bgfx::ShaderHandle vsh = bgfx::createShader(vsmem);
		bgfx::ShaderHandle fsh = bgfx::createShader(fsmem);
		m_program = bgfx::createProgram(vsh, fsh, true);

		m_decl
			.begin()
			.add(bgfx::Attrib::Position,  2, bgfx::AttribType::Float)
			.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
			.add(bgfx::Attrib::Color0,    4, bgfx::AttribType::Uint8, true)
			.end();

		s_tex = bgfx::createUniform("s_tex", bgfx::UniformType::Int1);

		uint8_t* data;
		int32_t width;
		int32_t height;
		{
			ImFontConfig config;
			config.FontDataOwnedByAtlas = false;
			config.MergeMode = false;
//			config.MergeGlyphCenterV = true;

			m_font[ImGui::Font::Regular] = io.Fonts->AddFontFromMemoryTTF( (void*)s_robotoRegularTtf,     sizeof(s_robotoRegularTtf),     _fontSize,      &config);
			m_font[ImGui::Font::Mono   ] = io.Fonts->AddFontFromMemoryTTF( (void*)s_robotoMonoRegularTtf, sizeof(s_robotoMonoRegularTtf), _fontSize-3.0f, &config);

			config.MergeMode = true;
			config.DstFont   = m_font[ImGui::Font::Regular];

			for (uint32_t ii = 0; ii < BX_COUNTOF(s_fontRangeMerge); ++ii)
			{
				const FontRangeMerge& frm = s_fontRangeMerge[ii];

				io.Fonts->AddFontFromMemoryTTF( (void*)frm.data
						, (int)frm.size
						, _fontSize-3.0f
						, &config
						, frm.ranges
						);
			}
		}

		io.Fonts->GetTexDataAsRGBA32(&data, &width, &height);

		m_texture = bgfx::createTexture2D(
			  (uint16_t)width
			, (uint16_t)height
			, false
			, 1
			, bgfx::TextureFormat::BGRA8
			, 0
			, bgfx::copy(data, width*height*4)
			);

		ImGui::InitDockContext();
	}
Ejemplo n.º 19
0
	static bool compile(bx::CommandLine& _cmdLine, uint32_t _version, const std::string& _code, bx::WriterI* _writer, bool _firstPass)
	{
		const char* profile = _cmdLine.findOption('p', "profile");
		if (NULL == profile)
		{
			fprintf(stderr, "Error: Shader profile must be specified.\n");
			return false;
		}

		s_compiler = load();

		bool result = false;
		bool debug = _cmdLine.hasArg('\0', "debug");

		uint32_t flags = D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
		flags |= debug ? D3DCOMPILE_DEBUG : 0;
		flags |= _cmdLine.hasArg('\0', "avoid-flow-control") ? D3DCOMPILE_AVOID_FLOW_CONTROL : 0;
		flags |= _cmdLine.hasArg('\0', "no-preshader") ? D3DCOMPILE_NO_PRESHADER : 0;
		flags |= _cmdLine.hasArg('\0', "partial-precision") ? D3DCOMPILE_PARTIAL_PRECISION : 0;
		flags |= _cmdLine.hasArg('\0', "prefer-flow-control") ? D3DCOMPILE_PREFER_FLOW_CONTROL : 0;
		flags |= _cmdLine.hasArg('\0', "backwards-compatibility") ? D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY : 0;

		bool werror = _cmdLine.hasArg('\0', "Werror");

		if (werror)
		{
			flags |= D3DCOMPILE_WARNINGS_ARE_ERRORS;
		}

		uint32_t optimization = 3;
		if (_cmdLine.hasArg(optimization, 'O') )
		{
			optimization = bx::uint32_min(optimization, BX_COUNTOF(s_optimizationLevelD3D11) - 1);
			flags |= s_optimizationLevelD3D11[optimization];
		}
		else
		{
			flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
		}

		BX_TRACE("Profile: %s", profile);
		BX_TRACE("Flags: 0x%08x", flags);

		ID3DBlob* code;
		ID3DBlob* errorMsg;

		// Output preprocessed shader so that HLSL can be debugged via GPA
		// or PIX. Compiling through memory won't embed preprocessed shader
		// file path.
		std::string hlslfp;

		if (debug)
		{
			hlslfp = _cmdLine.findOption('o');
			hlslfp += ".hlsl";
			writeFile(hlslfp.c_str(), _code.c_str(), (int32_t)_code.size() );
		}

		HRESULT hr = D3DCompile(_code.c_str()
			, _code.size()
			, hlslfp.c_str()
			, NULL
			, NULL
			, "main"
			, profile
			, flags
			, 0
			, &code
			, &errorMsg
			);
		if (FAILED(hr)
		|| (werror && NULL != errorMsg) )
		{
			const char* log = (char*)errorMsg->GetBufferPointer();

			int32_t line   = 0;
			int32_t column = 0;
			int32_t start  = 0;
			int32_t end    = INT32_MAX;

			bool found = false
				|| 2 == sscanf(log, "(%u,%u):", &line, &column)
				|| 2 == sscanf(log, " :%u:%u: ", &line, &column)
				;

			if (found
			&&  0 != line)
			{
				start = bx::uint32_imax(1, line - 10);
				end   = start + 20;
			}

			printCode(_code.c_str(), line, start, end, column);
			fprintf(stderr, "Error: D3DCompile failed 0x%08x %s\n", (uint32_t)hr, log);
			errorMsg->Release();
			return false;
		}

		UniformArray uniforms;
		uint8_t numAttrs = 0;
		uint16_t attrs[bgfx::Attrib::Count];
		uint16_t size = 0;

		if (_version == 9)
		{
			if (!getReflectionDataD3D9(code, uniforms) )
			{
				fprintf(stderr, "Error: Unable to get D3D9 reflection data.\n");
				goto error;
			}
		}
		else
		{
			UniformNameList unusedUniforms;
			if (!getReflectionDataD3D11(code, profile[0] == 'v', uniforms, numAttrs, attrs, size, unusedUniforms) )
			{
				fprintf(stderr, "Error: Unable to get D3D11 reflection data.\n");
				goto error;
			}

			if (_firstPass
			&&  unusedUniforms.size() > 0)
			{
				const size_t strLength = strlen("uniform");

				// first time through, we just find unused uniforms and get rid of them
				std::string output;
				LineReader reader(_code.c_str() );
				while (!reader.isEof() )
				{
					std::string line = reader.getLine();
					for (UniformNameList::iterator it = unusedUniforms.begin(), itEnd = unusedUniforms.end(); it != itEnd; ++it)
					{
						size_t index = line.find("uniform ");
						if (index == std::string::npos)
						{
							continue;
						}

						// matching lines like:  uniform u_name;
						// we want to replace "uniform" with "static" so that it's no longer
						// included in the uniform blob that the application must upload
						// we can't just remove them, because unused functions might still reference
						// them and cause a compile error when they're gone
						if (!!bx::findIdentifierMatch(line.c_str(), it->c_str() ) )
						{
							line = line.replace(index, strLength, "static");
							unusedUniforms.erase(it);
							break;
						}
					}

					output += line;
				}

				// recompile with the unused uniforms converted to statics
				return compile(_cmdLine, _version, output.c_str(), _writer, false);
			}
		}

		{
			uint16_t count = (uint16_t)uniforms.size();
			bx::write(_writer, count);

			uint32_t fragmentBit = profile[0] == 'p' ? BGFX_UNIFORM_FRAGMENTBIT : 0;
			for (UniformArray::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
			{
				const Uniform& un = *it;
				uint8_t nameSize = (uint8_t)un.name.size();
				bx::write(_writer, nameSize);
				bx::write(_writer, un.name.c_str(), nameSize);
				uint8_t type = uint8_t(un.type | fragmentBit);
				bx::write(_writer, type);
				bx::write(_writer, un.num);
				bx::write(_writer, un.regIndex);
				bx::write(_writer, un.regCount);

				BX_TRACE("%s, %s, %d, %d, %d"
					, un.name.c_str()
					, getUniformTypeName(un.type)
					, un.num
					, un.regIndex
					, un.regCount
					);
			}
		}

		{
			ID3DBlob* stripped;
			hr = D3DStripShader(code->GetBufferPointer()
				, code->GetBufferSize()
				, D3DCOMPILER_STRIP_REFLECTION_DATA
				| D3DCOMPILER_STRIP_TEST_BLOBS
				, &stripped
				);

			if (SUCCEEDED(hr) )
			{
				code->Release();
				code = stripped;
			}
		}

		{
			uint16_t shaderSize = (uint16_t)code->GetBufferSize();
			bx::write(_writer, shaderSize);
			bx::write(_writer, code->GetBufferPointer(), shaderSize);
			uint8_t nul = 0;
			bx::write(_writer, nul);
		}

		if (_version > 9)
		{
			bx::write(_writer, numAttrs);
			bx::write(_writer, attrs, numAttrs*sizeof(uint16_t) );

			bx::write(_writer, size);
		}

		if (_cmdLine.hasArg('\0', "disasm") )
		{
			ID3DBlob* disasm;
			D3DDisassemble(code->GetBufferPointer()
				, code->GetBufferSize()
				, 0
				, NULL
				, &disasm
				);

			if (NULL != disasm)
			{
				std::string disasmfp = _cmdLine.findOption('o');
				disasmfp += ".disasm";

				writeFile(disasmfp.c_str(), disasm->GetBufferPointer(), (uint32_t)disasm->GetBufferSize() );
				disasm->Release();
			}
		}

		if (NULL != errorMsg)
		{
			errorMsg->Release();
		}

		result = true;

	error:
		code->Release();
		unload();
		return result;
	}
Ejemplo n.º 20
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;
			}
		}
	}
Ejemplo n.º 21
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
		);

	// Create vertex stream declaration.
	PosTexcoordVertex::init();

	bgfx::TextureHandle textures[] =
	{
		loadTexture("texture_compression_bc1.dds",  BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP),
		loadTexture("texture_compression_bc2.dds",  BGFX_TEXTURE_U_CLAMP),
		loadTexture("texture_compression_bc3.dds",  BGFX_TEXTURE_V_CLAMP),
		loadTexture("texture_compression_etc1.ktx", BGFX_TEXTURE_U_BORDER|BGFX_TEXTURE_V_BORDER|BGFX_TEXTURE_BORDER_COLOR(1) ),
		loadTexture("texture_compression_etc2.ktx"),
		loadTexture("texture_compression_ptc12.pvr"),
		loadTexture("texture_compression_ptc14.pvr"),
		loadTexture("texture_compression_ptc22.pvr"),
		loadTexture("texture_compression_ptc24.pvr"),
	};

	const bgfx::Memory* mem8   = bgfx::alloc(32*32*32);
	const bgfx::Memory* mem16f = bgfx::alloc(32*32*32*2);
	const bgfx::Memory* mem32f = bgfx::alloc(32*32*32*4);
	for (uint8_t zz = 0; zz < 32; ++zz)
	{
		for (uint8_t yy = 0; yy < 32; ++yy)
		{
			for (uint8_t xx = 0; xx < 32; ++xx)
			{
				const uint32_t offset = ( (zz*32+yy)*32+xx);
				const uint32_t val = xx ^ yy ^ zz;
				mem8->data[offset] = val<<3;
				*(uint16_t*)&mem16f->data[offset*2] = bx::halfFromFloat( (float)val/32.0f);
				*(float*)&mem32f->data[offset*4] = (float)val/32.0f;
			}
		}
	}

	const bgfx::Caps* caps = bgfx::getCaps();
	const bool texture3DSupported = !!(caps->supported & BGFX_CAPS_TEXTURE_3D);
	const bool blitSupported      = !!(caps->supported & BGFX_CAPS_TEXTURE_BLIT);

	uint32_t numTextures3d = 0;
	bgfx::TextureHandle textures3d[3] = {};

	if (texture3DSupported)
	{
		if (0 != (BGFX_CAPS_FORMAT_TEXTURE_COLOR & caps->formats[bgfx::TextureFormat::R8]) )
		{
			textures3d[numTextures3d++] = bgfx::createTexture3D(32, 32, 32, 0, bgfx::TextureFormat::R8,   BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_W_CLAMP, mem8);
		}

		if (0 != (BGFX_CAPS_FORMAT_TEXTURE_COLOR & caps->formats[bgfx::TextureFormat::R16F]) )
		{
			textures3d[numTextures3d++] = bgfx::createTexture3D(32, 32, 32, 0, bgfx::TextureFormat::R16F, BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_W_CLAMP, mem16f);
		}

		if (0 != (BGFX_CAPS_FORMAT_TEXTURE_COLOR & caps->formats[bgfx::TextureFormat::R32F]) )
		{
			textures3d[numTextures3d++] = bgfx::createTexture3D(32, 32, 32, 0, bgfx::TextureFormat::R32F, BGFX_TEXTURE_U_CLAMP|BGFX_TEXTURE_V_CLAMP|BGFX_TEXTURE_W_CLAMP, mem32f);
		}
	}

	// Create static vertex buffer.
	bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer(bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) ), PosTexcoordVertex::ms_decl);

	// Create static index buffer.
	bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) ) );

	// Create programs.
	bgfx::ProgramHandle program    = loadProgram("vs_update", "fs_update");
	bgfx::ProgramHandle programCmp = loadProgram("vs_update", "fs_update_cmp");
	bgfx::ProgramHandle program3d  = BGFX_INVALID_HANDLE;
	if (texture3DSupported)
	{
		program3d = loadProgram("vs_update", "fs_update_3d");
	}

	// Create texture sampler uniforms.
	bgfx::UniformHandle s_texCube  = bgfx::createUniform("s_texCube",  bgfx::UniformType::Int1);
	bgfx::UniformHandle s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1);

	// Create time uniform.
	bgfx::UniformHandle u_time = bgfx::createUniform("u_time", bgfx::UniformType::Vec4);

	const uint32_t textureSide = 2048;

	bgfx::TextureHandle textureCube[2];

	textureCube[0] = bgfx::createTextureCube(textureSide, 1
		, bgfx::TextureFormat::BGRA8
		, BGFX_TEXTURE_MIN_POINT|BGFX_TEXTURE_MAG_POINT|BGFX_TEXTURE_MIP_POINT
		);

	if (blitSupported)
	{
		textureCube[1] = bgfx::createTextureCube(textureSide, 1
			, bgfx::TextureFormat::BGRA8
			, BGFX_TEXTURE_MIN_POINT|BGFX_TEXTURE_MAG_POINT|BGFX_TEXTURE_MIP_POINT|BGFX_TEXTURE_BLIT_DST
			);
	}

	const uint32_t texture2dSize = 256;

	bgfx::TextureHandle texture2d = bgfx::createTexture2D(texture2dSize, texture2dSize, 1
		, bgfx::TextureFormat::BGRA8
		, BGFX_TEXTURE_MIN_POINT|BGFX_TEXTURE_MAG_POINT|BGFX_TEXTURE_MIP_POINT
		);

	uint8_t* texture2dData = (uint8_t*)malloc(texture2dSize*texture2dSize*4);

	uint8_t rr = rand()%255;
	uint8_t gg = rand()%255;
	uint8_t bb = rand()%255;

	int64_t updateTime = 0;

	RectPackCubeT<256> cube(textureSide);

	uint32_t hit = 0;
	uint32_t miss = 0;
	std::list<PackCube> quads;

	int64_t timeOffset = bx::getHPCounter();

	while (!entry::processEvents(width, height, debug, reset) )
	{
		float borderColor[4] = { float(rand()%255)/255.0f, float(rand()%255)/255.0f, float(rand()%255)/255.0f, float(rand()%255)/255.0f };
		bgfx::setPaletteColor(1, borderColor);

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

		// This dummy draw call is here to make sure that view 0 is cleared
		// if no other draw calls are submitted to view 0.
		bgfx::touch(0);

		int64_t now = bx::getHPCounter();
		static int64_t last = now;
		const int64_t frameTime = now - last;
		last = now;
		const int64_t freq = bx::getHPFrequency();
		const double toMs = 1000.0/double(freq);
		float time = (float)( (now - timeOffset)/double(bx::getHPFrequency() ) );
		bgfx::setUniform(u_time, &time);

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

		if (now > updateTime)
		{
			PackCube face;

			uint32_t bw = bx::uint16_max(1, rand()%(textureSide/4) );
			uint32_t bh = bx::uint16_max(1, rand()%(textureSide/4) );

			if (cube.find(bw, bh, face) )
			{
				quads.push_back(face);

				++hit;
				const Pack2D& rect = face.m_rect;

				updateTextureCubeRectBgra8(textureCube[0], face.m_side, rect.m_x, rect.m_y, rect.m_width, rect.m_height, rr, gg, bb);
				if (blitSupported)
				{
					bgfx::blit(0, textureCube[1], 0, rect.m_x, rect.m_y, face.m_side, textureCube[0], 0, rect.m_x, rect.m_y, face.m_side, rect.m_width, rect.m_height);
				}

				rr = rand()%255;
				gg = rand()%255;
				bb = rand()%255;
			}
			else
			{
				++miss;

				for (uint32_t ii = 0, num = bx::uint32_min(10, (uint32_t)quads.size() ); ii < num; ++ii)
				{
					cube.clear(quads.front() );
					quads.pop_front();
				}
			}

			{
				// Fill rect.
				const uint32_t pitch = texture2dSize*4;

				const uint16_t tw = rand()%texture2dSize;
				const uint16_t th = rand()%texture2dSize;
				const uint16_t tx = rand()%(texture2dSize-tw);
				const uint16_t ty = rand()%(texture2dSize-th);

				uint8_t* dst = &texture2dData[(ty*texture2dSize+tx)*4];
				uint8_t* next = dst + pitch;

				// Using makeRef to pass texture memory without copying.
				const bgfx::Memory* mem = bgfx::makeRef(dst, tw*th*4);

				for (uint32_t yy = 0; yy < th; ++yy, dst = next, next += pitch)
				{
					for (uint32_t xx = 0; xx < tw; ++xx, dst += 4)
					{
						dst[0] = bb;
						dst[1] = gg;
						dst[2] = rr;
						dst[3] = 255;
					}
				}

				// Pitch here makes possible to pass data from source to destination
				// without need for textures and allocated memory to be the same size.
				bgfx::updateTexture2D(texture2d, 0, tx, ty, tw, th, mem, pitch);
			}
		}

		bgfx::dbgTextPrintf(0, 4, 0x0f, "hit: %d, miss %d", hit, miss);

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

		float view[16];
		float proj[16];
		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);

		for (uint32_t ii = 0; ii < 1 + uint32_t(blitSupported); ++ii)
		{
			float mtx[16];
			bx::mtxSRT(mtx, 1.0f, 1.0f, 1.0f, time, time*0.37f, 0.0f, -1.5f*blitSupported + ii*3.0f, 0.0f, 0.0f);

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

			// Set vertex and index buffer.
			bgfx::setVertexBuffer(vbh);
			bgfx::setIndexBuffer(ibh);

			// Bind texture.
			bgfx::setTexture(0, s_texCube, textureCube[ii]);

			// Set render states.
			bgfx::setState(BGFX_STATE_DEFAULT);

			// Submit primitive for rendering to view 0.
			bgfx::submit(0, program);
		}

		// Set view and projection matrix for view 1.
		const float aspectRatio = float(height)/float(width);
		const float size = 11.0f;
		bx::mtxOrtho(proj, -size, size, size*aspectRatio, -size*aspectRatio, 0.0f, 1000.0f);
		bgfx::setViewTransform(1, NULL, proj);

		float mtx[16];
		bx::mtxTranslate(mtx, -size+2.0f - BX_COUNTOF(textures)*0.1f*0.5f, 1.9f, 0.0f);

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

		// Set vertex and index buffer.
		bgfx::setVertexBuffer(vbh);
		bgfx::setIndexBuffer(ibh);

		// Bind texture.
		bgfx::setTexture(0, s_texColor, texture2d);

		// Set render states.
		bgfx::setState(BGFX_STATE_DEFAULT);

		// Submit primitive for rendering to view 1.
		bgfx::submit(1, programCmp);

		const float xpos = -size+2.0f - BX_COUNTOF(textures)*0.1f*0.5f;

		for (uint32_t ii = 0; ii < BX_COUNTOF(textures); ++ii)
		{
			bx::mtxTranslate(mtx, xpos + ii*2.1f, size-6.5f, 0.0f);

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

			// Set vertex and index buffer.
			bgfx::setVertexBuffer(vbh);
			bgfx::setIndexBuffer(ibh, 0, 6);

			// Bind texture.
			bgfx::setTexture(0, s_texColor, textures[ii]);

			// Set render states.
			bgfx::setState(BGFX_STATE_DEFAULT);

			// Submit primitive for rendering to view 1.
			bgfx::submit(1, programCmp);
		}

		for (uint32_t ii = 0; ii < numTextures3d; ++ii)
		{
			bx::mtxTranslate(mtx, xpos + ii*2.1f, -size+6.5f, 0.0f);

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

			// Set vertex and index buffer.
			bgfx::setVertexBuffer(vbh);
			bgfx::setIndexBuffer(ibh, 0, 6);

			// Bind texture.
			bgfx::setTexture(0, s_texColor, textures3d[ii]);

			// Set render states.
			bgfx::setState(BGFX_STATE_DEFAULT);

			// Submit primitive for rendering to view 1.
			bgfx::submit(1, program3d);
		}

		for (uint32_t ii = 0; ii < 4; ++ii)
		{
			bx::mtxTranslate(mtx, xpos + (size-2.0f)*2.1f, -size+6.5f + ii*2.1f, 0.0f);

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

			// Set vertex and index buffer.
			bgfx::setVertexBuffer(vbh, 24, 4);
			bgfx::setIndexBuffer(ibh, 0, 6);

			// Bind texture.
			bgfx::setTexture(0, s_texColor, textures[ii]);

			// Set render states.
			bgfx::setState(BGFX_STATE_DEFAULT);

			// Submit primitive for rendering to view 1.
			bgfx::submit(1, programCmp);
		}

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

	// texture2dData is managed from main thread, and it's passed to renderer
	// just as MemoryRef. At this point render might be using it. We must wait
	// previous frame to finish before we can free it.
	bgfx::frame();

	// Cleanup.
	free(texture2dData);

	for (uint32_t ii = 0; ii < BX_COUNTOF(textures); ++ii)
	{
		bgfx::destroyTexture(textures[ii]);
	}

	for (uint32_t ii = 0; ii < numTextures3d; ++ii)
	{
		bgfx::destroyTexture(textures3d[ii]);
	}

	bgfx::destroyTexture(texture2d);
	bgfx::destroyTexture(textureCube[0]);
	if (blitSupported)
	{
		bgfx::destroyTexture(textureCube[1]);
	}
	bgfx::destroyIndexBuffer(ibh);
	bgfx::destroyVertexBuffer(vbh);
	if (bgfx::isValid(program3d) )
	{
		bgfx::destroyProgram(program3d);
	}
	bgfx::destroyProgram(programCmp);
	bgfx::destroyProgram(program);
	bgfx::destroyUniform(u_time);
	bgfx::destroyUniform(s_texColor);
	bgfx::destroyUniform(s_texCube);

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

	return 0;
}
Ejemplo n.º 22
0
namespace entry
{
	static uint32_t s_debug = BGFX_DEBUG_NONE;
	static uint32_t s_reset = BGFX_RESET_NONE;
	static bool s_exit = false;

	static Remotery* s_rmt = NULL;

	static bx::FileReaderI* s_fileReader = NULL;
	static bx::FileWriterI* s_fileWriter = NULL;

	extern bx::AllocatorI* getDefaultAllocator();
	static bx::AllocatorI* s_allocator = getDefaultAllocator();

	void* rmtMalloc(void* /*_context*/, rmtU32 _size)
	{
		return BX_ALLOC(s_allocator, _size);
	}

	void* rmtRealloc(void* /*_context*/, void* _ptr, rmtU32 _size)
	{
		return BX_REALLOC(s_allocator, _ptr, _size);
	}

	void rmtFree(void* /*_context*/, void* _ptr)
	{
		BX_FREE(s_allocator, _ptr);
	}

#if ENTRY_CONFIG_IMPLEMENT_DEFAULT_ALLOCATOR
	bx::AllocatorI* getDefaultAllocator()
	{
BX_PRAGMA_DIAGNOSTIC_PUSH();
BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4459); // warning C4459: declaration of 's_allocator' hides global declaration
BX_PRAGMA_DIAGNOSTIC_IGNORED_CLANG_GCC("-Wshadow");
		static bx::CrtAllocator s_allocator;
		return &s_allocator;
BX_PRAGMA_DIAGNOSTIC_POP();
	}
#endif // ENTRY_CONFIG_IMPLEMENT_DEFAULT_ALLOCATOR

	static const char* s_keyName[] =
	{
		"None",
		"Esc",
		"Return",
		"Tab",
		"Space",
		"Backspace",
		"Up",
		"Down",
		"Left",
		"Right",
		"Insert",
		"Delete",
		"Home",
		"End",
		"PageUp",
		"PageDown",
		"Print",
		"Plus",
		"Minus",
		"LeftBracket",
		"RightBracket",
		"Semicolon",
		"Quote",
		"Comma",
		"Period",
		"Slash",
		"Backslash",
		"Tilde",
		"F1",
		"F2",
		"F3",
		"F4",
		"F5",
		"F6",
		"F7",
		"F8",
		"F9",
		"F10",
		"F11",
		"F12",
		"NumPad0",
		"NumPad1",
		"NumPad2",
		"NumPad3",
		"NumPad4",
		"NumPad5",
		"NumPad6",
		"NumPad7",
		"NumPad8",
		"NumPad9",
		"Key0",
		"Key1",
		"Key2",
		"Key3",
		"Key4",
		"Key5",
		"Key6",
		"Key7",
		"Key8",
		"Key9",
		"KeyA",
		"KeyB",
		"KeyC",
		"KeyD",
		"KeyE",
		"KeyF",
		"KeyG",
		"KeyH",
		"KeyI",
		"KeyJ",
		"KeyK",
		"KeyL",
		"KeyM",
		"KeyN",
		"KeyO",
		"KeyP",
		"KeyQ",
		"KeyR",
		"KeyS",
		"KeyT",
		"KeyU",
		"KeyV",
		"KeyW",
		"KeyX",
		"KeyY",
		"KeyZ",
		"GamepadA",
		"GamepadB",
		"GamepadX",
		"GamepadY",
		"GamepadThumbL",
		"GamepadThumbR",
		"GamepadShoulderL",
		"GamepadShoulderR",
		"GamepadUp",
		"GamepadDown",
		"GamepadLeft",
		"GamepadRight",
		"GamepadBack",
		"GamepadStart",
		"GamepadGuide",
	};
	BX_STATIC_ASSERT(Key::Count == BX_COUNTOF(s_keyName) );

	const char* getName(Key::Enum _key)
	{
		BX_CHECK(_key < Key::Count, "Invalid key %d.", _key);
		return s_keyName[_key];
	}

	char keyToAscii(Key::Enum _key, uint8_t _modifiers)
	{
		const bool isAscii = (Key::Key0 <= _key && _key <= Key::KeyZ)
						  || (Key::Esc  <= _key && _key <= Key::Minus);
		if (!isAscii)
		{
			return '\0';
		}

		const bool isNumber = (Key::Key0 <= _key && _key <= Key::Key9);
		if (isNumber)
		{
			return '0' + char(_key - Key::Key0);
		}

		const bool isChar = (Key::KeyA <= _key && _key <= Key::KeyZ);
		if (isChar)
		{
			enum { ShiftMask = Modifier::LeftShift|Modifier::RightShift };

			const bool shift = !!(_modifiers&ShiftMask);
			return (shift ? 'A' : 'a') + char(_key - Key::KeyA);
		}

		switch (_key)
		{
		case Key::Esc:       return 0x1b;
		case Key::Return:    return '\n';
		case Key::Tab:       return '\t';
		case Key::Space:     return ' ';
		case Key::Backspace: return 0x08;
		case Key::Plus:      return '+';
		case Key::Minus:     return '-';
		default:             break;
		}

		return '\0';
	}

	bool setOrToggle(uint32_t& _flags, const char* _name, uint32_t _bit, int _first, int _argc, char const* const* _argv)
	{
		if (0 == strcmp(_argv[_first], _name) )
		{
			int arg = _first+1;
			if (_argc > arg)
			{
				_flags &= ~_bit;
				_flags |= bx::toBool(_argv[arg]) ? _bit : 0;
			}
			else
			{
				_flags ^= _bit;
			}

			return true;
		}

		return false;
	}

	int cmdMouseLock(CmdContext* /*_context*/, void* /*_userData*/, int _argc, char const* const* _argv)
	{
		if (_argc > 1)
		{
			inputSetMouseLock(_argc > 1 ? bx::toBool(_argv[1]) : !inputIsMouseLocked() );
			return 0;
		}

		return 1;
	}

	int cmdGraphics(CmdContext* /*_context*/, void* /*_userData*/, int _argc, char const* const* _argv)
	{
		if (_argc > 1)
		{
			if (setOrToggle(s_reset, "vsync",       BGFX_RESET_VSYNC,              1, _argc, _argv)
			||  setOrToggle(s_reset, "maxaniso",    BGFX_RESET_MAXANISOTROPY,      1, _argc, _argv)
			||  setOrToggle(s_reset, "hmd",         BGFX_RESET_HMD,                1, _argc, _argv)
			||  setOrToggle(s_reset, "hmddbg",      BGFX_RESET_HMD_DEBUG,          1, _argc, _argv)
			||  setOrToggle(s_reset, "hmdrecenter", BGFX_RESET_HMD_RECENTER,       1, _argc, _argv)
			||  setOrToggle(s_reset, "msaa",        BGFX_RESET_MSAA_X16,           1, _argc, _argv)
			||  setOrToggle(s_reset, "flush",       BGFX_RESET_FLUSH_AFTER_RENDER, 1, _argc, _argv)
			||  setOrToggle(s_reset, "flip",        BGFX_RESET_FLIP_AFTER_RENDER,  1, _argc, _argv)
			||  setOrToggle(s_reset, "hidpi",       BGFX_RESET_HIDPI,              1, _argc, _argv)
			||  setOrToggle(s_reset, "depthclamp",  BGFX_RESET_DEPTH_CLAMP,        1, _argc, _argv)
			   )
			{
				return 0;
			}
			else if (setOrToggle(s_debug, "stats",     BGFX_DEBUG_STATS,     1, _argc, _argv)
				 ||  setOrToggle(s_debug, "ifh",       BGFX_DEBUG_IFH,       1, _argc, _argv)
				 ||  setOrToggle(s_debug, "text",      BGFX_DEBUG_TEXT,      1, _argc, _argv)
				 ||  setOrToggle(s_debug, "wireframe", BGFX_DEBUG_WIREFRAME, 1, _argc, _argv) )
			{
				bgfx::setDebug(s_debug);
				return 0;
			}
			else if (0 == strcmp(_argv[1], "screenshot") )
			{
				if (_argc > 2)
				{
					bgfx::saveScreenShot(_argv[2]);
				}
				else
				{
					time_t tt;
					time(&tt);

					char filePath[256];
					bx::snprintf(filePath, sizeof(filePath), "temp/screenshot-%d", tt);
					bgfx::saveScreenShot(filePath);
				}

				return 0;
			}
			else if (0 == strcmp(_argv[1], "fullscreen") )
			{
				WindowHandle window = { 0 };
				toggleFullscreen(window);
				return 0;
			}
		}

		return 1;
	}

	int cmdExit(CmdContext* /*_context*/, void* /*_userData*/, int /*_argc*/, char const* const* /*_argv*/)
	{
		s_exit = true;
		return 0;
	}

	static const InputBinding s_bindings[] =
	{
		{ entry::Key::KeyQ,         entry::Modifier::LeftCtrl,  1, NULL, "exit"                              },
		{ entry::Key::KeyQ,         entry::Modifier::RightCtrl, 1, NULL, "exit"                              },
		{ entry::Key::KeyF,         entry::Modifier::LeftCtrl,  1, NULL, "graphics fullscreen"               },
		{ entry::Key::KeyF,         entry::Modifier::RightCtrl, 1, NULL, "graphics fullscreen"               },
		{ entry::Key::Return,       entry::Modifier::RightAlt,  1, NULL, "graphics fullscreen"               },
		{ entry::Key::F1,           entry::Modifier::None,      1, NULL, "graphics stats"                    },
		{ entry::Key::GamepadStart, entry::Modifier::None,      1, NULL, "graphics stats"                    },
		{ entry::Key::F1,           entry::Modifier::LeftShift, 1, NULL, "graphics stats 0\ngraphics text 0" },
		{ entry::Key::F3,           entry::Modifier::None,      1, NULL, "graphics wireframe"                },
		{ entry::Key::F4,           entry::Modifier::None,      1, NULL, "graphics hmd"                      },
		{ entry::Key::F4,           entry::Modifier::LeftShift, 1, NULL, "graphics hmdrecenter"              },
		{ entry::Key::F4,           entry::Modifier::LeftCtrl,  1, NULL, "graphics hmddbg"                   },
		{ entry::Key::F7,           entry::Modifier::None,      1, NULL, "graphics vsync"                    },
		{ entry::Key::F8,           entry::Modifier::None,      1, NULL, "graphics msaa"                     },
		{ entry::Key::F9,           entry::Modifier::None,      1, NULL, "graphics flush"                    },
		{ entry::Key::F10,          entry::Modifier::None,      1, NULL, "graphics hidpi"                    },
		{ entry::Key::Print,        entry::Modifier::None,      1, NULL, "graphics screenshot"               },

		INPUT_BINDING_END
	};

#if BX_PLATFORM_EMSCRIPTEN
	static AppI* s_app;
	static void updateApp()
	{
		s_app->update();
	}
#endif // BX_PLATFORM_EMSCRIPTEN

	int runApp(AppI* _app, int _argc, char** _argv)
	{
		_app->init(_argc, _argv);
		bgfx::frame();

		WindowHandle defaultWindow = { 0 };
		setWindowSize(defaultWindow, ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT);

#if BX_PLATFORM_EMSCRIPTEN
		s_app = _app;
		emscripten_set_main_loop(&updateApp, -1, 1);
#else
		while (_app->update() );
#endif // BX_PLATFORM_EMSCRIPTEN

		return _app->shutdown();
	}

	int main(int _argc, char** _argv)
	{
		//DBG(BX_COMPILER_NAME " / " BX_CPU_NAME " / " BX_ARCH_NAME " / " BX_PLATFORM_NAME);

		if (BX_ENABLED(ENTRY_CONFIG_PROFILER) )
		{
			rmtSettings* settings = rmt_Settings();
			BX_WARN(NULL != settings, "Remotery is not enabled.");
			if (NULL != settings)
			{
				settings->malloc  = rmtMalloc;
				settings->realloc = rmtRealloc;
				settings->free    = rmtFree;

				rmtError err = rmt_CreateGlobalInstance(&s_rmt);
				BX_WARN(RMT_ERROR_NONE != err, "Remotery failed to create global instance.");
				if (RMT_ERROR_NONE == err)
				{
					rmt_SetCurrentThreadName("Main");
				}
				else
				{
					s_rmt = NULL;
				}
			}
		}

#if BX_CONFIG_CRT_FILE_READER_WRITER
		s_fileReader = new bx::CrtFileReader;
		s_fileWriter = new bx::CrtFileWriter;
#endif // BX_CONFIG_CRT_FILE_READER_WRITER

		cmdInit();
		cmdAdd("mouselock", cmdMouseLock);
		cmdAdd("graphics",  cmdGraphics );
		cmdAdd("exit",      cmdExit     );

		inputInit();
		inputAddBindings("bindings", s_bindings);

		entry::WindowHandle defaultWindow = { 0 };
		entry::setWindowTitle(defaultWindow, bx::baseName(_argv[0]) );
		setWindowSize(defaultWindow, ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT);

		int32_t result = ::_main_(_argc, _argv);

		inputRemoveBindings("bindings");
		inputShutdown();

		cmdShutdown();

#if BX_CONFIG_CRT_FILE_READER_WRITER
		delete s_fileReader;
		s_fileReader = NULL;

		delete s_fileWriter;
		s_fileWriter = NULL;
#endif // BX_CONFIG_CRT_FILE_READER_WRITER

		if (BX_ENABLED(ENTRY_CONFIG_PROFILER)
		&&  NULL != s_rmt)
		{
			rmt_DestroyGlobalInstance(s_rmt);
		}

		return result;
	}

	bool processEvents(uint32_t& _width, uint32_t& _height, uint32_t& _debug, uint32_t& _reset, MouseState* _mouse)
	{
		s_debug = _debug;
		s_reset = _reset;

		WindowHandle handle = { UINT16_MAX };

		bool mouseLock = inputIsMouseLocked();

		const Event* ev;
		do
		{
			struct SE { const Event* m_ev; SE() : m_ev(poll() ) {} ~SE() { if (NULL != m_ev) { release(m_ev); } } } scopeEvent;
			ev = scopeEvent.m_ev;

			if (NULL != ev)
			{
				switch (ev->m_type)
				{
				case Event::Axis:
					{
						const AxisEvent* axis = static_cast<const AxisEvent*>(ev);
						inputSetGamepadAxis(axis->m_gamepad, axis->m_axis, axis->m_value);
					}
					break;

				case Event::Char:
					{
						const CharEvent* chev = static_cast<const CharEvent*>(ev);
						inputChar(chev->m_len, chev->m_char);
					}
					break;

				case Event::Exit:
					return true;

				case Event::Gamepad:
					{
//						const GamepadEvent* gev = static_cast<const GamepadEvent*>(ev);
//						DBG("gamepad %d, %d", gev->m_gamepad.idx, gev->m_connected);
					}
					break;

				case Event::Mouse:
					{
						const MouseEvent* mouse = static_cast<const MouseEvent*>(ev);
						handle = mouse->m_handle;

						inputSetMousePos(mouse->m_mx, mouse->m_my, mouse->m_mz);
						if (!mouse->m_move)
						{
							inputSetMouseButtonState(mouse->m_button, mouse->m_down);
						}

						if (NULL != _mouse
						&&  !mouseLock)
						{
							_mouse->m_mx = mouse->m_mx;
							_mouse->m_my = mouse->m_my;
							_mouse->m_mz = mouse->m_mz;
							if (!mouse->m_move) 
							{
								_mouse->m_buttons[mouse->m_button] = mouse->m_down;
							}
						}
					}
					break;

				case Event::Key:
					{
						const KeyEvent* key = static_cast<const KeyEvent*>(ev);
						handle = key->m_handle;

						inputSetKeyState(key->m_key, key->m_modifiers, key->m_down);
					}
					break;

				case Event::Size:
					{
						const SizeEvent* size = static_cast<const SizeEvent*>(ev);
						handle  = size->m_handle;
						_width  = size->m_width;
						_height = size->m_height;
						_reset  = !s_reset; // force reset
					}
					break;

				case Event::Window:
					break;

				case Event::Suspend:
					break;

				default:
					break;
				}
			}

			inputProcess();

		} while (NULL != ev);

		if (handle.idx == 0
		&&  _reset != s_reset)
		{
			_reset = s_reset;
			bgfx::reset(_width, _height, _reset);
			inputSetMouseResolution(uint16_t(_width), uint16_t(_height) );
		}

		_debug = s_debug;

		return s_exit;
	}

	WindowState s_window[ENTRY_CONFIG_MAX_WINDOWS];

	bool processWindowEvents(WindowState& _state, uint32_t& _debug, uint32_t& _reset)
	{
		s_debug = _debug;
		s_reset = _reset;

		WindowHandle handle = { UINT16_MAX };

		bool mouseLock = inputIsMouseLocked();

		const Event* ev;
		do
		{
			struct SE
			{
				SE(WindowHandle _handle)
					: m_ev(poll(_handle) )
				{
				}

				~SE()
				{
					if (NULL != m_ev)
					{
						release(m_ev);
					}
				}

				const Event* m_ev;

			} scopeEvent(handle);
			ev = scopeEvent.m_ev;

			if (NULL != ev)
			{
				handle = ev->m_handle;
				WindowState& win = s_window[handle.idx];

				switch (ev->m_type)
				{
				case Event::Axis:
					{
						const AxisEvent* axis = static_cast<const AxisEvent*>(ev);
						inputSetGamepadAxis(axis->m_gamepad, axis->m_axis, axis->m_value);
					}
					break;

				case Event::Char:
					{
						const CharEvent* chev = static_cast<const CharEvent*>(ev);
						win.m_handle = chev->m_handle;
						inputChar(chev->m_len, chev->m_char);
					}
					break;

				case Event::Exit:
					return true;

				case Event::Gamepad:
					{
						const GamepadEvent* gev = static_cast<const GamepadEvent*>(ev);
						DBG("gamepad %d, %d", gev->m_gamepad.idx, gev->m_connected);
					}
					break;

				case Event::Mouse:
					{
						const MouseEvent* mouse = static_cast<const MouseEvent*>(ev);
						win.m_handle = mouse->m_handle;

						if (mouse->m_move)
						{
							inputSetMousePos(mouse->m_mx, mouse->m_my, mouse->m_mz);
						}
						else
						{
							inputSetMouseButtonState(mouse->m_button, mouse->m_down);
						}

						if (!mouseLock)
						{
							if (mouse->m_move)
							{
								win.m_mouse.m_mx = mouse->m_mx;
								win.m_mouse.m_my = mouse->m_my;
								win.m_mouse.m_mz = mouse->m_mz;
							}
							else
							{
								win.m_mouse.m_buttons[mouse->m_button] = mouse->m_down;
							}
						}
					}
					break;

				case Event::Key:
					{
						const KeyEvent* key = static_cast<const KeyEvent*>(ev);
						win.m_handle = key->m_handle;

						inputSetKeyState(key->m_key, key->m_modifiers, key->m_down);
					}
					break;

				case Event::Size:
					{
						const SizeEvent* size = static_cast<const SizeEvent*>(ev);
						win.m_handle = size->m_handle;
						win.m_width  = size->m_width;
						win.m_height = size->m_height;
						_reset  = win.m_handle.idx == 0
								? !s_reset
								: _reset
								; // force reset
					}
					break;

				case Event::Window:
					{
						const WindowEvent* window = static_cast<const WindowEvent*>(ev);
						win.m_handle = window->m_handle;
						win.m_nwh    = window->m_nwh;
						ev = NULL;
					}
					break;

				case Event::Suspend:
					break;

				default:
					break;
				}
			}

			inputProcess();

		} while (NULL != ev);

		if (isValid(handle) )
		{
			const WindowState& win = s_window[handle.idx];
			_state = win;

			if (handle.idx == 0)
			{
				inputSetMouseResolution(uint16_t(win.m_width), uint16_t(win.m_height) );
			}
		}

		if (_reset != s_reset)
		{
			_reset = s_reset;
			bgfx::reset(s_window[0].m_width, s_window[0].m_height, _reset);
			inputSetMouseResolution(uint16_t(s_window[0].m_width), uint16_t(s_window[0].m_height) );
		}

		_debug = s_debug;

		return s_exit;
	}

	bx::FileReaderI* getFileReader()
	{
		return s_fileReader;
	}

	bx::FileWriterI* getFileWriter()
	{
		return s_fileWriter;
	}

	bx::AllocatorI* getAllocator()
	{
		return s_allocator;
	}

	void* TinyStlAllocator::static_allocate(size_t _bytes)
	{
		return BX_ALLOC(getAllocator(), _bytes);
	}

	void TinyStlAllocator::static_deallocate(void* _ptr, size_t /*_bytes*/)
	{
		if (NULL != _ptr)
		{
			BX_FREE(getAllocator(), _ptr);
		}
	}

} // namespace entry
Ejemplo n.º 23
0
	static void initTranslateKey(uint16_t _xk, Key::Enum _key)
	{
		_xk += 256;
		BX_CHECK(_xk < BX_COUNTOF(s_translateKey), "Out of bounds %d.", _xk);
		s_translateKey[_xk&0x1ff] = (uint8_t)_key;
	}
Ejemplo n.º 24
0
	int32_t read(bx::ReaderI* _reader, SpvInstruction& _instruction, bx::Error* _err)
	{
		int32_t size = 0;

		uint32_t token;
		size += bx::read(_reader, token, _err);

		_instruction.opcode = SpvOpcode::Enum( (token & UINT32_C(0x0000ffff) )      );
		_instruction.length =        uint16_t( (token & UINT32_C(0xffff0000) ) >> 16);

		if (_instruction.opcode >= SpvOpcode::Count)
		{
			BX_ERROR_SET(_err, BGFX_SHADER_SPIRV_INVALID_INSTRUCTION, "SPIR-V: Invalid instruction.");
			return size;
		}

		if (0 == _instruction.length)
		{
			return size;
		}

		const SpvOpcodeInfo& info = s_spvOpcodeInfo[_instruction.opcode];
		_instruction.hasType   = info.hasType;
		_instruction.hasResult = info.hasResult;

		if (info.hasType)
		{
			size += read(_reader, _instruction.type, _err);
		}
		else
		{
			_instruction.type = UINT32_MAX;
		}

		if (info.hasResult)
		{
			size += read(_reader, _instruction.result, _err);
		}
		else
		{
			_instruction.result = UINT32_MAX;
		}

		uint16_t currOp = 0;
		switch (_instruction.opcode)
		{
		case SpvOpcode::EntryPoint:
			_instruction.operand[currOp].type = info.operands[currOp];
			size += read(_reader, _instruction.operand[currOp++], _err);
			_instruction.operand[currOp].type = info.operands[currOp];
			size += read(_reader, _instruction.operand[currOp++], _err);
			_instruction.operand[currOp].type = info.operands[currOp];
			size += read(_reader, _instruction.operand[currOp++], _err);

			_instruction.operand[currOp].type = SpvOperand::Id;
			for (uint32_t ii = 0, num = _instruction.length - size/4; ii < num; ++ii)
			{
				size += read(_reader, _instruction.operand[currOp], _err);
			}
			break;

		default:
			for (
				;  size/4 != _instruction.length
				&& _err->isOk()
				&& currOp < BX_COUNTOF(_instruction.operand)
				; ++currOp)
			{
				_instruction.operand[currOp].type = info.operands[currOp];
				size += read(_reader, _instruction.operand[currOp], _err);
			}
			break;
		}

		_instruction.numOperands = currOp;

		return size;
	}
Ejemplo n.º 25
0
		"Index",
		"Binding",
		"DescriptorSet",
		"Offset",
		"XfbBuffer",
		"XfbStride",
		"FuncParamAttr",
		"FPRoundingMode",
		"FPFastMathMode",
		"LinkageAttributes",
		"NoContraction",
		"InputAttachmentIndex",
		"Alignment",
		""
	};
	BX_STATIC_ASSERT(BX_COUNTOF(s_spvDecoration)-1 == SpvDecoration::Count);

	const char* getName(SpvDecoration::Enum _enum)
	{
		BX_CHECK(_enum <= SpvDecoration::Count, "Unknown decoration id %d.", _enum);
		return _enum <= SpvDecoration::Count
			?  s_spvDecoration[_enum]
			: "?SpvDecoration?"
			;
	}

#undef _
#undef SPV_OPERAND

	static const char* s_spvStorageClass[] =
	{
Ejemplo n.º 26
0
	"InOutCirc",
	"OutInCirc",
	"InElastic",
	"OutElastic",
	"InOutElastic",
	"OutInElastic",
	"InBack",
	"OutBack",
	"InOutBack",
	"OutInBack",
	"InBounce",
	"OutBounce",
	"InOutBounce",
	"OutInBounce",
};
BX_STATIC_ASSERT(BX_COUNTOF(s_easeFuncName) == bx::Easing::Count);

struct Emitter
{
	EmitterUniforms m_uniforms;
	EmitterHandle   m_handle;

	EmitterShape::Enum     m_shape;
	EmitterDirection::Enum m_direction;

	void create()
	{
		m_shape      = EmitterShape::Sphere;
		m_direction  = EmitterDirection::Outward;

		m_handle = psCreateEmitter(m_shape, m_direction, 1024);
Ejemplo n.º 27
0
		void spawn(float _dt)
		{
			float mtx[16];
			bx::mtxSRT(mtx
				, 1.0f, 1.0f, 1.0f
				, m_uniforms.m_angle[0],    m_uniforms.m_angle[1],    m_uniforms.m_angle[2]
				, m_uniforms.m_position[0], m_uniforms.m_position[1], m_uniforms.m_position[2]
				);

			const float timePerParticle = 1.0f/m_uniforms.m_particlesPerSecond;
			m_dt += _dt;
			const uint32_t numParticles = uint32_t(m_dt / timePerParticle);
			m_dt -= numParticles * timePerParticle;

			float time = 0.0f;
			for (uint32_t ii = 0
				; ii < numParticles && m_num < m_max
				; ++ii
				)
			{
				Particle& particle = m_particles[m_num];
				m_num++;

				const float up[3] = { 0.0f, 1.0f, 0.0f };

				float pos[3];
				switch (m_shape)
				{
					default:
					case EmitterShape::Sphere:
						bx::randUnitSphere(pos, &m_rng);
						break;

					case EmitterShape::Hemisphere:
						bx::randUnitHemisphere(pos, &m_rng, up);
						break;

					case EmitterShape::Circle:
						bx::randUnitCircle(pos, &m_rng);
						break;

					case EmitterShape::Disc:
						{
							float tmp[3];
							bx::randUnitCircle(tmp, &m_rng);
							bx::vec3Mul(pos, tmp, bx::frnd(&m_rng) );
						}
						break;

					case EmitterShape::Rect:
						pos[0] = bx::frndh(&m_rng);
						pos[1] = 0.0f;
						pos[2] = bx::frndh(&m_rng);
						break;
				}

				float dir[3];
				switch (m_direction)
				{
					default:
					case EmitterDirection::Up:
						bx::vec3Move(dir, up);
						break;

					case EmitterDirection::Outward:
						bx::vec3Norm(dir, pos);
						break;
				}

				float start[3];
				float end[3];
				const float startOffset = bx::flerp(m_uniforms.m_offsetStart[0], m_uniforms.m_offsetStart[1], bx::frnd(&m_rng) );
				bx::vec3Mul(start, pos, startOffset);

				const float endOffset = bx::flerp(m_uniforms.m_offsetEnd[0], m_uniforms.m_offsetEnd[1], bx::frnd(&m_rng) );
				float tmp1[3];
				bx::vec3Mul(tmp1, dir, endOffset);
				bx::vec3Add(end, tmp1, start);

				particle.life = time;
				particle.lifeSpan = bx::flerp(m_uniforms.m_lifeSpan[0], m_uniforms.m_lifeSpan[1], bx::frnd(&m_rng) );

				float gravity[3] = { 0.0f, -9.81f * m_uniforms.m_gravityScale * bx::fsq(particle.lifeSpan), 0.0f };

				bx::vec3MulMtx(particle.start,  start, mtx);
				bx::vec3MulMtx(particle.end[0], end,   mtx);
				bx::vec3Add(particle.end[1], particle.end[0], gravity);

				bx::memCopy(particle.rgba, m_uniforms.m_rgba, BX_COUNTOF(m_uniforms.m_rgba)*sizeof(uint32_t) );

				particle.blendStart = bx::flerp(m_uniforms.m_blendStart[0], m_uniforms.m_blendStart[1], bx::frnd(&m_rng) );
				particle.blendEnd   = bx::flerp(m_uniforms.m_blendEnd[0],   m_uniforms.m_blendEnd[1],   bx::frnd(&m_rng) );

				particle.scaleStart = bx::flerp(m_uniforms.m_scaleStart[0], m_uniforms.m_scaleStart[1], bx::frnd(&m_rng) );
				particle.scaleEnd   = bx::flerp(m_uniforms.m_scaleEnd[0],   m_uniforms.m_scaleEnd[1],   bx::frnd(&m_rng) );

				time += timePerParticle;
			}
		}
Ejemplo n.º 28
0
	void imgui(const float* _view, const float* _proj)
	{
//		if (ImGui::CollapsingHeader("General") )
		{
			if (ImGui::Combo("Shape", (int*)&m_shape, s_shapeNames, BX_COUNTOF(s_shapeNames) )
			||  ImGui::Combo("Direction", (int*)&m_direction, s_directionName, BX_COUNTOF(s_directionName) ) )
			{
				psDestroyEmitter(m_handle);
				m_handle = psCreateEmitter(m_shape, m_direction, 1024);
			}

			ImGui::SliderInt("particles / s", (int*)&m_uniforms.m_particlesPerSecond, 0, 1024);

			ImGui::SliderFloat("Gravity scale"
					, &m_uniforms.m_gravityScale
					, -2.0f
					,  2.0f
					);

			ImGui::RangeSliderFloat("Life span"
					, &m_uniforms.m_lifeSpan[0]
					, &m_uniforms.m_lifeSpan[1]
					, 0.1f
					, 5.0f
					);

			if (ImGui::Button("Reset") )
			{
				psUpdateEmitter(m_handle);
			}
		}

		if (ImGui::CollapsingHeader("Position and scale") )
		{
			ImGui::Combo("Position Ease", (int*)&m_uniforms.m_easePos, s_easeFuncName, BX_COUNTOF(s_easeFuncName) );

			ImGui::RangeSliderFloat("Start offset"
					, &m_uniforms.m_offsetStart[0]
					, &m_uniforms.m_offsetStart[1]
					, 0.0f
					, 10.0f
					);
			ImGui::RangeSliderFloat("End offset"
					, &m_uniforms.m_offsetEnd[0]
					, &m_uniforms.m_offsetEnd[1]
					, 0.0f
					, 10.0f
					);

			ImGui::Text("Scale:");

			ImGui::Combo("Scale Ease", (int*)&m_uniforms.m_easeScale, s_easeFuncName, BX_COUNTOF(s_easeFuncName) );

			ImGui::RangeSliderFloat("Scale Start"
					, &m_uniforms.m_scaleStart[0]
					, &m_uniforms.m_scaleStart[1]
					, 0.0f
					, 3.0f
					);
			ImGui::RangeSliderFloat("Scale End"
					, &m_uniforms.m_scaleEnd[0]
					, &m_uniforms.m_scaleEnd[1]
					, 0.0f
					, 3.0f
					);
		}

		if (ImGui::CollapsingHeader("Blending and color") )
		{
			ImGui::Combo("Blend Ease", (int*)&m_uniforms.m_easeBlend, s_easeFuncName, BX_COUNTOF(s_easeFuncName) );
			ImGui::RangeSliderFloat("Blend Start"
					, &m_uniforms.m_blendStart[0]
					, &m_uniforms.m_blendStart[1]
					, 0.0f
					, 1.0f
					);
			ImGui::RangeSliderFloat("Blend End"
					, &m_uniforms.m_blendEnd[0]
					, &m_uniforms.m_blendEnd[1]
					, 0.0f
					, 1.0f
					);

			ImGui::Text("Color:");

			ImGui::Combo("RGBA Ease", (int*)&m_uniforms.m_easeRgba, s_easeFuncName, BX_COUNTOF(s_easeFuncName) );
			ImGui::ColorEdit4("RGBA0", &m_uniforms.m_rgba[0], true);
			ImGui::ColorEdit4("RGBA1", &m_uniforms.m_rgba[1], true);
			ImGui::ColorEdit4("RGBA2", &m_uniforms.m_rgba[2], true);
			ImGui::ColorEdit4("RGBA3", &m_uniforms.m_rgba[3], true);
			ImGui::ColorEdit4("RGBA4", &m_uniforms.m_rgba[4], true);
		}

		ImGui::End();

		float mtx[16];
		bx::mtxSRT(mtx
				, 1.0f, 1.0f, 1.0f
				, m_uniforms.m_angle[0],    m_uniforms.m_angle[1],    m_uniforms.m_angle[2]
				, m_uniforms.m_position[0], m_uniforms.m_position[1], m_uniforms.m_position[2]
				);

		ImGuizmo::Manipulate(
				_view
				, _proj
				, ImGuizmo::TRANSLATE
				, ImGuizmo::LOCAL
				, mtx
				);

		float scale[3];
		ImGuizmo::DecomposeMatrixToComponents(mtx, m_uniforms.m_position, m_uniforms.m_angle, scale);
	}
Ejemplo n.º 29
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;
}
Ejemplo n.º 30
0
	void create(float _fontSize, bx::AllocatorI* _allocator)
	{
		m_allocator = _allocator;

		if (NULL == _allocator)
		{
			static bx::DefaultAllocator allocator;
			m_allocator = &allocator;
		}

		m_viewId = 255;
		m_lastScroll = 0;
		m_last = bx::getHPCounter();

		ImGuiIO& io = ImGui::GetIO();
		io.RenderDrawListsFn = renderDrawLists;
		io.MemAllocFn = memAlloc;
		io.MemFreeFn  = memFree;

		io.DisplaySize = ImVec2(1280.0f, 720.0f);
		io.DeltaTime   = 1.0f / 60.0f;
		io.IniFilename = NULL;

		setupStyle(true);

#if defined(SCI_NAMESPACE)
		io.KeyMap[ImGuiKey_Tab]        = (int)entry::Key::Tab;
		io.KeyMap[ImGuiKey_LeftArrow]  = (int)entry::Key::Left;
		io.KeyMap[ImGuiKey_RightArrow] = (int)entry::Key::Right;
		io.KeyMap[ImGuiKey_UpArrow]    = (int)entry::Key::Up;
		io.KeyMap[ImGuiKey_DownArrow]  = (int)entry::Key::Down;
		io.KeyMap[ImGuiKey_Home]       = (int)entry::Key::Home;
		io.KeyMap[ImGuiKey_End]        = (int)entry::Key::End;
		io.KeyMap[ImGuiKey_Delete]     = (int)entry::Key::Delete;
		io.KeyMap[ImGuiKey_Backspace]  = (int)entry::Key::Backspace;
		io.KeyMap[ImGuiKey_Enter]      = (int)entry::Key::Return;
		io.KeyMap[ImGuiKey_Escape]     = (int)entry::Key::Esc;
		io.KeyMap[ImGuiKey_A]          = (int)entry::Key::KeyA;
		io.KeyMap[ImGuiKey_C]          = (int)entry::Key::KeyC;
		io.KeyMap[ImGuiKey_V]          = (int)entry::Key::KeyV;
		io.KeyMap[ImGuiKey_X]          = (int)entry::Key::KeyX;
		io.KeyMap[ImGuiKey_Y]          = (int)entry::Key::KeyY;
		io.KeyMap[ImGuiKey_Z]          = (int)entry::Key::KeyZ;
#endif // defined(SCI_NAMESPACE)

		bgfx::RendererType::Enum type = bgfx::getRendererType();
		m_program = bgfx::createProgram(
			  bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_ocornut_imgui")
			, bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_ocornut_imgui")
			, true
			);

		u_imageLodEnabled = bgfx::createUniform("u_imageLodEnabled", bgfx::UniformType::Vec4);
		m_imageProgram = bgfx::createProgram(
			  bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_imgui_image")
			, bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_imgui_image")
			, true
			);

		m_decl
			.begin()
			.add(bgfx::Attrib::Position,  2, bgfx::AttribType::Float)
			.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
			.add(bgfx::Attrib::Color0,    4, bgfx::AttribType::Uint8, true)
			.end();

		s_tex = bgfx::createUniform("s_tex", bgfx::UniformType::Int1);

		uint8_t* data;
		int32_t width;
		int32_t height;
		{
			ImFontConfig config;
			config.FontDataOwnedByAtlas = false;
			config.MergeMode = false;
//			config.MergeGlyphCenterV = true;

			const ImWchar* ranges = io.Fonts->GetGlyphRangesCyrillic();
			m_font[ImGui::Font::Regular] = io.Fonts->AddFontFromMemoryTTF( (void*)s_robotoRegularTtf,     sizeof(s_robotoRegularTtf),     _fontSize,      &config, ranges);
			m_font[ImGui::Font::Mono   ] = io.Fonts->AddFontFromMemoryTTF( (void*)s_robotoMonoRegularTtf, sizeof(s_robotoMonoRegularTtf), _fontSize-3.0f, &config, ranges);

			config.MergeMode = true;
			config.DstFont   = m_font[ImGui::Font::Regular];

			for (uint32_t ii = 0; ii < BX_COUNTOF(s_fontRangeMerge); ++ii)
			{
				const FontRangeMerge& frm = s_fontRangeMerge[ii];

				io.Fonts->AddFontFromMemoryTTF( (void*)frm.data
						, (int)frm.size
						, _fontSize-3.0f
						, &config
						, frm.ranges
						);
			}
		}

		io.Fonts->GetTexDataAsRGBA32(&data, &width, &height);

		m_texture = bgfx::createTexture2D(
			  (uint16_t)width
			, (uint16_t)height
			, false
			, 1
			, bgfx::TextureFormat::BGRA8
			, 0
			, bgfx::copy(data, width*height*4)
			);

		ImGui::InitDockContext();
	}