XR_ANDROID_light_estimation_cubemap
Name String
XR_ANDROID_light_estimation_cubemap
Uzantı Türü
Örnek uzantısı
Kayıtlı Uzantı Numarası
722
Düzeltme
1
Onay Durumu
Onaylanmadı
Uzantı ve Sürüm Bağımlılıkları
XR_ANDROID_light_estimation
Son Değiştirilme Tarihi
2025-08-06
IP Durumu
Bilinen IP hak talebi yok.
Katkıda bulunanlar
Salar Khan, Google
Scott Chung, Google
Jared Finder, Google
Spencer Quin, Google
Levana Chen, Google
Nihav Jain, Google
Jürgen Sturm, Google
Genel Bakış
Bu uzantı, temel XR_ANDROID_light_estimation uzantısı üzerine kurulmuştur. Küresel harita ışık tahminleri alma desteği eklenir. Bu sayede, fiziksel ortamdaki ışıklandırma hakkında daha ayrıntılı tahminler sağlanır.
Not
Işık tahmini verilerini alma mekanizması, temel uzantıyla aynıdır. Ancak ışık tahmin edici tutamacı oluşturulurken XrCubemapLightEstimatorCreateInfoANDROID, XrLightEstimatorCreateInfoANDROID'e zincirlenmelidir.
Sistem kapasitesini inceleme
typedef struct XrSystemCubemapLightEstimationPropertiesANDROID {
XrStructureType type;
void* next;
XrBool32 supportsCubemapLightEstimation;
} XrSystemCubemapLightEstimationPropertiesANDROID;
Üye Açıklamaları
type, bu yapının XrStructureType'ıdır.next,NULLveya bir yapı zincirindeki sonraki yapının işaretçisidir. Temel OpenXR'de veya bu uzantıda bu tür yapılar tanımlanmamıştır.supportsCubemapLightEstimation, geçerli sistemin küp haritası ışık tahminini destekleyip desteklemediğini belirten birXrBool32değeridir.
Bir uygulama, xrGetSystemProperties çağrılırken XrSystemProperties'i XrSystemCubemapLightEstimationPropertiesANDROID yapısıyla genişleterek sistemin küp haritası ışık tahmini özelliğini destekleyip desteklemediğini kontrol edebilir .
Çalışma zamanı, XR_FALSE için supportsCubemapLightEstimation değerini döndürürse ve XrCubemapLightEstimatorCreateInfoANDROID, XrLightEstimatorCreateInfoANDROID ile zincirlenmişse çalışma zamanı, xrCreateLightEstimatorANDROID işlevinden XR_ERROR_FEATURE_UNSUPPORTED değerini döndürmelidir .
Geçerli Kullanım (Dolaylı)
-
XR_ANDROID_light_estimation_cubemapuzantısı, XrSystemCubemapLightEstimationPropertiesANDROID kullanılmadan önce etkinleştirilmelidir. -
typeXR_TYPE_SYSTEM_CUBEMAP_LIGHT_ESTIMATION_PROPERTIES_ANDROIDolmalıdır. -
nextmust beNULLor a valid pointer to the next structure in a structure chain
Desteklenen küp haritası çözünürlüklerini alma
XrResult xrEnumerateCubemapLightingResolutionsANDROID(
XrInstance instance,
XrSystemId systemId,
uint32_t resolutionCapacityInput,
uint32_t* resolutionCountOutput,
uint32_t* resolutions);
Parametre Açıklamaları
instance, daha önce oluşturulmuş bir XrInstance'tır.systemId, desteklenen kübik harita çözünürlüklerinin alınacağı, xrGetSystem tarafından daha önce alınanXrSystemIddeğeridir.resolutionCapacityInput,resolutionsdizisinde depolanabilecek maksimum öğe sayısını gösteren biruint32_t'dir.resolutionCountOutput, çalışma zamanı tarafındanresolutionsdizisine yazılan öğelerin sayısını belirten, çalışma zamanı tarafından ayarlanan biruint32_tişaretçisidir.resolutions, desteklenen kübik harita çözünürlükleriyle çalışma zamanında doldurulan biruint32_tdizisidir.
Bir küp haritası çözünürlüğü, küp haritasının her yüzünün piksel cinsinden genişliğini ve yüksekliğini gösterir. 2 çağrılı deyim Uygulama, ışık tahmin edici tutamacını oluştururken XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution içinde desteklenen çözünürlüklerden birini kullanmayı seçebilir. Uygulama, seçilen çözünürlüğe ve renk biçimine göre XrCubemapLightingDataANDROID öğesinin görüntü arabelleği üyeleri için uygun miktarda bellek ayırmalıdır.
Geçerli Kullanım (Dolaylı)
- xrEnumerateCubemapLightingResolutionsANDROID çağrılmadan önce
XR_ANDROID_light_estimation_cubemapuzantısı etkinleştirilmelidir. -
instancegeçerli bir XrInstance işleyeni olmalıdır. -
resolutionCountOutput,uint32_tdeğerine yönelik bir işaretçi olmalıdır. -
resolutionCapacityInputdeğeri0değilseresolutions,resolutionCapacityInputuint32_tdeğerlerinden oluşan bir dizinin işaretçisi olmalıdır.
Dönüş Kodları
XR_SUCCESS
XR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_RUNTIME_FAILUREXR_ERROR_SIZE_INSUFFICIENTXR_ERROR_SYSTEM_INVALIDXR_ERROR_VALIDATION_FAILURE
Desteklenen küp haritası renk biçimlerini alma
XrCubemapLightingColorFormatANDROID numaralandırması, küp haritası aydınlatmasının kullanılacak renk biçimini çalışma zamanına bildirir.
typedef enum XrCubemapLightingColorFormatANDROID {
XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32_SFLOAT_ANDROID = 1,
XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32A32_SFLOAT_ANDROID = 2,
XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R16G16B16A16_SFLOAT_ANDROID = 3,
XR_CUBEMAP_LIGHTING_COLOR_FORMAT_MAX_ENUM_ANDROID = 0x7FFFFFFF
} XrCubemapLightingColorFormatANDROID;
Numaralandırılmış değerler aşağıdaki anlamlara gelir:
Enum Açıklaması
XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32_SFLOAT_ANDROID
Her kanalın 32 bit kayan nokta değeri olduğu 3 kanallı bir renk biçimi.
XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32A32_SFLOAT_ANDROID
Her kanalın 32 bit kayan nokta değeri olduğu 4 kanallı bir renk biçimi.
XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R16G16B16A16_SFLOAT_ANDROID
Her kanalın 16 bit kayan nokta değeri olduğu 4 kanallı bir renk biçimi.
XrResult xrEnumerateCubemapLightingColorFormatsANDROID(
XrInstance instance,
XrSystemId systemId,
uint32_t colorFormatCapacityInput,
uint32_t* colorFormatCountOutput,
XrCubemapLightingColorFormatANDROID* colorFormats);
Parametre Açıklamaları
instance, daha önce oluşturulmuş bir XrInstance'tır.systemId, desteklenen kübik harita çözünürlüklerinin alınacağı, xrGetSystem tarafından daha önce alınanXrSystemIddeğeridir.colorFormatCapacityInput,colorFormatsdizisinde depolanabilecek maksimum öğe sayısını gösteren biruint32_t'dir.colorFormatCountOutput, çalışma zamanı tarafındancolorFormatsdizisine yazılan öğelerin sayısını belirten, çalışma zamanı tarafından ayarlanan biruint32_tişaretçisidir.colorFormats, desteklenen küp haritası renk biçimleriyle çalışma zamanında doldurulan bir XrCubemapLightingColorFormatANDROID dizisidir.
2 çağrılı deyim: Uygulama, ışık tahmin edici tutamacını oluştururken XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat içinde desteklenen renk biçimlerinden birini kullanmayı seçebilir. Uygulama, seçilen renk biçimine göre XrCubemapLightingDataANDROID'in görüntü arabelleği üyeleri için uygun miktarda bellek ayırmalıdır.
Geçerli Kullanım (Dolaylı)
- xrEnumerateCubemapLightingColorFormatsANDROID çağrılmadan önce
XR_ANDROID_light_estimation_cubemapuzantısı etkinleştirilmelidir. -
instancegeçerli bir XrInstance işleyeni olmalıdır. -
colorFormatCountOutput,uint32_tdeğerine yönelik bir işaretçi olmalıdır. -
colorFormatCapacityInput,0değilsecolorFormats,colorFormatCapacityInputXrCubemapLightingColorFormatANDROID değerlerinden oluşan bir dizinin işaretçisi olmalıdır.
Dönüş Kodları
XR_SUCCESS
XR_ERROR_FUNCTION_UNSUPPORTEDXR_ERROR_HANDLE_INVALIDXR_ERROR_INSTANCE_LOSTXR_ERROR_RUNTIME_FAILUREXR_ERROR_SIZE_INSUFFICIENTXR_ERROR_SYSTEM_INVALIDXR_ERROR_VALIDATION_FAILURE
Küresel harita ışık tahmin aracı oluşturma
typedef struct XrCubemapLightEstimatorCreateInfoANDROID {
XrStructureType type;
const void* next;
uint32_t cubemapResolution;
XrCubemapLightingColorFormatANDROID colorFormat;
XrBool32 reproject;
} XrCubemapLightEstimatorCreateInfoANDROID;
Üye Açıklamaları
type, bu yapının XrStructureType'ıdır.next,NULLveya bir yapı zincirindeki sonraki yapının işaretçisidir.cubemapResolution, kullanılacak kübik harita aydınlatmasının çözünürlüğünü gösteren biruint32_t'dir.colorFormat, kullanılacak küp haritası ışıklandırma verilerinin renk biçimini belirten bir XrCubemapLightingColorFormatANDROID değeridir.reproject, küp haritası ışıklandırmasının uygulama taban alanına yeniden yansıtılıp yansıtılmayacağını gösteren birXrBool32değeridir.
XrCubemapLightEstimatorCreateInfoANDROID yapısı, küp haritası aydınlatma tahminleri sağlayabilecek bir XrLightEstimatorANDROID tutacı oluşturmak için gereken bilgileri açıklar. XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution üyesi, xrEnumerateCubemapLightingResolutionsANDROID tarafından döndürülen çözünürlüklerden birine ayarlanmalıdır . XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat üyesi, xrEnumerateCubemapLightingColorFormatsANDROID tarafından döndürülen renk biçimlerinden birine ayarlanmalıdır . Uygulama, çözünürlüğü desteklenen çözünürlüklerden birine veya renk biçimini desteklenen renk biçimlerinden birine ayarlamazsa çalışma zamanı, xrCreateLightEstimatorANDROID işlevinden XR_ERROR_FEATURE_UNSUPPORTED değerini döndürmelidir.
Geçerli Kullanım (Dolaylı)
- XrCubemapLightEstimatorCreateInfoANDROID kullanılmadan önce
XR_ANDROID_light_estimation_cubemapuzantısı etkinleştirilmelidir. -
typeXR_TYPE_CUBEMAP_LIGHT_ESTIMATOR_CREATE_INFO_ANDROIDolmalıdır. -
nextmust beNULLor a valid pointer to the next structure in a structure chain -
colorFormatgeçerli bir XrCubemapLightingColorFormatANDROID değeri olmalıdır.
Cubemap ışık tahminleri
typedef struct XrCubemapLightingDataANDROID {
XrStructureType type;
void* next;
XrLightEstimateStateANDROID state;
uint32_t imageBufferSize;
uint8_t* imageBufferRight;
uint8_t* imageBufferLeft;
uint8_t* imageBufferTop;
uint8_t* imageBufferBottom;
uint8_t* imageBufferFront;
uint8_t* imageBufferBack;
XrQuaternionf rotation;
XrTime centerExposureTime;
} XrCubemapLightingDataANDROID;
Üye Açıklamaları
type, bu yapının XrStructureType'ıdır.next,NULLveya bir yapı zincirindeki sonraki yapının işaretçisidir. Geçerli yapılar XrAmbientLightANDROID, XrSphericalHarmonicsANDROID ve XrDirectionalLightANDROID'dir .state, ışık tahmini durumunu temsil eden XrLightEstimateStateANDROID değeridir.imageBufferSize, küp haritasındaki her yüz görüntüsü arabelleğinin bayt boyutunu gösteren biruint32_t'dir.imageBufferRight, küp haritasının sağ yüz görüntüsünü içeren biruint8_tarabelleğidir.imageBufferLeft, küp haritasının sol yüz görüntüsünü içeren biruint8_tarabelleğidir.imageBufferTop, küp haritasının üst yüz görüntüsünü içeren biruint8_tarabelleğidir.imageBufferBottom, küp haritasının alt yüz görüntüsünü içeren biruint8_tarabelleğidir.imageBufferFront, küp haritasının ön yüz görüntüsünü içeren biruint8_tarabelleğidir.imageBufferBack, küp haritasının arka yüz görüntüsünü içeren biruint8_tarabelleğidir.rotation, küp haritasının döndürülmesini gösteren bir XrQuaternionf değeridir.centerExposureTime, küp haritasının çekildiği zamanı gösteren birXrTime'dir.
Bu yapı, XrLightEstimateANDROID ile zincirlenebilir. Çalışma zamanı, bu yapıyı yalnızca ışık tahmin edici tutma yeri oluşturmak için XrCubemapLightEstimatorCreateInfoANDROID kullanıldıysa xrGetLightEstimateANDROID içinde doldurmalıdır. Uygulama, ışık tahmin edici tutacını oluştururken XrCubemapLightEstimatorCreateInfoANDROID :: cubemapResolution ve XrCubemapLightEstimatorCreateInfoANDROID :: colorFormat içinde ayarlanan değerlere bağlı olarak görüntü arabellekleri için uygun miktarda bellek ayırmalıdır. Uygulama, XrCubemapLightingDataANDROID :: imageBufferSize değerini her yüz resmi arabelleğinin kapasitesine (bayt cinsinden) ayarlamalıdır. Uygulama küp haritası ışık tahmini kullanmıyorsa veya XrCubemapLightingDataANDROID :: imageBufferSize, çalışma zamanının görüntü arabelleklerini doldurması için yeterince büyük değilse çalışma zamanı XrCubemapLightingDataANDROID :: state değerini XR_LIGHT_ESTIMATE_STATE_INVALID_ANDROID olarak ayarlamalıdır .
Uygulama, ışık tahmin edici tutamacını oluştururken XrCubemapLightEstimatorCreateInfoANDROID :: reproject değerini XR_TRUE olarak ayarlarsa çalışma zamanı XrCubemapLightingDataANDROID :: rotation değerini kimlik rotasyonu olarak ayarlamalı ve dahili olarak döndürülmüş küp haritanın, uygulama taban alanındaki bir kimlik küp haritasının yüzlerine yeniden yansıtılmasını sağlamalıdır.
Işıklandırma küp haritasının düzeni, aşağıdaki resimde gösterildiği gibi OpenGL küp haritası düzeniyle aynıdır.
Şekil 24. Cubemap düzeni.
Geçerli Kullanım (Dolaylı)
- XrCubemapLightingDataANDROID kullanılmadan önce
XR_ANDROID_light_estimation_cubemapuzantısı etkinleştirilmelidir. -
typeXR_TYPE_CUBEMAP_LIGHTING_DATA_ANDROIDolmalıdır. -
nextmust beNULLor a valid pointer to the next structure in a structure chain -
stategeçerli bir XrLightEstimateStateANDROID değeri olmalıdır. -
imageBufferRightmust be a pointer to an array ofimageBufferSizeuint8_tvalues -
imageBufferLeftmust be a pointer to an array ofimageBufferSizeuint8_tvalues -
imageBufferTopmust be a pointer to an array ofimageBufferSizeuint8_tvalues -
imageBufferBottommust be a pointer to an array ofimageBufferSizeuint8_tvalues -
imageBufferFrontmust be a pointer to an array ofimageBufferSizeuint8_tvalues -
imageBufferBackmust be a pointer to an array ofimageBufferSizeuint8_tvalues -
imageBufferSizeparametresi0değerinden büyük olmalıdır.
Işık tahmini için örnek kod
Aşağıdaki örnek kod, çalışma zamanında olası tüm ışık tahmini miktarlarının nasıl alınacağını gösterir.
XrSession session; // Created at app startup
XrInstance instance; // Created at app startup
XrSpace appSpace; // Created previously.
XrSystemId systemId; // Retrieved previously by xrGetSystem
PFN_xrCreateLightEstimatorANDROID xrCreateLightEstimatorANDROID; // Created previously.
PFN_xrDestroyLightEstimatorANDROID xrDestroyLightEstimatorANDROID; // Created previously.
PFN_xrGetLightEstimateANDROID xrGetLightEstimateANDROID; // Created previously.
PFN_xrEnumerateCubemapLightingResolutionsANDROID xrEnumerateCubemapLightingResolutionsANDROID; // Created previously.
PFN_xrEnumerateCubemapLightingColorFormatsANDROID xrEnumerateCubemapLightingColorFormatsANDROID; // Created previously.
XrSystemCubemapLightEstimationPropertiesANDROID props = {
.type = XR_TYPE_SYSTEM_CUBEMAP_LIGHT_ESTIMATION_PROPERTIES_ANDROID};
XrSystemProperties base = {.type = XR_TYPE_SYSTEM_PROPERTIES,
.next = &props};
CHK_XR(xrGetSystemProperties(instance, systemId, &base));
if (!props.supportsCubemapLightEstimation) {
// Cubemap light estimation is not supported
}
uint32_t cubemapResolution = 0;
std::vector<uint32_t> supportedCubemapResolutions;
uint32_t resolutionCount;
CHK_XR(xrEnumerateCubemapLightingResolutionsANDROID(
instance, systemId, 0, &resolutionCount, nullptr));
supportedCubemapResolutions.resize(resolutionCount);
if (resolutionCount == 0) {
// No cubemap lighting supported
} else {
CHK_XR(xrEnumerateCubemapLightingResolutionsANDROID(
instance, systemId, 0, &resolutionCount, supportedCubemapResolutions.data()));
cubemapResolution = supportedCubemapResolutions[0];
}
uint32_t pixelCount = cubemapResolution * cubemapResolution;
XrCubemapLightingColorFormatANDROID colorFormat;
std::vector<XrCubemapLightingColorFormatANDROID> supportedColorFormats;
uint32_t colorFormatCount;
CHK_XR(xrEnumerateCubemapLightingColorFormatsANDROID(
instance, systemId, 0, &colorFormatCount, nullptr));
supportedColorFormats.resize(colorFormatCount);
if (colorFormatCount == 0) {
// No supported color formats for cubemap lighting. Cannot use cubemap
// light estimation.
} else {
CHK_XR(xrEnumerateCubemapLightingColorFormatsANDROID(
instance, systemId, 0, &colorFormatCount, supportedColorFormats.data()));
colorFormat = supportedColorFormats[0];
}
uint32_t pixelSize = 0;
switch (colorFormat) {
case XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32_SFLOAT_ANDROID:
pixelSize = 3 * sizeof(float);
break;
case XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R32G32B32A32_SFLOAT_ANDROID:
pixelSize = 4 * sizeof(float);
break;
case XR_CUBEMAP_LIGHTING_COLOR_FORMAT_R16G16B16A16_SFLOAT_ANDROID:
pixelSize = 4 * sizeof(uint16_t);
break;
default:
// Should not happen since the color format was validated previously.
break;
}
uint32_t perFaceImageBufferSize = pixelCount * pixelSize;
XrLightEstimatorANDROID estimator;
XrCubemapLightEstimatorCreateInfoANDROID cubemapCreateInfo = {
.type = XR_TYPE_CUBEMAP_LIGHT_ESTIMATOR_CREATE_INFO_ANDROID,
.cubemapResolution = cubemapResolution,
.colorFormat = colorFormat,
.reproject = XR_TRUE
};
XrLightEstimatorCreateInfoANDROID basicCreateInfo = {
.type = XR_TYPE_LIGHT_ESTIMATOR_CREATE_INFO_ANDROID,
.next = &cubemapCreateInfo};
CHK_XR(xrCreateLightEstimatorANDROID(session, &basicCreateInfo, &estimator));
std::vector<uint8_t> cubemapBuffer(perFaceImageBufferSize * 6); // 6 faces * perFaceImageBufferSize
// Every frame
XrTime updateTime; // Time used for the current frame's simulation update.
XrLightEstimateGetInfoANDROID info = {
.type = XR_TYPE_LIGHT_ESTIMATE_GET_INFO_ANDROID,
.space = appSpace,
.time = updateTime,
};
XrCubemapLightingDataANDROID cubemap = {
.type = XR_TYPE_CUBEMAP_LIGHTING_DATA_ANDROID,
.next = nullptr,
.imageBufferSize = perFaceImageBufferSize,
.imageBufferRight = cubemapBuffer.data() + 0 * perFaceImageBufferSize,
.imageBufferLeft = cubemapBuffer.data() + 1 * perFaceImageBufferSize,
.imageBufferTop = cubemapBuffer.data() + 2 * perFaceImageBufferSize,
.imageBufferBottom = cubemapBuffer.data() + 3 * perFaceImageBufferSize,
.imageBufferFront = cubemapBuffer.data() + 4 * perFaceImageBufferSize,
.imageBufferBack = cubemapBuffer.data() + 5 * perFaceImageBufferSize,
};
XrDirectionalLightANDROID directionalLight = {
.type = XR_TYPE_DIRECTIONAL_LIGHT_ANDROID,
.next = &cubemap,
};
XrSphericalHarmonicsANDROID totalSh = {
.type = XR_TYPE_SPHERICAL_HARMONICS_ANDROID,
.next = &directionalLight,
.kind = XR_SPHERICAL_HARMONICS_KIND_TOTAL_ANDROID,
};
XrSphericalHarmonicsANDROID ambientSh = {
.type = XR_TYPE_SPHERICAL_HARMONICS_ANDROID,
.next = &totalSh,
.kind = XR_SPHERICAL_HARMONICS_KIND_AMBIENT_ANDROID,
};
XrAmbientLightANDROID ambientLight = {
.type = XR_TYPE_AMBIENT_LIGHT_ANDROID,
.next = &ambientSh,
};
XrLightEstimateANDROID estimate = {
.type = XR_TYPE_LIGHT_ESTIMATE_ANDROID,
.next = &ambientLight,
};
XrResult result = xrGetLightEstimateANDROID(estimator, &info, &estimate);
if (result == XR_SUCCESS &&
estimate.state == XR_LIGHT_ESTIMATE_STATE_VALID_ANDROID) {
// use cubemap, directionalLight, totalSh, ambientSh, and
// ambientLight if each struct has a valid state field
if (cubemap.state == XR_LIGHT_ESTIMATE_STATE_VALID_ANDROID) {
// use cubemap
if (cubemapCreateInfo.reproject == XR_TRUE) {
XrQuaternionf identityQuaternion = {0.0f, 0.0f, 0.0f, 1.0f};
assert(memcmp(&cubemap.rotation, &identityQuaternion, sizeof(XrQuaternionf)) == 0);
}
}
}
// When you want to disable light estimation
CHK_XR(xrDestroyLightEstimatorANDROID(estimator));
Yeni Komutlar
Yeni Yapılar
XrLightEstimateANDROID uzatma :
XrLightEstimatorCreateInfoANDROID'i genişletme :
XrSystemProperties'i genişletme :
Yeni Sıralamalar
Yeni Numaralandırılmış Değer Sabitleri
XR_ANDROID_LIGHT_ESTIMATION_CUBEMAP_EXTENSION_NAMEXR_ANDROID_light_estimation_cubemap_SPEC_VERSIONXrStructureType'ı genişletme :
XR_TYPE_CUBEMAP_LIGHTING_DATA_ANDROIDXR_TYPE_CUBEMAP_LIGHT_ESTIMATOR_CREATE_INFO_ANDROIDXR_TYPE_SYSTEM_CUBEMAP_LIGHT_ESTIMATION_PROPERTIES_ANDROID
Sorunlar
Sürüm Geçmişi
Düzeltme 1, 2025-12-05 (Salar Khan)
- İlk uzantı açıklaması