D3D11: Implement basic screen rotation (90 degree is the only one fully implemented)

This commit is contained in:
Henrik Rydgard authored and Henrik Rydgård committed 2017-03-23 10:02:28 +01:00
1 parent c02060594d
commit 4a98bd904e
6 files changed
+95 -61

No files matched your search

+2 -1
View File
@@ -49,12 +49,13 @@ namespace DX
IWICImagingFactory2* GetWicImagingFactory() const { return m_wicFactory.Get(); }
D2D1::Matrix3x2F GetOrientationTransform2D() const { return m_orientationTransform2D; }
DXGI_MODE_ROTATION ComputeDisplayRotation();
private:
void CreateDeviceIndependentResources();
void CreateDeviceResources();
void CreateWindowSizeDependentResources();
void UpdateRenderTargetSize();
DXGI_MODE_ROTATION ComputeDisplayRotation();
// Direct3D objects.
Microsoft::WRL::ComPtr<ID3D11Device3> m_d3dDevice;
+35 -1
View File
@@ -167,9 +167,23 @@ bool PPSSPP_UWPMain::Render() {
// Reset the viewport to target the whole screen.
auto viewport = m_deviceResources->GetScreenViewport();
switch (m_deviceResources->ComputeDisplayRotation()) {
case DXGI_MODE_ROTATION_IDENTITY: g_display_rotation = DisplayRotation::ROTATE_0; break;
case DXGI_MODE_ROTATION_ROTATE90: g_display_rotation = DisplayRotation::ROTATE_90; break;
case DXGI_MODE_ROTATION_ROTATE180: g_display_rotation = DisplayRotation::ROTATE_180; break;
case DXGI_MODE_ROTATION_ROTATE270: g_display_rotation = DisplayRotation::ROTATE_270; break;
}
// Not super elegant but hey.
memcpy(&g_display_rot_matrix, &m_deviceResources->GetOrientationTransform3D(), sizeof(float) * 16);
pixel_xres = viewport.Width;
pixel_yres = viewport.Height;
if (g_display_rotation == DisplayRotation::ROTATE_90 || g_display_rotation == DisplayRotation::ROTATE_270) {
// We need to swap our width/height.
std::swap(pixel_xres, pixel_yres);
}
g_dpi = m_deviceResources->GetDpi();
g_dpi_scale = 96.0f / g_dpi;
@@ -235,9 +249,28 @@ void PPSSPP_UWPMain::OnMouseWheel(float delta) {
NativeKey(keyInput);
}
void PPSSPP_UWPMain::RotateXYToDisplay(float &x, float &y) {
switch (m_deviceResources->ComputeDisplayRotation()) {
case DXGI_MODE_ROTATION_IDENTITY:
// Nothing to do here.
break;
case DXGI_MODE_ROTATION_ROTATE90:
// TODO
break;
case DXGI_MODE_ROTATION_ROTATE180:
x = m_deviceResources->GetScreenViewport().Width - x;
y = m_deviceResources->GetScreenViewport().Height - y;
break;
case DXGI_MODE_ROTATION_ROTATE270:
// TODO
break;
}
}
void PPSSPP_UWPMain::OnTouchEvent(int touchEvent, int touchId, float x, float y, double timestamp) {
TouchInput input{};
input.id = touchId;
RotateXYToDisplay(x, y);
input.x = x;
input.y = y;
input.flags = touchEvent;
@@ -269,7 +302,8 @@ void PPSSPP_UWPMain::LoadStorageFile(StorageFile ^file) {
}
UWPGraphicsContext::UWPGraphicsContext(std::shared_ptr<DX::DeviceResources> resources) {
draw_ = Draw::T3DCreateD3D11Context(resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetD3DDevice(), resources->GetD3DDeviceContext(), 0);
draw_ = Draw::T3DCreateD3D11Context(
resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetD3DDevice(), resources->GetD3DDeviceContext(), resources->GetDeviceFeatureLevel(), 0);
}
void UWPGraphicsContext::Shutdown() {
+4 -2
View File
@@ -30,8 +30,7 @@ private:
std::shared_ptr<DX::DeviceResources> resources_;
};
class PPSSPP_UWPMain : public DX::IDeviceNotify
{
class PPSSPP_UWPMain : public DX::IDeviceNotify {
public:
PPSSPP_UWPMain(App ^app, const std::shared_ptr<DX::DeviceResources>& deviceResources);
~PPSSPP_UWPMain();
@@ -51,6 +50,9 @@ public:
void OnMouseWheel(float delta);
void RotateXYToDisplay(float &x, float &y);
// Save state fast if we can!
void OnSuspend();
void Close();
+1 -4
View File
@@ -13,7 +13,6 @@ using namespace Windows::Storage::Streams;
std::mutex initMutex;
StorageFileLoader::StorageFileLoader(Windows::Storage::StorageFile ^file) {
initMutex.lock();
file_ = file;
path_ = FromPlatformString(file_->Path);
thread_.reset(new std::thread([this]() { this->threadfunc(); }));
@@ -61,13 +60,11 @@ void StorageFileLoader::threadfunc() {
}
catch (Platform::COMException ^e) {
std::string what = FromPlatformString(e->ToString());
ILOG("%s", what);
ILOG("%s", what.c_str());
}
initMutex.unlock();
initMutex.unlock();
std::unique_lock<std::mutex> lock(mutex_);
while (active_) {
if (!operationRequested_) {
+2 -2
View File
@@ -27,7 +27,7 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0d070030-beb5-4f48-99a0-b1777297a468}</ProjectGuid>
<ProjectGuid>{01D7D581-09A3-4A26-94BD-A7C529B29329}</ProjectGuid>
<Keyword>DirectXApp</Keyword>
<RootNamespace>UWP</RootNamespace>
<DefaultLanguage>en-US</DefaultLanguage>
@@ -334,4 +334,4 @@
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\MeshContentTask.targets" />
<Import Project="$(VSINSTALLDIR)\Common7\IDE\Extensions\Microsoft\VsGraphics\ShaderGraphContentTask.targets" />
</ImportGroup>
</Project>
</Project>
+51 -51
View File
@@ -77,8 +77,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glslang", "..\ext\glslang.v
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SPIRV-Cross", "..\ext\SPIRV-Cross.vcxproj", "{4328A62C-F1E9-47ED-B816-A1A81DAF4363}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PPSSPP_UWP", "..\UWP\UWP.vcxproj", "{0D070030-BEB5-4F48-99A0-B1777297A468}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UWP", "UWP", "{13ED48E6-7BC8-474F-8A8D-195B57921353}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CommonUWP", "..\UWP\CommonUWP\CommonUWP.vcxproj", "{ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}"
@@ -93,10 +91,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UI_UWP", "..\UWP\UI_UWP\UI_
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libkirk_UWP", "..\UWP\libkirk_UWP\libkirk_UWP.vcxproj", "{2F911C05-B341-4291-8BF5-09EDECBDD5F5}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glslang_UWP", "..\UWP\glslang_UWP\glslang_UWP.vcxproj", "{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib_UWP", "..\UWP\zlib_UWP\zlib_UWP.vcxproj", "{DDF90203-0AAE-4F38-B589-2E9637658CE6}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PPSSPP_UWP", "..\UWP\UWP.vcxproj", "{01D7D581-09A3-4A26-94BD-A7C529B29329}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "glslang_UWP", "..\UWP\glslang_UWP\glslang_UWP.vcxproj", "{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SPIRVCross_UWP", "..\UWP\SPIRVCross_UWP\SPIRVCross_UWP.vcxproj", "{2B2D16BD-1D37-46AF-A3F8-552900951B26}"
EndProject
Global
@@ -319,33 +319,6 @@ Global
{4328A62C-F1E9-47ED-B816-A1A81DAF4363}.Tests|Win32.Build.0 = Release|Win32
{4328A62C-F1E9-47ED-B816-A1A81DAF4363}.Tests|x64.ActiveCfg = Release|x64
{4328A62C-F1E9-47ED-B816-A1A81DAF4363}.Tests|x64.Build.0 = Release|x64
{0D070030-BEB5-4F48-99A0-B1777297A468}.Debug|ARM.ActiveCfg = Debug|ARM
{0D070030-BEB5-4F48-99A0-B1777297A468}.Debug|ARM.Build.0 = Debug|ARM
{0D070030-BEB5-4F48-99A0-B1777297A468}.Debug|ARM.Deploy.0 = Debug|ARM
{0D070030-BEB5-4F48-99A0-B1777297A468}.Debug|Win32.ActiveCfg = Debug|Win32
{0D070030-BEB5-4F48-99A0-B1777297A468}.Debug|Win32.Build.0 = Debug|Win32
{0D070030-BEB5-4F48-99A0-B1777297A468}.Debug|Win32.Deploy.0 = Debug|Win32
{0D070030-BEB5-4F48-99A0-B1777297A468}.Debug|x64.ActiveCfg = Debug|x64
{0D070030-BEB5-4F48-99A0-B1777297A468}.Debug|x64.Build.0 = Debug|x64
{0D070030-BEB5-4F48-99A0-B1777297A468}.Debug|x64.Deploy.0 = Debug|x64
{0D070030-BEB5-4F48-99A0-B1777297A468}.Release|ARM.ActiveCfg = Release|ARM
{0D070030-BEB5-4F48-99A0-B1777297A468}.Release|ARM.Build.0 = Release|ARM
{0D070030-BEB5-4F48-99A0-B1777297A468}.Release|ARM.Deploy.0 = Release|ARM
{0D070030-BEB5-4F48-99A0-B1777297A468}.Release|Win32.ActiveCfg = Release|Win32
{0D070030-BEB5-4F48-99A0-B1777297A468}.Release|Win32.Build.0 = Release|Win32
{0D070030-BEB5-4F48-99A0-B1777297A468}.Release|Win32.Deploy.0 = Release|Win32
{0D070030-BEB5-4F48-99A0-B1777297A468}.Release|x64.ActiveCfg = Release|x64
{0D070030-BEB5-4F48-99A0-B1777297A468}.Release|x64.Build.0 = Release|x64
{0D070030-BEB5-4F48-99A0-B1777297A468}.Release|x64.Deploy.0 = Release|x64
{0D070030-BEB5-4F48-99A0-B1777297A468}.Tests|ARM.ActiveCfg = Release|ARM
{0D070030-BEB5-4F48-99A0-B1777297A468}.Tests|ARM.Build.0 = Release|ARM
{0D070030-BEB5-4F48-99A0-B1777297A468}.Tests|ARM.Deploy.0 = Release|ARM
{0D070030-BEB5-4F48-99A0-B1777297A468}.Tests|Win32.ActiveCfg = Release|Win32
{0D070030-BEB5-4F48-99A0-B1777297A468}.Tests|Win32.Build.0 = Release|Win32
{0D070030-BEB5-4F48-99A0-B1777297A468}.Tests|Win32.Deploy.0 = Release|Win32
{0D070030-BEB5-4F48-99A0-B1777297A468}.Tests|x64.ActiveCfg = Release|x64
{0D070030-BEB5-4F48-99A0-B1777297A468}.Tests|x64.Build.0 = Release|x64
{0D070030-BEB5-4F48-99A0-B1777297A468}.Tests|x64.Deploy.0 = Release|x64
{ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Debug|ARM.ActiveCfg = Debug|ARM
{ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Debug|ARM.Build.0 = Debug|ARM
{ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -454,24 +427,6 @@ Global
{2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Tests|Win32.Build.0 = Release|Win32
{2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Tests|x64.ActiveCfg = Release|x64
{2F911C05-B341-4291-8BF5-09EDECBDD5F5}.Tests|x64.Build.0 = Release|x64
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|ARM.ActiveCfg = Debug|ARM
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|ARM.Build.0 = Debug|ARM
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|Win32.ActiveCfg = Debug|Win32
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|Win32.Build.0 = Debug|Win32
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|x64.ActiveCfg = Debug|x64
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|x64.Build.0 = Debug|x64
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|ARM.ActiveCfg = Release|ARM
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|ARM.Build.0 = Release|ARM
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|Win32.ActiveCfg = Release|Win32
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|Win32.Build.0 = Release|Win32
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|x64.ActiveCfg = Release|x64
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|x64.Build.0 = Release|x64
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Tests|ARM.ActiveCfg = Release|ARM
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Tests|ARM.Build.0 = Release|ARM
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Tests|Win32.ActiveCfg = Release|Win32
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Tests|Win32.Build.0 = Release|Win32
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Tests|x64.ActiveCfg = Release|x64
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Tests|x64.Build.0 = Release|x64
{DDF90203-0AAE-4F38-B589-2E9637658CE6}.Debug|ARM.ActiveCfg = Debug|ARM
{DDF90203-0AAE-4F38-B589-2E9637658CE6}.Debug|ARM.Build.0 = Debug|ARM
{DDF90203-0AAE-4F38-B589-2E9637658CE6}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -490,6 +445,51 @@ Global
{DDF90203-0AAE-4F38-B589-2E9637658CE6}.Tests|Win32.Build.0 = Release|Win32
{DDF90203-0AAE-4F38-B589-2E9637658CE6}.Tests|x64.ActiveCfg = Release|x64
{DDF90203-0AAE-4F38-B589-2E9637658CE6}.Tests|x64.Build.0 = Release|x64
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|ARM.ActiveCfg = Debug|ARM
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|ARM.Build.0 = Debug|ARM
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|ARM.Deploy.0 = Debug|ARM
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|Win32.ActiveCfg = Debug|Win32
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|Win32.Build.0 = Debug|Win32
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|Win32.Deploy.0 = Debug|Win32
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|x64.ActiveCfg = Debug|x64
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|x64.Build.0 = Debug|x64
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Debug|x64.Deploy.0 = Debug|x64
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|ARM.ActiveCfg = Release|ARM
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|ARM.Build.0 = Release|ARM
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|ARM.Deploy.0 = Release|ARM
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|Win32.ActiveCfg = Release|Win32
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|Win32.Build.0 = Release|Win32
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|Win32.Deploy.0 = Release|Win32
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|x64.ActiveCfg = Release|x64
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|x64.Build.0 = Release|x64
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Release|x64.Deploy.0 = Release|x64
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Tests|ARM.ActiveCfg = Release|ARM
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Tests|ARM.Build.0 = Release|ARM
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Tests|ARM.Deploy.0 = Release|ARM
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Tests|Win32.ActiveCfg = Release|Win32
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Tests|Win32.Build.0 = Release|Win32
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Tests|Win32.Deploy.0 = Release|Win32
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Tests|x64.ActiveCfg = Release|x64
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Tests|x64.Build.0 = Release|x64
{01D7D581-09A3-4A26-94BD-A7C529B29329}.Tests|x64.Deploy.0 = Release|x64
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|ARM.ActiveCfg = Debug|ARM
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|ARM.Build.0 = Debug|ARM
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|Win32.ActiveCfg = Debug|Win32
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|Win32.Build.0 = Debug|Win32
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|x64.ActiveCfg = Debug|x64
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Debug|x64.Build.0 = Debug|x64
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|ARM.ActiveCfg = Release|ARM
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|ARM.Build.0 = Release|ARM
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|Win32.ActiveCfg = Release|Win32
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|Win32.Build.0 = Release|Win32
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|x64.ActiveCfg = Release|x64
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Release|x64.Build.0 = Release|x64
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Tests|ARM.ActiveCfg = Release|ARM
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Tests|ARM.Build.0 = Release|ARM
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Tests|Win32.ActiveCfg = Release|Win32
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Tests|Win32.Build.0 = Release|Win32
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Tests|x64.ActiveCfg = Release|x64
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC}.Tests|x64.Build.0 = Release|x64
{2B2D16BD-1D37-46AF-A3F8-552900951B26}.Debug|ARM.ActiveCfg = Debug|ARM
{2B2D16BD-1D37-46AF-A3F8-552900951B26}.Debug|ARM.Build.0 = Debug|ARM
{2B2D16BD-1D37-46AF-A3F8-552900951B26}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -513,15 +513,15 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{0D070030-BEB5-4F48-99A0-B1777297A468} = {13ED48E6-7BC8-474F-8A8D-195B57921353}
{ACB316CA-3ECB-48E5-BE0A-91E72D5B0F12} = {13ED48E6-7BC8-474F-8A8D-195B57921353}
{40B76674-02DE-40EF-889B-FAD1489685E7} = {13ED48E6-7BC8-474F-8A8D-195B57921353}
{5D271429-C288-4534-98AF-94475D940058} = {13ED48E6-7BC8-474F-8A8D-195B57921353}
{935028AF-B850-4AD7-A00E-7BA84FB97D05} = {13ED48E6-7BC8-474F-8A8D-195B57921353}
{5FAC15BD-7397-4512-99D5-66CDC03AF5B7} = {13ED48E6-7BC8-474F-8A8D-195B57921353}
{2F911C05-B341-4291-8BF5-09EDECBDD5F5} = {13ED48E6-7BC8-474F-8A8D-195B57921353}
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC} = {13ED48E6-7BC8-474F-8A8D-195B57921353}
{DDF90203-0AAE-4F38-B589-2E9637658CE6} = {13ED48E6-7BC8-474F-8A8D-195B57921353}
{01D7D581-09A3-4A26-94BD-A7C529B29329} = {13ED48E6-7BC8-474F-8A8D-195B57921353}
{D326891E-ECE4-4B94-B5E7-8AA0A8E8ECBC} = {13ED48E6-7BC8-474F-8A8D-195B57921353}
{2B2D16BD-1D37-46AF-A3F8-552900951B26} = {13ED48E6-7BC8-474F-8A8D-195B57921353}
EndGlobalSection
EndGlobal