Exemple #1
0
//==============================================================================
Error XmlElement::getMat4(Mat4& out) const
{
	DArrayAuto<F64> arr(m_alloc);
	Error err = getFloats(arr);	

	if(!err && arr.getSize() != 16)
	{
		ANKI_LOGE("Expecting 16 elements for Mat4");
		err = ErrorCode::USER_DATA;
	}

	if(!err)
	{
		for(U i = 0; i < 16 && !err; i++)
		{
			out[i] = arr[i];
		}
	}

	if(err)
	{
		ANKI_LOGE("Failed to return Mat4. Element: %s", m_el->Value());
	}

	return err;
}
//==============================================================================
static ANKI_USE_RESULT Error loadTga(ResourceFilePtr fs,
	U32& width,
	U32& height,
	U32& bpp,
	DynamicArray<U8>& data,
	GenericMemoryPoolAllocator<U8>& alloc)
{
	char myTgaHeader[12];

	ANKI_CHECK(fs->read(&myTgaHeader[0], sizeof(myTgaHeader)));

	if(memcmp(tgaHeaderUncompressed, &myTgaHeader[0], sizeof(myTgaHeader)) == 0)
	{
		ANKI_CHECK(loadUncompressedTga(fs, width, height, bpp, data, alloc));
	}
	else if(std::memcmp(
				tgaHeaderCompressed, &myTgaHeader[0], sizeof(myTgaHeader))
		== 0)
	{
		ANKI_CHECK(loadCompressedTga(fs, width, height, bpp, data, alloc));
	}
	else
	{
		ANKI_LOGE("Invalid image header");
		return ErrorCode::USER_DATA;
	}

	if(bpp != 32 && bpp != 24)
	{
		ANKI_LOGE("Invalid bpp");
		return ErrorCode::USER_DATA;
	}

	return ErrorCode::NONE;
}
Exemple #3
0
//==============================================================================
Error XmlElement::getVec4(Vec4& out) const
{
	DynamicArrayAuto<F64> arr(m_alloc);
	Error err = getFloats(arr);

	if(!err && arr.getSize() != 4)
	{
		ANKI_LOGE("Expecting 4 elements for Vec3");
		err = ErrorCode::USER_DATA;
	}

	if(!err)
	{
		for(U i = 0; i < 4; i++)
		{
			out[i] = arr[i];
		}
	}

	if(err)
	{
		ANKI_LOGE("Failed to return Vec4. Element: %s", m_el->Value());
	}

	return err;
}
//==============================================================================
Error ShaderLoader::parseFileIncludes(ResourceFilename filename, U32 depth)
{
	// first check the depth
	if(depth > MAX_INCLUDE_DEPTH)
	{
		ANKI_LOGE("The include depth is too high. "
				  "Probably circular includance");
		return ErrorCode::USER_DATA;
	}

	// load file in lines
	StringAuto txt(m_alloc);
	StringListAuto lines(m_alloc);

	ResourceFilePtr file;
	ANKI_CHECK(m_manager->getFilesystem().openFile(filename, file));
	ANKI_CHECK(file->readAllText(TempResourceAllocator<char>(m_alloc), txt));
	lines.splitString(txt.toCString(), '\n');
	if(lines.getSize() < 1)
	{
		ANKI_LOGE("File is empty: %s", &filename[0]);
		return ErrorCode::USER_DATA;
	}

	for(const String& line : lines)
	{
		static const CString token = "#include \"";

		if(line.find(token) == 0)
		{
			// - Expect something between the quotes
			// - Expect the last char to be a quote
			if(line.getLength() >= token.getLength() + 2
				&& line[line.getLength() - 1] == '\"')
			{
				StringAuto filen(m_alloc);
				filen.create(line.begin() + token.getLength(), line.end() - 1);

				ANKI_CHECK(parseFileIncludes(filen.toCString(), depth + 1));
			}
			else
			{
				ANKI_LOGE("Malformed #include: %s", &line[0]);
				return ErrorCode::USER_DATA;
			}
		}
		else
		{
			m_sourceLines.pushBackSprintf(m_alloc, "%s", &line[0]);
		}
	}

	return ErrorCode::NONE;
}
Exemple #5
0
//==============================================================================
Error XmlDocument::loadFile(const CString& filename, 
	GenericMemoryPoolAllocator<U8> alloc)
{
	Error err = ErrorCode::NONE;

	File file;
	err = file.open(filename, File::OpenFlag::READ);
	if(err)
	{
		return err;
	}

	m_alloc = alloc;
	String text;
	
	err = file.readAllText(m_alloc, text);
	if(err)
	{
		return err;
	}

	if(m_doc.Parse(&text[0]))
	{
		ANKI_LOGE("Cannot parse file. Reason: %s",
			((m_doc.GetErrorStr1() == nullptr)
			? "unknown" : m_doc.GetErrorStr1()));
	}

	text.destroy(m_alloc);

	return err;
}
Exemple #6
0
//==============================================================================
/// Given a string that defines blending return the GLenum
static GLenum blendToEnum(const CString& str)
{
// Dont make idiotic mistakes
#define TXT_AND_ENUM(x) \
	if(str == #x) \
	{ \
		return x; \
	}

	TXT_AND_ENUM(GL_ZERO)
	TXT_AND_ENUM(GL_ONE)
	TXT_AND_ENUM(GL_DST_COLOR)
	TXT_AND_ENUM(GL_ONE_MINUS_DST_COLOR)
	TXT_AND_ENUM(GL_SRC_ALPHA)
	TXT_AND_ENUM(GL_ONE_MINUS_SRC_ALPHA)
	TXT_AND_ENUM(GL_DST_ALPHA)
	TXT_AND_ENUM(GL_ONE_MINUS_DST_ALPHA)
	TXT_AND_ENUM(GL_SRC_ALPHA_SATURATE)
	TXT_AND_ENUM(GL_SRC_COLOR)
	TXT_AND_ENUM(GL_ONE_MINUS_SRC_COLOR);
	ANKI_LOGE("Incorrect blend enum");
	return 0;

#undef TXT_AND_ENUM
}
	Error operator()(AsyncLoaderTaskContext& ctx)
	{
		if(m_count)
		{
			auto x = m_count->fetchAdd(1);

			if(m_id >= 0)
			{
				if(m_id != static_cast<I32>(x))
				{
					ANKI_LOGE("Wrong excecution order");
					return ErrorCode::FUNCTION_FAILED;
				}
			}
		}

		if(m_sleepTime != 0.0)
		{
			HighRezTimer::sleep(m_sleepTime);
		}

		if(m_barrier)
		{
			m_barrier->wait();
		}

		ctx.m_pause = m_pause;
		ctx.m_resubmitTask = m_resubmit;
		m_resubmit = false;

		return ErrorCode::NONE;
	}
Exemple #8
0
Error GrManagerImpl::initDevice(const GrManagerInitInfo& init)
{
	uint32_t count = 0;
	vkGetPhysicalDeviceQueueFamilyProperties(m_physicalDevice, &count, nullptr);
	ANKI_LOGI("VK: Number of queue families: %u\n", count);

	DynamicArrayAuto<VkQueueFamilyProperties> queueInfos(getAllocator());
	queueInfos.create(count);
	vkGetPhysicalDeviceQueueFamilyProperties(m_physicalDevice, &count, &queueInfos[0]);

	uint32_t desiredFamilyIdx = MAX_U32;
	const VkQueueFlags DESITED_QUEUE_FLAGS = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT;
	for(U i = 0; i < count; ++i)
	{
		if((queueInfos[i].queueFlags & DESITED_QUEUE_FLAGS) == DESITED_QUEUE_FLAGS)
		{
			VkBool32 supportsPresent = false;
			ANKI_VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(m_physicalDevice, i, m_surface, &supportsPresent));

			if(supportsPresent)
			{
				desiredFamilyIdx = i;
				break;
			}
		}
	}

	if(desiredFamilyIdx == MAX_U32)
	{
		ANKI_LOGE("Couldn't find a queue family with graphics+compute+transfer+present."
				  "The assumption was wrong. The code needs to be reworked");
		return ErrorCode::FUNCTION_FAILED;
	}

	m_queueIdx = desiredFamilyIdx;

	F32 priority = 1.0;
	VkDeviceQueueCreateInfo q = {};
	q.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
	q.queueFamilyIndex = desiredFamilyIdx;
	q.queueCount = 1;
	q.pQueuePriorities = &priority;

	static Array<const char*, 1> DEV_EXTENSIONS = {{VK_KHR_SWAPCHAIN_EXTENSION_NAME}};

	VkDeviceCreateInfo ci = {};
	ci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
	ci.queueCreateInfoCount = 1;
	ci.pQueueCreateInfos = &q;
	ci.enabledExtensionCount = DEV_EXTENSIONS.getSize();
	ci.ppEnabledExtensionNames = &DEV_EXTENSIONS[0];
	ci.pEnabledFeatures = &m_devFeatures;

	ANKI_VK_CHECK(vkCreateDevice(m_physicalDevice, &ci, nullptr, &m_device));

	return ErrorCode::NONE;
}
Exemple #9
0
//==============================================================================
ANKI_USE_RESULT Error XmlElement::check() const
{
	Error err = ErrorCode::NONE;
	if(m_el == nullptr)
	{
		ANKI_LOGE("Empty element");
		err = ErrorCode::USER_DATA;
	}
	return err;
}
Exemple #10
0
Error Pps::init(const ConfigSet& config)
{
	Error err = initInternal(config);
	if(err)
	{
		ANKI_LOGE("Failed to init PPS");
	}

	return err;
}
Exemple #11
0
Error Tiler::init()
{
	Error err = initInternal();

	if(err)
	{
		ANKI_LOGE("Failed to init tiler");
	}

	return err;
}
//==============================================================================
Error createDirectory(const CString& dir)
{
	Error err = ErrorCode::NONE;
	if(CreateDirectory(dir.get(), NULL) == 0)
	{
		ANKI_LOGE("Failed to create directory %s", dir.get());
		err = ErrorCode::FUNCTION_FAILED;
	}

	return err;
}
Exemple #13
0
Error GrManagerImpl::init(const GrManagerInitInfo& init)
{
	Error err = initInternal(init);
	if(err)
	{
		ANKI_LOGE("Vulkan initialization failed");
		return ErrorCode::FUNCTION_FAILED;
	}

	return ErrorCode::NONE;
}
Exemple #14
0
Error CollisionResource::load(const ResourceFilename& filename)
{
	XmlElement el;
	XmlDocument doc;
	ANKI_CHECK(openFileParseXml(filename, doc));

	XmlElement collEl;
	ANKI_CHECK(doc.getChildElement("collisionShape", collEl));

	ANKI_CHECK(collEl.getChildElement("type", el));
	CString type;
	ANKI_CHECK(el.getText(type));

	XmlElement valEl;
	ANKI_CHECK(collEl.getChildElement("value", valEl));

	PhysicsWorld& physics = getManager().getPhysicsWorld();
	PhysicsCollisionShapeInitInfo csInit;

	if(type == "sphere")
	{
		F64 tmp;
		ANKI_CHECK(valEl.getF64(tmp));
		m_physicsShape = physics.newInstance<PhysicsSphere>(csInit, tmp);
	}
	else if(type == "box")
	{
		Vec3 extend;
		ANKI_CHECK(valEl.getVec3(extend));
		m_physicsShape = physics.newInstance<PhysicsBox>(csInit, extend);
	}
	else if(type == "staticMesh")
	{
		CString meshfname;
		ANKI_CHECK(valEl.getText(meshfname));

		MeshLoader loader(&getManager());
		ANKI_CHECK(loader.load(meshfname));

		m_physicsShape = physics.newInstance<PhysicsTriangleSoup>(csInit,
			reinterpret_cast<const Vec3*>(loader.getVertexData()),
			loader.getVertexSize(),
			reinterpret_cast<const U16*>(loader.getIndexData()),
			loader.getHeader().m_totalIndicesCount);
	}
	else
	{
		ANKI_LOGE("Incorrect collision type");
		return ErrorCode::USER_DATA;
	}

	return ErrorCode::NONE;
}
Exemple #15
0
//==============================================================================
ANKI_USE_RESULT Error XmlDocument::getChildElement(
	const CString& name, XmlElement& out)
{
	Error err = ErrorCode::NONE;
	out = XmlElement(m_doc.FirstChildElement(&name[0]), m_alloc);

	if(!out)
	{
		ANKI_LOGE("Cannot find tag %s", &name[0]);
		err = ErrorCode::USER_DATA;
	}

	return err;
}
//==============================================================================
static ANKI_USE_RESULT Error loadTga(const CString& filename, 
	U32& width, U32& height, U32& bpp, DArray<U8>& data,
	GenericMemoryPoolAllocator<U8>& alloc)
{
	File fs;
	char myTgaHeader[12];

	ANKI_CHECK(fs.open(filename, 
		File::OpenFlag::READ | File::OpenFlag::BINARY));

	ANKI_CHECK(fs.read(&myTgaHeader[0], sizeof(myTgaHeader)));

	if(std::memcmp(
		tgaHeaderUncompressed, &myTgaHeader[0], sizeof(myTgaHeader)) == 0)
	{
		ANKI_CHECK(loadUncompressedTga(fs, width, height, bpp, data, alloc));
	}
	else if(std::memcmp(tgaHeaderCompressed, &myTgaHeader[0],
		sizeof(myTgaHeader)) == 0)
	{
		ANKI_CHECK(loadCompressedTga(fs, width, height, bpp, data, alloc));
	}
	else
	{
		ANKI_LOGE("Invalid image header");
		return ErrorCode::USER_DATA;
	}

	if(bpp != 32 && bpp != 24)
	{
		ANKI_LOGE("Invalid bpp");
		return ErrorCode::USER_DATA;
	}

	return ErrorCode::NONE;
}
Exemple #17
0
//==============================================================================
Error LuaBinder::evalString(const CString& str)
{
	Error err = ErrorCode::NONE;
	int e = luaL_dostring(m_l, &str[0]);
	if(e)
	{
		ANKI_LOGE("%s", lua_tostring(m_l, -1));
		lua_pop(m_l, 1);
		err = ErrorCode::USER_DATA;
	}

	lua_gc(m_l, LUA_GCCOLLECT, 0);

	return err;
}
Exemple #18
0
StdinListener::~StdinListener()
{
	m_quit = true;
	Error err = m_thrd.join();
	if(err)
	{
		ANKI_LOGE("Error when joining StdinListener");
	}

	for(String& s : m_q)
	{
		s.destroy(m_alloc);
	}

	m_q.destroy(m_alloc);
}
//==============================================================================
Error removeDirectory(const CString& dirname)
{
	Error err = ErrorCode::NONE;
	SHFILEOPSTRUCTA fileOperation;
	fileOperation.wFunc = FO_DELETE;
	fileOperation.pFrom = dirname.get();
	fileOperation.fFlags = FOF_NO_UI | FOF_NOCONFIRMATION;

	I result = SHFileOperationA(&fileOperation);
	if(result != 0) 
	{
		ANKI_LOGE("Could not delete directory %s", dirname.get());
		err = ErrorCode::FUNCTION_FAILED;
	}

	return err;
}
//==============================================================================
Error GlFramebuffer::createFbo(
	const Array<U, MAX_COLOR_ATTACHMENTS + 1>& layers,
	GLenum depthStencilBindingPoint)
{
	Error err = ErrorCode::NONE;

	ANKI_ASSERT(!isCreated());
	glGenFramebuffers(1, &m_glName);
	ANKI_ASSERT(m_glName != 0);
	const GLenum target = GL_FRAMEBUFFER;
	glBindFramebuffer(target, m_glName);

	// Attach color
	for(U i = 0; i < MAX_COLOR_ATTACHMENTS; i++)
	{
		if(!m_attachments[i].isCreated())
		{
			continue;
		}
		
		const GlTexture& tex = m_attachments[i]._get();
		attachTextureInternal(GL_COLOR_ATTACHMENT0 + i, tex, layers[i]);
	}

	// Attach depth/stencil
	if(m_attachments[MAX_COLOR_ATTACHMENTS].isCreated())
	{
		ANKI_ASSERT(depthStencilBindingPoint != GL_NONE);

		const GlTexture& tex = m_attachments[MAX_COLOR_ATTACHMENTS]._get();
		attachTextureInternal(depthStencilBindingPoint, tex, 
			layers[MAX_COLOR_ATTACHMENTS]);
	}

	// Check completeness
	GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
	if(status != GL_FRAMEBUFFER_COMPLETE)
	{
		ANKI_LOGE("FBO is incomplete");
		destroy();
		err = ErrorCode::FUNCTION_FAILED;
	}

	return err;
}
//==============================================================================
void RenderingThread::threadLoop()
{
	prepare();

	while(1)
	{
		CommandBufferPtr cmd;

		// Wait for something
		{
			LockGuard<Mutex> lock(m_mtx);
			while(m_tail == m_head)
			{
				m_condVar.wait(m_mtx);
			}

			// Check signals
			if(m_renderingThreadSignal == 1)
			{
				// Requested to stop
				break;
			}

			U64 idx = m_head % m_queue.getSize();
			// Pop a command
			cmd = m_queue[idx];
			m_queue[idx] = CommandBufferPtr(); // Insert empty cmd buffer

			++m_head;
		}

		ANKI_TRACE_START_EVENT(GL_THREAD);
		Error err = cmd->getImplementation().executeAllCommands();
		ANKI_TRACE_STOP_EVENT(GL_THREAD);

		if(err)
		{
			ANKI_LOGE("Error in rendering thread. Aborting");
			abort();
		}
	}

	finish();
}
Exemple #22
0
//==============================================================================
Error XmlElement::getFloats(DynamicArrayAuto<F64>& out) const
{
	Error err = check();

	const char* txt;
	if(!err)
	{
		txt = m_el->GetText();
		if(txt == nullptr)
		{
			err = ErrorCode::USER_DATA;
		}
	}

	StringList list;
	if(!err)
	{
		list.splitString(m_alloc, txt, ' ');
	}

	out = DynamicArrayAuto<F64>(m_alloc);

	if(!err)
	{
		out.create(list.getSize());
	}

	auto it = list.getBegin();
	for(U i = 0; i < out.getSize() && !err; i++)
	{
		err = it->toF64(out[i]);
		++it;
	}

	if(err)
	{
		ANKI_LOGE("Failed to return floats. Element: %s", m_el->Value());
	}

	list.destroy(m_alloc);

	return err;
}
Exemple #23
0
Error PhysicsWorld::create(AllocAlignedCallback allocCb, void* allocCbData)
{
	Error err = ErrorCode::NONE;

	m_alloc = HeapAllocator<U8>(allocCb, allocCbData);

	// Set allocators
	gAlloc = &m_alloc;
	NewtonSetMemorySystem(newtonAlloc, newtonFree);

	// Initialize world
	m_world = NewtonCreate();
	if(!m_world)
	{
		ANKI_LOGE("NewtonCreate() failed");
		return ErrorCode::FUNCTION_FAILED;
	}

	// Set the simplified solver mode (faster but less accurate)
	NewtonSetSolverModel(m_world, 1);

	// Create scene collision
	m_sceneCollision = NewtonCreateSceneCollision(m_world, 0);
	Mat4 trf = Mat4::getIdentity();
	m_sceneBody = NewtonCreateDynamicBody(m_world, m_sceneCollision, &trf[0]);
	NewtonBodySetMaterialGroupID(m_sceneBody, NewtonMaterialGetDefaultGroupID(m_world));

	NewtonDestroyCollision(m_sceneCollision); // destroy old scene
	m_sceneCollision = NewtonBodyGetCollision(m_sceneBody);

	// Set the post update listener
	NewtonWorldAddPostListener(m_world, "world", this, postUpdateCallback, destroyCallback);

	// Set callbacks
	NewtonMaterialSetCollisionCallback(m_world,
		NewtonMaterialGetDefaultGroupID(m_world),
		NewtonMaterialGetDefaultGroupID(m_world),
		nullptr,
		onAabbOverlapCallback,
		onContactCallback);

	return err;
}
Exemple #24
0
//==============================================================================
Error XmlElement::getF64(F64& out) const
{
	Error err = check();

	if(!err)
	{
		const char* txt = m_el->GetText();
		if(txt != nullptr)
		{
			err = CString(txt).toF64(out);
		}
		else
		{
			ANKI_LOGE("Failed to return float. Element: %s", m_el->Value());
			err = ErrorCode::USER_DATA;
		}
	}

	return err;
}
Exemple #25
0
Error DescriptorSetAllocator::allocate(const DescriptorSetLayoutInfo& dsinf, VkDescriptorSet& out)
{
	VkDescriptorSetLayout layout;
	ANKI_CHECK(m_layoutFactory.getOrCreateLayout(dsinf, layout));

	out = VK_NULL_HANDLE;
	VkDescriptorSetAllocateInfo ci = {};
	ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
	ci.descriptorPool = m_globalDPool;
	ci.descriptorSetCount = 1;
	ci.pSetLayouts = &layout;

	LockGuard<Mutex> lock(m_mtx);
	if(++m_descriptorSetAllocationCount > MAX_RESOURCE_GROUPS)
	{
		ANKI_LOGE("Exceeded the MAX_RESOURCE_GROUPS");
		return ErrorCode::OUT_OF_MEMORY;
	}
	ANKI_VK_CHECK(vkAllocateDescriptorSets(m_dev, &ci, &out));
	return ErrorCode::NONE;
}
//==============================================================================
static ANKI_USE_RESULT Error loadUncompressedTga(ResourceFilePtr fs,
	U32& width,
	U32& height,
	U32& bpp,
	DynamicArray<U8>& data,
	GenericMemoryPoolAllocator<U8>& alloc)
{
	Array<U8, 6> header6;

	// read the info from header
	ANKI_CHECK(fs->read((char*)&header6[0], sizeof(header6)));

	width = header6[1] * 256 + header6[0];
	height = header6[3] * 256 + header6[2];
	bpp = header6[4];

	if((width == 0) || (height == 0) || ((bpp != 24) && (bpp != 32)))
	{
		ANKI_LOGE("Invalid image information");
		return ErrorCode::USER_DATA;
	}

	// read the data
	I bytesPerPxl = (bpp / 8);
	I imageSize = bytesPerPxl * width * height;
	data.create(alloc, imageSize);

	ANKI_CHECK(fs->read(reinterpret_cast<char*>(&data[0]), imageSize));

	// swap red with blue
	for(I i = 0; i < imageSize; i += bytesPerPxl)
	{
		U32 temp = data[i];
		data[i] = data[i + 2];
		data[i + 2] = temp;
	}

	return ErrorCode::NONE;
}
Exemple #27
0
Error fileExtensionToShaderType(const CString& filename, ShaderType& type)
{
	type = ShaderType::COUNT;
	Error err = ErrorCode::NONE;

	// Find the shader type
	if(filename.find(".vert.glsl") != ResourceFilename::NPOS)
	{
		type = ShaderType::VERTEX;
	}
	else if(filename.find(".tc.glsl") != ResourceFilename::NPOS)
	{
		type = ShaderType::TESSELLATION_CONTROL;
	}
	else if(filename.find(".te.glsl") != ResourceFilename::NPOS)
	{
		type = ShaderType::TESSELLATION_EVALUATION;
	}
	else if(filename.find(".geom.glsl") != ResourceFilename::NPOS)
	{
		type = ShaderType::GEOMETRY;
	}
	else if(filename.find(".frag.glsl") != ResourceFilename::NPOS)
	{
		type = ShaderType::FRAGMENT;
	}
	else if(filename.find(".comp.glsl") != ResourceFilename::NPOS)
	{
		type = ShaderType::COMPUTE;
	}
	else
	{
		ANKI_LOGE("Wrong shader file format: %s", &filename[0]);
		err = ErrorCode::USER_DATA;
	}

	return err;
}
Exemple #28
0
//==============================================================================
Error XmlElement::getChildElement(const CString& name, XmlElement& out) const
{
	Error err = check();
	if(err)
	{
		out = XmlElement();
		return err;
	}

	err = getChildElementOptional(name, out);
	if(err)
	{
		return err;
	}

	if(!out)
	{
		ANKI_LOGE("Cannot find tag %s", &name[0]);
		err = ErrorCode::USER_DATA;
	}

	return err;
}
//==============================================================================
Error GrManagerImpl::initSurface(const GrManagerInitInfo& init)
{
	SDL_SysWMinfo wminfo;
	SDL_VERSION(&wminfo.version);
	if(!SDL_GetWindowWMInfo(init.m_window->getNative().m_window, &wminfo))
	{
		ANKI_LOGE("SDL_GetWindowWMInfo() failed");
		return ErrorCode::NONE;
	}

#if ANKI_OS == ANKI_OS_LINUX
	VkXcbSurfaceCreateInfoKHR ci = {};
	ci.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR;
	ci.connection = XGetXCBConnection(wminfo.info.x11.display);
	ci.window = wminfo.info.x11.window;

	ANKI_VK_CHECK(vkCreateXcbSurfaceKHR(m_instance, &ci, nullptr, &m_surface));
#else
#error TODO
#endif

	return ErrorCode::NONE;
}
Exemple #30
0
Error DecalComponent::setLayer(CString texAtlasFname, CString texAtlasSubtexName, F32 blendFactor, LayerType type)
{
	Layer& l = m_layers[type];

	ANKI_CHECK(getSceneGraph().getResourceManager().loadResource(texAtlasFname, l.m_atlas));

	ANKI_CHECK(l.m_atlas->getSubTextureInfo(texAtlasSubtexName, &l.m_uv[0]));

	// Add a border to the UVs to avoid complex shader logic
	if(l.m_atlas->getSubTextureMargin() < ATLAS_SUB_TEXTURE_MARGIN)
	{
		ANKI_LOGE("Need texture atlas with margin at least %u", ATLAS_SUB_TEXTURE_MARGIN);
		return ErrorCode::USER_DATA;
	}

	Vec2 marginf = F32(ATLAS_SUB_TEXTURE_MARGIN / 2) / Vec2(l.m_atlas->getWidth(), l.m_atlas->getHeight());
	Vec2 minUv = l.m_uv.xy() - marginf;
	Vec2 sizeUv = (l.m_uv.zw() - l.m_uv.xy()) + 2.0f * marginf;
	l.m_uv = Vec4(minUv.x(), minUv.y(), minUv.x() + sizeUv.x(), minUv.y() + sizeUv.y());

	l.m_blendFactor = blendFactor;
	return ErrorCode::NONE;
}