Merge pull request #67775 from dsnopek/opengl-multiview-openxr
Add support for OpenGL to OpenXR
This commit is contained in:
commit
6bb2ea281e
|
@ -1725,9 +1725,17 @@
|
|||
</constant>
|
||||
<constant name="WINDOW_VIEW" value="2" enum="HandleType">
|
||||
Window view:
|
||||
- Windows: [code]HDC[/code] for the window (only with the GL Compatibility renderer).
|
||||
- macOS: [code]NSView*[/code] for the window main view.
|
||||
- iOS: [code]UIView*[/code] for the window main view.
|
||||
</constant>
|
||||
<constant name="OPENGL_CONTEXT" value="3" enum="HandleType">
|
||||
OpenGL context (only with the GL Compatibility renderer):
|
||||
- Windows: [code]HGLRC[/code] for the window.
|
||||
- Linux: [code]GLXContext*[/code] for the window.
|
||||
- MacOS: [code]NSOpenGLContext*[/code] for the window.
|
||||
- Android: [code]EGLContext[/code] for the window.
|
||||
</constant>
|
||||
<constant name="TTS_UTTERANCE_STARTED" value="0" enum="TTSUtteranceEvent">
|
||||
Utterance has begun to be spoken.
|
||||
</constant>
|
||||
|
|
|
@ -1642,6 +1642,9 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
|
|||
ERR_FAIL_COND(rb.is_null());
|
||||
}
|
||||
|
||||
GLES3::RenderTarget *rt = texture_storage->get_render_target(rb->render_target);
|
||||
ERR_FAIL_COND(!rt);
|
||||
|
||||
// Assign render data
|
||||
// Use the format from rendererRD
|
||||
RenderDataGLES3 render_data;
|
||||
|
@ -1729,8 +1732,20 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
|
|||
|
||||
scene_state.ubo.emissive_exposure_normalization = -1.0; // Use default exposure normalization.
|
||||
|
||||
bool flip_y = !render_data.reflection_probe.is_valid();
|
||||
|
||||
if (rt->overridden.color.is_valid()) {
|
||||
// If we've overridden the render target's color texture, then don't render upside down.
|
||||
// We're probably rendering directly to an XR device.
|
||||
flip_y = false;
|
||||
}
|
||||
if (!flip_y) {
|
||||
// If we're rendering right-side up, then we need to change the winding order.
|
||||
glFrontFace(GL_CW);
|
||||
}
|
||||
|
||||
_setup_lights(&render_data, false, render_data.directional_light_count, render_data.omni_light_count, render_data.spot_light_count);
|
||||
_setup_environment(&render_data, render_data.reflection_probe.is_valid(), screen_size, !render_data.reflection_probe.is_valid(), clear_color, false);
|
||||
_setup_environment(&render_data, render_data.reflection_probe.is_valid(), screen_size, flip_y, clear_color, false);
|
||||
|
||||
_fill_render_list(RENDER_LIST_OPAQUE, &render_data, PASS_MODE_COLOR);
|
||||
render_list[RENDER_LIST_OPAQUE].sort_by_key();
|
||||
|
@ -1811,7 +1826,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
|
|||
}
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, rb->framebuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
|
||||
glViewport(0, 0, rb->width, rb->height);
|
||||
|
||||
// Do depth prepass if it's explicitly enabled
|
||||
|
@ -1917,6 +1932,11 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
|
|||
|
||||
_render_list_template<PASS_MODE_COLOR_TRANSPARENT>(&render_list_params_alpha, &render_data, 0, render_list[RENDER_LIST_ALPHA].elements.size(), true);
|
||||
|
||||
if (!flip_y) {
|
||||
// Restore the default winding order.
|
||||
glFrontFace(GL_CCW);
|
||||
}
|
||||
|
||||
if (rb.is_valid()) {
|
||||
_render_buffers_debug_draw(rb, p_shadow_atlas, p_occluder_debug_tex);
|
||||
}
|
||||
|
|
|
@ -33,17 +33,12 @@
|
|||
#include "render_scene_buffers_gles3.h"
|
||||
#include "texture_storage.h"
|
||||
|
||||
#ifdef ANDROID_ENABLED
|
||||
#define glFramebufferTextureMultiviewOVR GLES3::Config::get_singleton()->eglFramebufferTextureMultiviewOVR
|
||||
#endif
|
||||
|
||||
RenderSceneBuffersGLES3::~RenderSceneBuffersGLES3() {
|
||||
free_render_buffer_data();
|
||||
}
|
||||
|
||||
void RenderSceneBuffersGLES3::configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) {
|
||||
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
|
||||
GLES3::Config *config = GLES3::Config::get_singleton();
|
||||
|
||||
//internal_size.x = p_internal_size.x; // ignore for now
|
||||
//internal_size.y = p_internal_size.y;
|
||||
|
@ -62,66 +57,9 @@ void RenderSceneBuffersGLES3::configure(RID p_render_target, const Size2i p_inte
|
|||
GLES3::RenderTarget *rt = texture_storage->get_render_target(p_render_target);
|
||||
|
||||
is_transparent = rt->is_transparent;
|
||||
|
||||
// framebuffer
|
||||
glGenFramebuffers(1, &framebuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
|
||||
if (view_count > 1 && config->multiview_supported) {
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, rt->color);
|
||||
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, rt->color, 0, 0, view_count);
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, rt->color);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0);
|
||||
}
|
||||
|
||||
glGenTextures(1, &depth_texture);
|
||||
if (view_count > 1 && config->multiview_supported) {
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, depth_texture);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, view_count, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, depth_texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
if (view_count > 1 && config->multiview_supported) {
|
||||
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depth_texture, 0, 0, view_count);
|
||||
} else {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_texture, 0);
|
||||
}
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, texture_storage->system_fbo);
|
||||
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
free_render_buffer_data();
|
||||
WARN_PRINT("Could not create 3D renderbuffer, status: " + texture_storage->get_framebuffer_error(status));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderSceneBuffersGLES3::free_render_buffer_data() {
|
||||
if (depth_texture) {
|
||||
glDeleteTextures(1, &depth_texture);
|
||||
depth_texture = 0;
|
||||
}
|
||||
if (framebuffer) {
|
||||
glDeleteFramebuffers(1, &framebuffer);
|
||||
framebuffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
|
|
@ -61,9 +61,6 @@ public:
|
|||
bool is_transparent = false;
|
||||
|
||||
RID render_target;
|
||||
GLuint internal_texture = 0; // Used for rendering when post effects are enabled
|
||||
GLuint depth_texture = 0; // Main depth texture
|
||||
GLuint framebuffer = 0; // Main framebuffer, contains internal_texture and depth_texture or render_target->color and depth_texture
|
||||
|
||||
//built-in textures used for ping pong image processing and blurring
|
||||
struct Blur {
|
||||
|
|
|
@ -614,7 +614,9 @@ void TextureStorage::texture_free(RID p_texture) {
|
|||
}
|
||||
|
||||
if (t->tex_id != 0) {
|
||||
glDeleteTextures(1, &t->tex_id);
|
||||
if (!t->is_external) {
|
||||
glDeleteTextures(1, &t->tex_id);
|
||||
}
|
||||
t->tex_id = 0;
|
||||
}
|
||||
|
||||
|
@ -680,6 +682,35 @@ void TextureStorage::texture_proxy_initialize(RID p_texture, RID p_base) {
|
|||
texture_owner.initialize_rid(p_texture, proxy_tex);
|
||||
}
|
||||
|
||||
RID TextureStorage::texture_create_external(Texture::Type p_type, Image::Format p_format, unsigned int p_image, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type) {
|
||||
Texture texture;
|
||||
texture.active = true;
|
||||
texture.is_external = true;
|
||||
texture.type = p_type;
|
||||
|
||||
switch (p_type) {
|
||||
case Texture::TYPE_2D: {
|
||||
texture.target = GL_TEXTURE_2D;
|
||||
} break;
|
||||
case Texture::TYPE_3D: {
|
||||
texture.target = GL_TEXTURE_3D;
|
||||
} break;
|
||||
case Texture::TYPE_LAYERED: {
|
||||
texture.target = GL_TEXTURE_2D_ARRAY;
|
||||
} break;
|
||||
}
|
||||
|
||||
texture.real_format = texture.format = p_format;
|
||||
texture.tex_id = p_image;
|
||||
texture.alloc_width = texture.width = p_width;
|
||||
texture.alloc_height = texture.height = p_height;
|
||||
texture.depth = p_depth;
|
||||
texture.layers = p_layers;
|
||||
texture.layered_type = p_layered_type;
|
||||
|
||||
return texture_owner.make_rid(texture);
|
||||
}
|
||||
|
||||
void TextureStorage::texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer) {
|
||||
texture_set_data(p_texture, p_image, p_layer);
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
@ -1459,43 +1490,74 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
|
|||
glDepthMask(GL_FALSE);
|
||||
|
||||
{
|
||||
Texture *texture;
|
||||
bool use_multiview = rt->view_count > 1 && config->multiview_supported;
|
||||
GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
|
||||
|
||||
/* Front FBO */
|
||||
|
||||
Texture *texture = get_texture(rt->texture);
|
||||
ERR_FAIL_COND(!texture);
|
||||
|
||||
// framebuffer
|
||||
glGenFramebuffers(1, &rt->fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
|
||||
|
||||
// color
|
||||
glGenTextures(1, &rt->color);
|
||||
if (rt->view_count > 1 && config->multiview_supported) {
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, rt->color);
|
||||
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, rt->color_internal_format, rt->size.x, rt->size.y, rt->view_count, 0, rt->color_format, rt->color_type, nullptr);
|
||||
if (rt->overridden.color.is_valid()) {
|
||||
texture = get_texture(rt->overridden.color);
|
||||
ERR_FAIL_COND(!texture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
rt->color = texture->tex_id;
|
||||
rt->size = Size2i(texture->width, texture->height);
|
||||
} else {
|
||||
glBindTexture(GL_TEXTURE_2D, rt->color);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, rt->color_internal_format, rt->size.x, rt->size.y, 0, rt->color_format, rt->color_type, nullptr);
|
||||
texture = get_texture(rt->texture);
|
||||
ERR_FAIL_COND(!texture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glGenTextures(1, &rt->color);
|
||||
glBindTexture(texture_target, rt->color);
|
||||
|
||||
if (use_multiview) {
|
||||
glTexImage3D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, rt->view_count, 0, rt->color_format, rt->color_type, nullptr);
|
||||
} else {
|
||||
glTexImage2D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, 0, rt->color_format, rt->color_type, nullptr);
|
||||
}
|
||||
|
||||
glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
if (rt->view_count > 1 && config->multiview_supported) {
|
||||
if (use_multiview) {
|
||||
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, rt->color, 0, 0, rt->view_count);
|
||||
} else {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0);
|
||||
}
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
// depth
|
||||
if (rt->overridden.depth.is_valid()) {
|
||||
texture = get_texture(rt->overridden.depth);
|
||||
ERR_FAIL_COND(!texture);
|
||||
|
||||
rt->depth = texture->tex_id;
|
||||
} else {
|
||||
glGenTextures(1, &rt->depth);
|
||||
glBindTexture(texture_target, rt->depth);
|
||||
|
||||
if (use_multiview) {
|
||||
glTexImage3D(texture_target, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, rt->view_count, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
|
||||
} else {
|
||||
glTexImage2D(texture_target, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
|
||||
}
|
||||
|
||||
glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
if (use_multiview) {
|
||||
glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, rt->depth, 0, 0, rt->view_count);
|
||||
} else {
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
|
||||
}
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
glDeleteFramebuffers(1, &rt->fbo);
|
||||
glDeleteTextures(1, &rt->color);
|
||||
|
@ -1503,32 +1565,38 @@ void TextureStorage::_update_render_target(RenderTarget *rt) {
|
|||
rt->size.x = 0;
|
||||
rt->size.y = 0;
|
||||
rt->color = 0;
|
||||
texture->tex_id = 0;
|
||||
texture->active = false;
|
||||
rt->depth = 0;
|
||||
if (rt->overridden.color.is_null()) {
|
||||
texture->tex_id = 0;
|
||||
texture->active = false;
|
||||
}
|
||||
WARN_PRINT("Could not create render target, status: " + get_framebuffer_error(status));
|
||||
return;
|
||||
}
|
||||
|
||||
texture->format = rt->image_format;
|
||||
texture->real_format = rt->image_format;
|
||||
if (rt->view_count > 1 && config->multiview_supported) {
|
||||
texture->type = Texture::TYPE_LAYERED;
|
||||
texture->target = GL_TEXTURE_2D_ARRAY;
|
||||
texture->layers = rt->view_count;
|
||||
if (rt->overridden.color.is_valid()) {
|
||||
texture->is_render_target = true;
|
||||
} else {
|
||||
texture->type = Texture::TYPE_2D;
|
||||
texture->target = GL_TEXTURE_2D;
|
||||
texture->layers = 1;
|
||||
texture->format = rt->image_format;
|
||||
texture->real_format = rt->image_format;
|
||||
texture->target = texture_target;
|
||||
if (rt->view_count > 1 && config->multiview_supported) {
|
||||
texture->type = Texture::TYPE_LAYERED;
|
||||
texture->layers = rt->view_count;
|
||||
} else {
|
||||
texture->type = Texture::TYPE_2D;
|
||||
texture->layers = 1;
|
||||
}
|
||||
texture->gl_format_cache = rt->color_format;
|
||||
texture->gl_type_cache = GL_UNSIGNED_BYTE;
|
||||
texture->gl_internal_format_cache = rt->color_internal_format;
|
||||
texture->tex_id = rt->color;
|
||||
texture->width = rt->size.x;
|
||||
texture->alloc_width = rt->size.x;
|
||||
texture->height = rt->size.y;
|
||||
texture->alloc_height = rt->size.y;
|
||||
texture->active = true;
|
||||
}
|
||||
texture->gl_format_cache = rt->color_format;
|
||||
texture->gl_type_cache = GL_UNSIGNED_BYTE;
|
||||
texture->gl_internal_format_cache = rt->color_internal_format;
|
||||
texture->tex_id = rt->color;
|
||||
texture->width = rt->size.x;
|
||||
texture->alloc_width = rt->size.x;
|
||||
texture->height = rt->size.y;
|
||||
texture->alloc_height = rt->size.y;
|
||||
texture->active = true;
|
||||
}
|
||||
|
||||
glClearColor(0, 0, 0, 0);
|
||||
|
@ -1596,17 +1664,32 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
|
|||
|
||||
if (rt->fbo) {
|
||||
glDeleteFramebuffers(1, &rt->fbo);
|
||||
glDeleteTextures(1, &rt->color);
|
||||
rt->fbo = 0;
|
||||
}
|
||||
|
||||
if (rt->overridden.color.is_null()) {
|
||||
glDeleteTextures(1, &rt->color);
|
||||
rt->color = 0;
|
||||
}
|
||||
|
||||
Texture *tex = get_texture(rt->texture);
|
||||
tex->alloc_height = 0;
|
||||
tex->alloc_width = 0;
|
||||
tex->width = 0;
|
||||
tex->height = 0;
|
||||
tex->active = false;
|
||||
if (rt->overridden.depth.is_null()) {
|
||||
glDeleteTextures(1, &rt->depth);
|
||||
rt->depth = 0;
|
||||
}
|
||||
|
||||
if (rt->texture.is_valid()) {
|
||||
Texture *tex = get_texture(rt->texture);
|
||||
tex->alloc_height = 0;
|
||||
tex->alloc_width = 0;
|
||||
tex->width = 0;
|
||||
tex->height = 0;
|
||||
tex->active = false;
|
||||
}
|
||||
|
||||
if (rt->overridden.color.is_valid()) {
|
||||
Texture *tex = get_texture(rt->overridden.color);
|
||||
tex->is_render_target = false;
|
||||
}
|
||||
|
||||
if (rt->backbuffer_fbo != 0) {
|
||||
glDeleteFramebuffers(1, &rt->backbuffer_fbo);
|
||||
|
@ -1617,6 +1700,15 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
|
|||
_render_target_clear_sdf(rt);
|
||||
}
|
||||
|
||||
void TextureStorage::_clear_render_target_overridden_fbo_cache(RenderTarget *rt) {
|
||||
// Dispose of the cached fbo's and the allocated textures
|
||||
for (KeyValue<uint32_t, RenderTarget::RTOverridden::FBOCacheEntry> &E : rt->overridden.fbo_cache) {
|
||||
glDeleteTextures(E.value.allocated_textures.size(), E.value.allocated_textures.ptr());
|
||||
glDeleteFramebuffers(1, &E.value.fbo);
|
||||
}
|
||||
rt->overridden.fbo_cache.clear();
|
||||
}
|
||||
|
||||
RID TextureStorage::render_target_create() {
|
||||
RenderTarget render_target;
|
||||
//render_target.was_used = false;
|
||||
|
@ -1635,11 +1727,14 @@ RID TextureStorage::render_target_create() {
|
|||
void TextureStorage::render_target_free(RID p_rid) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_rid);
|
||||
_clear_render_target(rt);
|
||||
_clear_render_target_overridden_fbo_cache(rt);
|
||||
|
||||
Texture *t = get_texture(rt->texture);
|
||||
if (t) {
|
||||
t->is_render_target = false;
|
||||
texture_free(rt->texture);
|
||||
if (rt->overridden.color.is_null()) {
|
||||
texture_free(rt->texture);
|
||||
}
|
||||
//memdelete(t);
|
||||
}
|
||||
render_target_owner.free(p_rid);
|
||||
|
@ -1666,6 +1761,9 @@ void TextureStorage::render_target_set_size(RID p_render_target, int p_width, in
|
|||
if (p_width == rt->size.x && p_height == rt->size.y && p_view_count == rt->view_count) {
|
||||
return;
|
||||
}
|
||||
if (rt->overridden.color.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_clear_render_target(rt);
|
||||
|
||||
|
@ -1683,10 +1781,91 @@ Size2i TextureStorage::render_target_get_size(RID p_render_target) const {
|
|||
return rt->size;
|
||||
}
|
||||
|
||||
void TextureStorage::render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND(!rt);
|
||||
ERR_FAIL_COND(rt->direct_to_screen);
|
||||
|
||||
rt->overridden.velocity = p_velocity_texture;
|
||||
|
||||
if (rt->overridden.color == p_color_texture && rt->overridden.depth == p_depth_texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_color_texture.is_null() && p_depth_texture.is_null()) {
|
||||
_clear_render_target(rt);
|
||||
rt->overridden.is_overridden = false;
|
||||
rt->overridden.color = RID();
|
||||
rt->overridden.depth = RID();
|
||||
rt->size = Size2i();
|
||||
_clear_render_target_overridden_fbo_cache(rt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rt->overridden.is_overridden) {
|
||||
_clear_render_target(rt);
|
||||
}
|
||||
|
||||
rt->overridden.color = p_color_texture;
|
||||
rt->overridden.depth = p_depth_texture;
|
||||
rt->overridden.is_overridden = true;
|
||||
|
||||
uint32_t hash_key = hash_murmur3_one_64(p_color_texture.get_id());
|
||||
hash_key = hash_murmur3_one_64(p_depth_texture.get_id(), hash_key);
|
||||
hash_key = hash_fmix32(hash_key);
|
||||
|
||||
RBMap<uint32_t, RenderTarget::RTOverridden::FBOCacheEntry>::Element *cache;
|
||||
if ((cache = rt->overridden.fbo_cache.find(hash_key)) != nullptr) {
|
||||
rt->fbo = cache->get().fbo;
|
||||
rt->size = cache->get().size;
|
||||
rt->texture = p_color_texture;
|
||||
return;
|
||||
}
|
||||
|
||||
_update_render_target(rt);
|
||||
|
||||
RenderTarget::RTOverridden::FBOCacheEntry new_entry;
|
||||
new_entry.fbo = rt->fbo;
|
||||
new_entry.size = rt->size;
|
||||
// Keep track of any textures we had to allocate because they weren't overridden.
|
||||
if (p_color_texture.is_null()) {
|
||||
new_entry.allocated_textures.push_back(rt->color);
|
||||
}
|
||||
if (p_depth_texture.is_null()) {
|
||||
new_entry.allocated_textures.push_back(rt->depth);
|
||||
}
|
||||
rt->overridden.fbo_cache.insert(hash_key, new_entry);
|
||||
}
|
||||
|
||||
RID TextureStorage::render_target_get_override_color(RID p_render_target) const {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND_V(!rt, RID());
|
||||
|
||||
return rt->overridden.color;
|
||||
}
|
||||
|
||||
RID TextureStorage::render_target_get_override_depth(RID p_render_target) const {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND_V(!rt, RID());
|
||||
|
||||
return rt->overridden.depth;
|
||||
}
|
||||
|
||||
RID TextureStorage::render_target_get_override_velocity(RID p_render_target) const {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND_V(!rt, RID());
|
||||
|
||||
return rt->overridden.velocity;
|
||||
}
|
||||
|
||||
RID TextureStorage::render_target_get_texture(RID p_render_target) {
|
||||
RenderTarget *rt = render_target_owner.get_or_null(p_render_target);
|
||||
ERR_FAIL_COND_V(!rt, RID());
|
||||
|
||||
if (rt->overridden.color.is_valid()) {
|
||||
return rt->overridden.color;
|
||||
}
|
||||
|
||||
return rt->texture;
|
||||
}
|
||||
|
||||
|
@ -1696,8 +1875,10 @@ void TextureStorage::render_target_set_transparent(RID p_render_target, bool p_t
|
|||
|
||||
rt->is_transparent = p_transparent;
|
||||
|
||||
_clear_render_target(rt);
|
||||
_update_render_target(rt);
|
||||
if (rt->overridden.color.is_null()) {
|
||||
_clear_render_target(rt);
|
||||
_update_render_target(rt);
|
||||
}
|
||||
}
|
||||
|
||||
bool TextureStorage::render_target_get_transparent(RID p_render_target) const {
|
||||
|
@ -1718,6 +1899,11 @@ void TextureStorage::render_target_set_direct_to_screen(RID p_render_target, boo
|
|||
// those functions change how they operate depending on the value of DIRECT_TO_SCREEN
|
||||
_clear_render_target(rt);
|
||||
rt->direct_to_screen = p_direct_to_screen;
|
||||
if (rt->direct_to_screen) {
|
||||
rt->overridden.color = RID();
|
||||
rt->overridden.depth = RID();
|
||||
rt->overridden.velocity = RID();
|
||||
}
|
||||
_update_render_target(rt);
|
||||
}
|
||||
|
||||
|
@ -1750,6 +1936,7 @@ void TextureStorage::render_target_set_msaa(RID p_render_target, RS::ViewportMSA
|
|||
}
|
||||
|
||||
WARN_PRINT("2D MSAA is not yet supported for GLES3.");
|
||||
|
||||
_clear_render_target(rt);
|
||||
rt->msaa = p_msaa;
|
||||
_update_render_target(rt);
|
||||
|
|
|
@ -126,6 +126,7 @@ struct Texture {
|
|||
RID self;
|
||||
|
||||
bool is_proxy = false;
|
||||
bool is_external = false;
|
||||
bool is_render_target = false;
|
||||
|
||||
RID proxy_to = RID();
|
||||
|
@ -187,6 +188,7 @@ struct Texture {
|
|||
void copy_from(const Texture &o) {
|
||||
proxy_to = o.proxy_to;
|
||||
is_proxy = o.is_proxy;
|
||||
is_external = o.is_external;
|
||||
width = o.width;
|
||||
height = o.height;
|
||||
alloc_width = o.alloc_width;
|
||||
|
@ -310,6 +312,7 @@ struct RenderTarget {
|
|||
RID self;
|
||||
GLuint fbo = 0;
|
||||
GLuint color = 0;
|
||||
GLuint depth = 0;
|
||||
GLuint backbuffer_fbo = 0;
|
||||
GLuint backbuffer = 0;
|
||||
|
||||
|
@ -333,6 +336,20 @@ struct RenderTarget {
|
|||
bool used_in_frame = false;
|
||||
RS::ViewportMSAA msaa = RS::VIEWPORT_MSAA_DISABLED;
|
||||
|
||||
struct RTOverridden {
|
||||
bool is_overridden = false;
|
||||
RID color;
|
||||
RID depth;
|
||||
RID velocity;
|
||||
|
||||
struct FBOCacheEntry {
|
||||
GLuint fbo;
|
||||
Size2i size;
|
||||
Vector<GLuint> allocated_textures;
|
||||
};
|
||||
RBMap<uint32_t, FBOCacheEntry> fbo_cache;
|
||||
} overridden;
|
||||
|
||||
RID texture;
|
||||
|
||||
Color clear_color = Color(1, 1, 1, 1);
|
||||
|
@ -395,6 +412,7 @@ private:
|
|||
mutable RID_Owner<RenderTarget> render_target_owner;
|
||||
|
||||
void _clear_render_target(RenderTarget *rt);
|
||||
void _clear_render_target_overridden_fbo_cache(RenderTarget *rt);
|
||||
void _update_render_target(RenderTarget *rt);
|
||||
void _create_render_target_backbuffer(RenderTarget *rt);
|
||||
void _render_target_allocate_sdf(RenderTarget *rt);
|
||||
|
@ -454,6 +472,8 @@ public:
|
|||
virtual void texture_3d_initialize(RID p_texture, Image::Format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) override;
|
||||
virtual void texture_proxy_initialize(RID p_texture, RID p_base) override; //all slices, then all the mipmaps, must be coherent
|
||||
|
||||
RID texture_create_external(Texture::Type p_type, Image::Format p_format, unsigned int p_image, int p_width, int p_height, int p_depth, int p_layers, RS::TextureLayeredType p_layered_type = RS::TEXTURE_LAYERED_2D_ARRAY);
|
||||
|
||||
virtual void texture_2d_update(RID p_texture, const Ref<Image> &p_image, int p_layer = 0) override;
|
||||
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) override{};
|
||||
virtual void texture_proxy_update(RID p_proxy, RID p_base) override;
|
||||
|
@ -593,10 +613,10 @@ public:
|
|||
virtual void render_target_set_vrs_texture(RID p_render_target, RID p_texture) override {}
|
||||
virtual RID render_target_get_vrs_texture(RID p_render_target) const override { return RID(); }
|
||||
|
||||
virtual void render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) override {}
|
||||
virtual RID render_target_get_override_color(RID p_render_target) const override { return RID(); }
|
||||
virtual RID render_target_get_override_depth(RID p_render_target) const override { return RID(); }
|
||||
virtual RID render_target_get_override_velocity(RID p_render_target) const override { return RID(); }
|
||||
virtual void render_target_set_override(RID p_render_target, RID p_color_texture, RID p_depth_texture, RID p_velocity_texture) override;
|
||||
virtual RID render_target_get_override_color(RID p_render_target) const override;
|
||||
virtual RID render_target_get_override_depth(RID p_render_target) const override;
|
||||
virtual RID render_target_get_override_velocity(RID p_render_target) const override;
|
||||
|
||||
virtual RID render_target_get_texture(RID p_render_target) override;
|
||||
|
||||
|
|
|
@ -90,6 +90,8 @@ if env["platform"] == "android":
|
|||
env_openxr.add_source_files(module_obj, "extensions/openxr_android_extension.cpp")
|
||||
if env["vulkan"]:
|
||||
env_openxr.add_source_files(module_obj, "extensions/openxr_vulkan_extension.cpp")
|
||||
if env["opengl3"]:
|
||||
env_openxr.add_source_files(module_obj, "extensions/openxr_opengl_extension.cpp")
|
||||
|
||||
env_openxr.add_source_files(module_obj, "extensions/openxr_palm_pose_extension.cpp")
|
||||
env_openxr.add_source_files(module_obj, "extensions/openxr_composition_layer_depth_extension.cpp")
|
||||
|
|
|
@ -0,0 +1,479 @@
|
|||
/*************************************************************************/
|
||||
/* openxr_opengl_extension.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
#include "../extensions/openxr_opengl_extension.h"
|
||||
#include "../openxr_util.h"
|
||||
#include "drivers/gles3/effects/copy_effects.h"
|
||||
#include "drivers/gles3/storage/texture_storage.h"
|
||||
#include "servers/rendering/rendering_server_globals.h"
|
||||
#include "servers/rendering_server.h"
|
||||
|
||||
OpenXROpenGLExtension::OpenXROpenGLExtension(OpenXRAPI *p_openxr_api) :
|
||||
OpenXRGraphicsExtensionWrapper(p_openxr_api) {
|
||||
#ifdef ANDROID_ENABLED
|
||||
request_extensions[XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME] = nullptr;
|
||||
#else
|
||||
request_extensions[XR_KHR_OPENGL_ENABLE_EXTENSION_NAME] = nullptr;
|
||||
#endif
|
||||
|
||||
ERR_FAIL_NULL(openxr_api);
|
||||
}
|
||||
|
||||
OpenXROpenGLExtension::~OpenXROpenGLExtension() {
|
||||
}
|
||||
|
||||
void OpenXROpenGLExtension::on_instance_created(const XrInstance p_instance) {
|
||||
ERR_FAIL_NULL(openxr_api);
|
||||
|
||||
// Obtain pointers to functions we're accessing here.
|
||||
|
||||
#ifdef ANDROID_ENABLED
|
||||
EXT_INIT_XR_FUNC(xrGetOpenGLESGraphicsRequirementsKHR);
|
||||
#else
|
||||
EXT_INIT_XR_FUNC(xrGetOpenGLGraphicsRequirementsKHR);
|
||||
#endif
|
||||
EXT_INIT_XR_FUNC(xrEnumerateSwapchainImages);
|
||||
}
|
||||
|
||||
bool OpenXROpenGLExtension::check_graphics_api_support(XrVersion p_desired_version) {
|
||||
ERR_FAIL_NULL_V(openxr_api, false);
|
||||
|
||||
XrSystemId system_id = openxr_api->get_system_id();
|
||||
XrInstance instance = openxr_api->get_instance();
|
||||
|
||||
#ifdef ANDROID_ENABLED
|
||||
XrGraphicsRequirementsOpenGLESKHR opengl_requirements;
|
||||
opengl_requirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR;
|
||||
opengl_requirements.next = nullptr;
|
||||
|
||||
XrResult result = xrGetOpenGLESGraphicsRequirementsKHR(instance, system_id, &opengl_requirements);
|
||||
if (!openxr_api->xr_result(result, "Failed to get OpenGL graphics requirements!")) {
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
XrGraphicsRequirementsOpenGLKHR opengl_requirements;
|
||||
opengl_requirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR;
|
||||
opengl_requirements.next = nullptr;
|
||||
|
||||
XrResult result = xrGetOpenGLGraphicsRequirementsKHR(instance, system_id, &opengl_requirements);
|
||||
if (!openxr_api->xr_result(result, "Failed to get OpenGL graphics requirements!")) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (p_desired_version < opengl_requirements.minApiVersionSupported) {
|
||||
print_line("OpenXR: Requested OpenGL version does not meet the minimum version this runtime supports.");
|
||||
print_line("- desired_version ", OpenXRUtil::make_xr_version_string(p_desired_version));
|
||||
print_line("- minApiVersionSupported ", OpenXRUtil::make_xr_version_string(opengl_requirements.minApiVersionSupported));
|
||||
print_line("- maxApiVersionSupported ", OpenXRUtil::make_xr_version_string(opengl_requirements.maxApiVersionSupported));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (p_desired_version > opengl_requirements.maxApiVersionSupported) {
|
||||
print_line("OpenXR: Requested OpenGL version exceeds the maximum version this runtime has been tested on and is known to support.");
|
||||
print_line("- desired_version ", OpenXRUtil::make_xr_version_string(p_desired_version));
|
||||
print_line("- minApiVersionSupported ", OpenXRUtil::make_xr_version_string(opengl_requirements.minApiVersionSupported));
|
||||
print_line("- maxApiVersionSupported ", OpenXRUtil::make_xr_version_string(opengl_requirements.maxApiVersionSupported));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
XrGraphicsBindingOpenGLWin32KHR OpenXROpenGLExtension::graphics_binding_gl;
|
||||
#elif ANDROID_ENABLED
|
||||
XrGraphicsBindingOpenGLESAndroidKHR OpenXROpenGLExtension::graphics_binding_gl;
|
||||
#else
|
||||
XrGraphicsBindingOpenGLXlibKHR OpenXROpenGLExtension::graphics_binding_gl;
|
||||
#endif
|
||||
|
||||
void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_next_pointer) {
|
||||
XrVersion desired_version = XR_MAKE_VERSION(3, 3, 0);
|
||||
|
||||
if (!check_graphics_api_support(desired_version)) {
|
||||
print_line("OpenXR: Trying to initialize with OpenGL anyway...");
|
||||
//return p_next_pointer;
|
||||
}
|
||||
|
||||
DisplayServer *display_server = DisplayServer::get_singleton();
|
||||
|
||||
#ifdef WIN32
|
||||
graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR,
|
||||
graphics_binding_gl.next = p_next_pointer;
|
||||
|
||||
graphics_binding_gl.hDC = (HDC)display_server->window_get_native_handle(DisplayServer::WINDOW_VIEW);
|
||||
graphics_binding_gl.hGLRC = (HGLRC)display_server->window_get_native_handle(DisplayServer::OPENGL_CONTEXT);
|
||||
#elif ANDROID_ENABLED
|
||||
graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR;
|
||||
graphics_binding_gl.next = p_next_pointer;
|
||||
|
||||
graphics_binding_gl.display = eglGetCurrentDisplay();
|
||||
graphics_binding_gl.config = (EGLConfig)0; // https://github.com/KhronosGroup/OpenXR-SDK-Source/blob/master/src/tests/hello_xr/graphicsplugin_opengles.cpp#L122
|
||||
graphics_binding_gl.context = eglGetCurrentContext();
|
||||
#else
|
||||
graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR;
|
||||
graphics_binding_gl.next = p_next_pointer;
|
||||
|
||||
void *display_handle = (void *)display_server->window_get_native_handle(DisplayServer::DISPLAY_HANDLE);
|
||||
void *glxcontext_handle = (void *)display_server->window_get_native_handle(DisplayServer::OPENGL_CONTEXT);
|
||||
void *glxdrawable_handle = (void *)display_server->window_get_native_handle(DisplayServer::WINDOW_HANDLE);
|
||||
|
||||
graphics_binding_gl.xDisplay = (Display *)display_handle;
|
||||
graphics_binding_gl.glxContext = (GLXContext)glxcontext_handle;
|
||||
graphics_binding_gl.glxDrawable = (GLXDrawable)glxdrawable_handle;
|
||||
|
||||
if (graphics_binding_gl.xDisplay == nullptr) {
|
||||
print_line("OpenXR Failed to get xDisplay from Godot, using XOpenDisplay(nullptr)");
|
||||
graphics_binding_gl.xDisplay = XOpenDisplay(nullptr);
|
||||
}
|
||||
if (graphics_binding_gl.glxContext == nullptr) {
|
||||
print_line("OpenXR Failed to get glxContext from Godot, using glXGetCurrentContext()");
|
||||
graphics_binding_gl.glxContext = glXGetCurrentContext();
|
||||
}
|
||||
if (graphics_binding_gl.glxDrawable == 0) {
|
||||
print_line("OpenXR Failed to get glxDrawable from Godot, using glXGetCurrentDrawable()");
|
||||
graphics_binding_gl.glxDrawable = glXGetCurrentDrawable();
|
||||
}
|
||||
|
||||
// spec says to use proper values but runtimes don't care
|
||||
graphics_binding_gl.visualid = 0;
|
||||
graphics_binding_gl.glxFBConfig = 0;
|
||||
#endif
|
||||
|
||||
return &graphics_binding_gl;
|
||||
}
|
||||
|
||||
void OpenXROpenGLExtension::get_usable_swapchain_formats(Vector<int64_t> &p_usable_swap_chains) {
|
||||
#ifdef WIN32
|
||||
p_usable_swap_chains.push_back(GL_SRGB8_ALPHA8);
|
||||
p_usable_swap_chains.push_back(GL_RGBA8);
|
||||
#elif ANDROID_ENABLED
|
||||
p_usable_swap_chains.push_back(GL_SRGB8_ALPHA8);
|
||||
p_usable_swap_chains.push_back(GL_RGBA8);
|
||||
#else
|
||||
p_usable_swap_chains.push_back(GL_SRGB8_ALPHA8_EXT);
|
||||
p_usable_swap_chains.push_back(GL_RGBA8_EXT);
|
||||
#endif
|
||||
}
|
||||
|
||||
void OpenXROpenGLExtension::get_usable_depth_formats(Vector<int64_t> &p_usable_depth_formats) {
|
||||
p_usable_depth_formats.push_back(GL_DEPTH_COMPONENT32F);
|
||||
p_usable_depth_formats.push_back(GL_DEPTH24_STENCIL8);
|
||||
p_usable_depth_formats.push_back(GL_DEPTH32F_STENCIL8);
|
||||
}
|
||||
|
||||
bool OpenXROpenGLExtension::get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) {
|
||||
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
|
||||
ERR_FAIL_NULL_V(texture_storage, false);
|
||||
|
||||
uint32_t swapchain_length;
|
||||
XrResult result = xrEnumerateSwapchainImages(p_swapchain, 0, &swapchain_length, nullptr);
|
||||
if (XR_FAILED(result)) {
|
||||
print_line("OpenXR: Failed to get swapchaim image count [", openxr_api->get_error_string(result), "]");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ANDROID_ENABLED
|
||||
XrSwapchainImageOpenGLESKHR *images = (XrSwapchainImageOpenGLESKHR *)memalloc(sizeof(XrSwapchainImageOpenGLESKHR) * swapchain_length);
|
||||
#else
|
||||
XrSwapchainImageOpenGLKHR *images = (XrSwapchainImageOpenGLKHR *)memalloc(sizeof(XrSwapchainImageOpenGLKHR) * swapchain_length);
|
||||
#endif
|
||||
ERR_FAIL_NULL_V_MSG(images, false, "OpenXR Couldn't allocate memory for swap chain image");
|
||||
|
||||
for (uint64_t i = 0; i < swapchain_length; i++) {
|
||||
#ifdef ANDROID_ENABLED
|
||||
images[i].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_ES_KHR;
|
||||
#else
|
||||
images[i].type = XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR;
|
||||
#endif
|
||||
images[i].next = nullptr;
|
||||
images[i].image = 0;
|
||||
}
|
||||
|
||||
result = xrEnumerateSwapchainImages(p_swapchain, swapchain_length, &swapchain_length, (XrSwapchainImageBaseHeader *)images);
|
||||
if (XR_FAILED(result)) {
|
||||
print_line("OpenXR: Failed to get swapchaim images [", openxr_api->get_error_string(result), "]");
|
||||
memfree(images);
|
||||
return false;
|
||||
}
|
||||
|
||||
SwapchainGraphicsData *data = memnew(SwapchainGraphicsData);
|
||||
if (data == nullptr) {
|
||||
print_line("OpenXR: Failed to allocate memory for swapchain data");
|
||||
memfree(images);
|
||||
return false;
|
||||
}
|
||||
*r_swapchain_graphics_data = data;
|
||||
data->is_multiview = (p_array_size > 1);
|
||||
|
||||
Image::Format format = Image::FORMAT_RGBA8;
|
||||
|
||||
Vector<RID> texture_rids;
|
||||
|
||||
for (uint64_t i = 0; i < swapchain_length; i++) {
|
||||
RID texture_rid = texture_storage->texture_create_external(
|
||||
p_array_size == 1 ? GLES3::Texture::TYPE_2D : GLES3::Texture::TYPE_LAYERED,
|
||||
format,
|
||||
images[i].image,
|
||||
p_width,
|
||||
p_height,
|
||||
1,
|
||||
p_array_size);
|
||||
|
||||
texture_rids.push_back(texture_rid);
|
||||
}
|
||||
|
||||
data->texture_rids = texture_rids;
|
||||
|
||||
memfree(images);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenXROpenGLExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) {
|
||||
XrMatrix4x4f matrix;
|
||||
XrMatrix4x4f_CreateProjectionFov(&matrix, GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far);
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
r_camera_matrix.columns[j][i] = matrix.m[j * 4 + i];
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
RID OpenXROpenGLExtension::get_texture(void *p_swapchain_graphics_data, int p_image_index) {
|
||||
SwapchainGraphicsData *data = (SwapchainGraphicsData *)p_swapchain_graphics_data;
|
||||
ERR_FAIL_NULL_V(data, RID());
|
||||
|
||||
ERR_FAIL_INDEX_V(p_image_index, data->texture_rids.size(), RID());
|
||||
return data->texture_rids[p_image_index];
|
||||
}
|
||||
|
||||
void OpenXROpenGLExtension::cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) {
|
||||
if (*p_swapchain_graphics_data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
|
||||
ERR_FAIL_NULL(texture_storage);
|
||||
|
||||
SwapchainGraphicsData *data = (SwapchainGraphicsData *)*p_swapchain_graphics_data;
|
||||
|
||||
for (int i = 0; i < data->texture_rids.size(); i++) {
|
||||
texture_storage->texture_free(data->texture_rids[i]);
|
||||
}
|
||||
data->texture_rids.clear();
|
||||
|
||||
memdelete(data);
|
||||
*p_swapchain_graphics_data = nullptr;
|
||||
}
|
||||
|
||||
#define ENUM_TO_STRING_CASE(e) \
|
||||
case e: { \
|
||||
return String(#e); \
|
||||
} break;
|
||||
|
||||
String OpenXROpenGLExtension::get_swapchain_format_name(int64_t p_swapchain_format) const {
|
||||
// These are somewhat different per platform, will need to weed some stuff out...
|
||||
switch (p_swapchain_format) {
|
||||
#ifdef WIN32
|
||||
// using definitions from GLAD
|
||||
ENUM_TO_STRING_CASE(GL_R8_SNORM)
|
||||
ENUM_TO_STRING_CASE(GL_RG8_SNORM)
|
||||
ENUM_TO_STRING_CASE(GL_RGB8_SNORM)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA8_SNORM)
|
||||
ENUM_TO_STRING_CASE(GL_R16_SNORM)
|
||||
ENUM_TO_STRING_CASE(GL_RG16_SNORM)
|
||||
ENUM_TO_STRING_CASE(GL_RGB16_SNORM)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA16_SNORM)
|
||||
ENUM_TO_STRING_CASE(GL_RGB4)
|
||||
ENUM_TO_STRING_CASE(GL_RGB5)
|
||||
ENUM_TO_STRING_CASE(GL_RGB8)
|
||||
ENUM_TO_STRING_CASE(GL_RGB10)
|
||||
ENUM_TO_STRING_CASE(GL_RGB12)
|
||||
ENUM_TO_STRING_CASE(GL_RGB16)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA2)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA4)
|
||||
ENUM_TO_STRING_CASE(GL_RGB5_A1)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA8)
|
||||
ENUM_TO_STRING_CASE(GL_RGB10_A2)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA12)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA16)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA32F)
|
||||
ENUM_TO_STRING_CASE(GL_RGB32F)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA16F)
|
||||
ENUM_TO_STRING_CASE(GL_RGB16F)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA32UI)
|
||||
ENUM_TO_STRING_CASE(GL_RGB32UI)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA16UI)
|
||||
ENUM_TO_STRING_CASE(GL_RGB16UI)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA8UI)
|
||||
ENUM_TO_STRING_CASE(GL_RGB8UI)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA32I)
|
||||
ENUM_TO_STRING_CASE(GL_RGB32I)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA16I)
|
||||
ENUM_TO_STRING_CASE(GL_RGB16I)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA8I)
|
||||
ENUM_TO_STRING_CASE(GL_RGB8I)
|
||||
ENUM_TO_STRING_CASE(GL_RGB10_A2UI)
|
||||
ENUM_TO_STRING_CASE(GL_SRGB)
|
||||
ENUM_TO_STRING_CASE(GL_SRGB8)
|
||||
ENUM_TO_STRING_CASE(GL_SRGB_ALPHA)
|
||||
ENUM_TO_STRING_CASE(GL_SRGB8_ALPHA8)
|
||||
ENUM_TO_STRING_CASE(GL_DEPTH_COMPONENT16)
|
||||
ENUM_TO_STRING_CASE(GL_DEPTH_COMPONENT24)
|
||||
ENUM_TO_STRING_CASE(GL_DEPTH_COMPONENT32)
|
||||
ENUM_TO_STRING_CASE(GL_DEPTH24_STENCIL8)
|
||||
ENUM_TO_STRING_CASE(GL_R11F_G11F_B10F)
|
||||
ENUM_TO_STRING_CASE(GL_DEPTH_COMPONENT32F)
|
||||
ENUM_TO_STRING_CASE(GL_DEPTH32F_STENCIL8)
|
||||
|
||||
#elif ANDROID_ENABLED
|
||||
// using definitions from GLES3/gl3.h
|
||||
|
||||
ENUM_TO_STRING_CASE(GL_RGBA4)
|
||||
ENUM_TO_STRING_CASE(GL_RGB5_A1)
|
||||
ENUM_TO_STRING_CASE(GL_RGB565)
|
||||
ENUM_TO_STRING_CASE(GL_RGB8)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA8)
|
||||
ENUM_TO_STRING_CASE(GL_RGB10_A2)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA32F)
|
||||
ENUM_TO_STRING_CASE(GL_RGB32F)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA16F)
|
||||
ENUM_TO_STRING_CASE(GL_RGB16F)
|
||||
ENUM_TO_STRING_CASE(GL_R11F_G11F_B10F)
|
||||
ENUM_TO_STRING_CASE(GL_UNSIGNED_INT_10F_11F_11F_REV)
|
||||
ENUM_TO_STRING_CASE(GL_RGB9_E5)
|
||||
ENUM_TO_STRING_CASE(GL_UNSIGNED_INT_5_9_9_9_REV)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA32UI)
|
||||
ENUM_TO_STRING_CASE(GL_RGB32UI)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA16UI)
|
||||
ENUM_TO_STRING_CASE(GL_RGB16UI)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA8UI)
|
||||
ENUM_TO_STRING_CASE(GL_RGB8UI)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA32I)
|
||||
ENUM_TO_STRING_CASE(GL_RGB32I)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA16I)
|
||||
ENUM_TO_STRING_CASE(GL_RGB16I)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA8I)
|
||||
ENUM_TO_STRING_CASE(GL_RGB8I)
|
||||
ENUM_TO_STRING_CASE(GL_RG)
|
||||
ENUM_TO_STRING_CASE(GL_RG_INTEGER)
|
||||
ENUM_TO_STRING_CASE(GL_R8)
|
||||
ENUM_TO_STRING_CASE(GL_RG8)
|
||||
ENUM_TO_STRING_CASE(GL_R16F)
|
||||
ENUM_TO_STRING_CASE(GL_R32F)
|
||||
ENUM_TO_STRING_CASE(GL_RG16F)
|
||||
ENUM_TO_STRING_CASE(GL_RG32F)
|
||||
ENUM_TO_STRING_CASE(GL_R8I)
|
||||
ENUM_TO_STRING_CASE(GL_R8UI)
|
||||
ENUM_TO_STRING_CASE(GL_R16I)
|
||||
ENUM_TO_STRING_CASE(GL_R16UI)
|
||||
ENUM_TO_STRING_CASE(GL_R32I)
|
||||
ENUM_TO_STRING_CASE(GL_R32UI)
|
||||
ENUM_TO_STRING_CASE(GL_RG8I)
|
||||
ENUM_TO_STRING_CASE(GL_RG8UI)
|
||||
ENUM_TO_STRING_CASE(GL_RG16I)
|
||||
ENUM_TO_STRING_CASE(GL_RG16UI)
|
||||
ENUM_TO_STRING_CASE(GL_RG32I)
|
||||
ENUM_TO_STRING_CASE(GL_RG32UI)
|
||||
ENUM_TO_STRING_CASE(GL_R8_SNORM)
|
||||
ENUM_TO_STRING_CASE(GL_RG8_SNORM)
|
||||
ENUM_TO_STRING_CASE(GL_RGB8_SNORM)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA8_SNORM)
|
||||
ENUM_TO_STRING_CASE(GL_RGB10_A2UI)
|
||||
ENUM_TO_STRING_CASE(GL_SRGB)
|
||||
ENUM_TO_STRING_CASE(GL_SRGB8)
|
||||
ENUM_TO_STRING_CASE(GL_SRGB8_ALPHA8)
|
||||
ENUM_TO_STRING_CASE(GL_COMPRESSED_R11_EAC)
|
||||
ENUM_TO_STRING_CASE(GL_COMPRESSED_SIGNED_R11_EAC)
|
||||
ENUM_TO_STRING_CASE(GL_COMPRESSED_RG11_EAC)
|
||||
ENUM_TO_STRING_CASE(GL_COMPRESSED_SIGNED_RG11_EAC)
|
||||
ENUM_TO_STRING_CASE(GL_COMPRESSED_RGB8_ETC2)
|
||||
ENUM_TO_STRING_CASE(GL_COMPRESSED_SRGB8_ETC2)
|
||||
ENUM_TO_STRING_CASE(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2)
|
||||
ENUM_TO_STRING_CASE(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2)
|
||||
ENUM_TO_STRING_CASE(GL_COMPRESSED_RGBA8_ETC2_EAC)
|
||||
ENUM_TO_STRING_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC)
|
||||
ENUM_TO_STRING_CASE(GL_DEPTH_COMPONENT16)
|
||||
ENUM_TO_STRING_CASE(GL_DEPTH_COMPONENT24)
|
||||
ENUM_TO_STRING_CASE(GL_DEPTH24_STENCIL8)
|
||||
|
||||
#else
|
||||
// using definitions from GL/gl.h
|
||||
ENUM_TO_STRING_CASE(GL_ALPHA4_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_ALPHA8_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_ALPHA12_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_ALPHA16_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_LUMINANCE4_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_LUMINANCE8_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_LUMINANCE12_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_LUMINANCE16_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_LUMINANCE4_ALPHA4_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_LUMINANCE6_ALPHA2_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_LUMINANCE8_ALPHA8_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_LUMINANCE12_ALPHA4_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_LUMINANCE12_ALPHA12_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_LUMINANCE16_ALPHA16_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_INTENSITY_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_INTENSITY4_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_INTENSITY8_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_INTENSITY12_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_INTENSITY16_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_RGB2_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_RGB4_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_RGB5_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_RGB8_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_RGB10_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_RGB12_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_RGB16_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA2_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA4_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_RGB5_A1_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA8_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_RGB10_A2_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA12_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_RGBA16_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_SRGB_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_SRGB8_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_SRGB_ALPHA_EXT)
|
||||
ENUM_TO_STRING_CASE(GL_SRGB8_ALPHA8_EXT)
|
||||
#endif
|
||||
default: {
|
||||
return String("Swapchain format 0x") + String::num_int64(p_swapchain_format, 16);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // GLES3_ENABLED
|
|
@ -0,0 +1,120 @@
|
|||
/*************************************************************************/
|
||||
/* openxr_opengl_extension.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
|
||||
/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef OPENXR_OPENGL_EXTENSION_H
|
||||
#define OPENXR_OPENGL_EXTENSION_H
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
|
||||
#include "core/templates/vector.h"
|
||||
#include "openxr_extension_wrapper.h"
|
||||
|
||||
#include "../openxr_api.h"
|
||||
#include "../util.h"
|
||||
|
||||
#ifdef ANDROID_ENABLED
|
||||
#define XR_USE_GRAPHICS_API_OPENGL_ES
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES3/gl3.h>
|
||||
#include <GLES3/gl3ext.h>
|
||||
#else
|
||||
#define XR_USE_GRAPHICS_API_OPENGL
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS_ENABLED
|
||||
// Including windows.h here is absolutely evil, we shouldn't be doing this outside of platform
|
||||
// however due to the way the openxr headers are put together, we have no choice.
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef X11_ENABLED
|
||||
#include OPENGL_INCLUDE_H
|
||||
#define GL_GLEXT_PROTOTYPES 1
|
||||
#define GL3_PROTOTYPES 1
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include <GL/glx.h>
|
||||
#include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID_ENABLED
|
||||
// The jobject type from jni.h is used by openxr_platform.h on Android.
|
||||
#include <jni.h>
|
||||
#endif
|
||||
|
||||
// include platform dependent structs
|
||||
#include <openxr/openxr_platform.h>
|
||||
|
||||
class OpenXROpenGLExtension : public OpenXRGraphicsExtensionWrapper {
|
||||
public:
|
||||
OpenXROpenGLExtension(OpenXRAPI *p_openxr_api);
|
||||
virtual ~OpenXROpenGLExtension() override;
|
||||
|
||||
virtual void on_instance_created(const XrInstance p_instance) override;
|
||||
virtual void *set_session_create_and_get_next_pointer(void *p_next_pointer) override;
|
||||
|
||||
virtual void get_usable_swapchain_formats(Vector<int64_t> &p_usable_swap_chains) override;
|
||||
virtual void get_usable_depth_formats(Vector<int64_t> &p_usable_swap_chains) override;
|
||||
virtual String get_swapchain_format_name(int64_t p_swapchain_format) const override;
|
||||
virtual bool get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) override;
|
||||
virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) override;
|
||||
virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) override;
|
||||
virtual RID get_texture(void *p_swapchain_graphics_data, int p_image_index) override;
|
||||
|
||||
private:
|
||||
static OpenXROpenGLExtension *singleton;
|
||||
|
||||
#ifdef WIN32
|
||||
static XrGraphicsBindingOpenGLWin32KHR graphics_binding_gl;
|
||||
#elif ANDROID_ENABLED
|
||||
static XrGraphicsBindingOpenGLESAndroidKHR graphics_binding_gl;
|
||||
#else
|
||||
static XrGraphicsBindingOpenGLXlibKHR graphics_binding_gl;
|
||||
#endif
|
||||
|
||||
struct SwapchainGraphicsData {
|
||||
bool is_multiview;
|
||||
Vector<RID> texture_rids;
|
||||
};
|
||||
|
||||
bool check_graphics_api_support(XrVersion p_desired_version);
|
||||
|
||||
#ifdef ANDROID_ENABLED
|
||||
EXT_PROTO_XRRESULT_FUNC3(xrGetOpenGLESGraphicsRequirementsKHR, (XrInstance), p_instance, (XrSystemId), p_system_id, (XrGraphicsRequirementsOpenGLESKHR *), p_graphics_requirements)
|
||||
#else
|
||||
EXT_PROTO_XRRESULT_FUNC3(xrGetOpenGLGraphicsRequirementsKHR, (XrInstance), p_instance, (XrSystemId), p_system_id, (XrGraphicsRequirementsOpenGLKHR *), p_graphics_requirements)
|
||||
#endif
|
||||
EXT_PROTO_XRRESULT_FUNC4(xrEnumerateSwapchainImages, (XrSwapchain), p_swapchain, (uint32_t), p_image_capacity_input, (uint32_t *), p_image_count_output, (XrSwapchainImageBaseHeader *), p_images)
|
||||
};
|
||||
|
||||
#endif // GLES3_ENABLED
|
||||
|
||||
#endif // OPENXR_OPENGL_EXTENSION_H
|
|
@ -45,10 +45,40 @@
|
|||
#include "extensions/openxr_android_extension.h"
|
||||
#endif
|
||||
|
||||
// We need to have all the graphics API defines before the Vulkan or OpenGL
|
||||
// extensions are included, otherwise we'll only get one graphics API.
|
||||
#ifdef VULKAN_ENABLED
|
||||
#define XR_USE_GRAPHICS_API_VULKAN
|
||||
#endif
|
||||
#ifdef GLES3_ENABLED
|
||||
#ifdef ANDROID
|
||||
#define XR_USE_GRAPHICS_API_OPENGL_ES
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES3/gl3.h>
|
||||
#include <GLES3/gl3ext.h>
|
||||
#else
|
||||
#define XR_USE_GRAPHICS_API_OPENGL
|
||||
#endif // ANDROID
|
||||
#ifdef X11_ENABLED
|
||||
#include OPENGL_INCLUDE_H
|
||||
#define GL_GLEXT_PROTOTYPES 1
|
||||
#define GL3_PROTOTYPES 1
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include <GL/glx.h>
|
||||
#include <X11/Xlib.h>
|
||||
#endif // X11_ENABLED
|
||||
#endif // GLES_ENABLED
|
||||
|
||||
#ifdef VULKAN_ENABLED
|
||||
#include "extensions/openxr_vulkan_extension.h"
|
||||
#endif
|
||||
|
||||
#ifdef GLES3_ENABLED
|
||||
#include "extensions/openxr_opengl_extension.h"
|
||||
#endif
|
||||
|
||||
#include "extensions/openxr_composition_layer_depth_extension.h"
|
||||
#include "extensions/openxr_fb_display_refresh_rate_extension.h"
|
||||
#include "extensions/openxr_fb_passthrough_extension_wrapper.h"
|
||||
|
@ -1142,9 +1172,8 @@ bool OpenXRAPI::initialize(const String &p_rendering_driver) {
|
|||
#endif
|
||||
} else if (p_rendering_driver == "opengl3") {
|
||||
#ifdef GLES3_ENABLED
|
||||
// graphics_extension = memnew(OpenXROpenGLExtension(this));
|
||||
// register_extension_wrapper(graphics_extension);
|
||||
ERR_FAIL_V_MSG(false, "OpenXR: OpenGL is not supported at this time.");
|
||||
graphics_extension = memnew(OpenXROpenGLExtension(this));
|
||||
register_extension_wrapper(graphics_extension);
|
||||
#else
|
||||
// shouldn't be possible...
|
||||
ERR_FAIL_V(false);
|
||||
|
|
|
@ -321,6 +321,11 @@ int64_t DisplayServerAndroid::window_get_native_handle(HandleType p_handle_type,
|
|||
case WINDOW_VIEW: {
|
||||
return 0; // Not supported.
|
||||
}
|
||||
#ifdef GLES3_ENABLED
|
||||
case OPENGL_CONTEXT: {
|
||||
return eglGetCurrentContext();
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1309,6 +1309,11 @@ int64_t DisplayServerX11::window_get_native_handle(HandleType p_handle_type, Win
|
|||
case WINDOW_VIEW: {
|
||||
return 0; // Not supported.
|
||||
}
|
||||
#ifdef GLES3_ENABLED
|
||||
case OPENGL_CONTEXT: {
|
||||
return (int64_t)gl_manager->get_glx_context(p_window);
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -376,6 +376,17 @@ bool GLManager_X11::is_using_vsync() const {
|
|||
return use_vsync;
|
||||
}
|
||||
|
||||
void *GLManager_X11::get_glx_context(DisplayServer::WindowID p_window_id) {
|
||||
if (p_window_id == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const GLWindow &win = _windows[p_window_id];
|
||||
const GLDisplay &disp = get_display(win.gldisplay_id);
|
||||
|
||||
return (void *)disp.context->glx_context;
|
||||
}
|
||||
|
||||
GLManager_X11::GLManager_X11(const Vector2i &p_size, ContextType p_context_type) {
|
||||
context_type = p_context_type;
|
||||
|
||||
|
|
|
@ -116,6 +116,8 @@ public:
|
|||
void set_use_vsync(bool p_use);
|
||||
bool is_using_vsync() const;
|
||||
|
||||
void *get_glx_context(DisplayServer::WindowID p_window_id);
|
||||
|
||||
GLManager_X11(const Vector2i &p_size, ContextType p_context_type);
|
||||
~GLManager_X11();
|
||||
};
|
||||
|
|
|
@ -2932,6 +2932,11 @@ int64_t DisplayServerMacOS::window_get_native_handle(HandleType p_handle_type, W
|
|||
case WINDOW_VIEW: {
|
||||
return (int64_t)windows[p_window].window_view;
|
||||
}
|
||||
#ifdef GLES3_ENABLED
|
||||
case OPENGL_CONTEXT: {
|
||||
return (int64_t)gl_manager->get_context(p_window);
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -89,6 +89,8 @@ public:
|
|||
void set_use_vsync(bool p_use);
|
||||
bool is_using_vsync() const;
|
||||
|
||||
NSOpenGLContext *get_context(DisplayServer::WindowID p_window_id);
|
||||
|
||||
GLManager_MacOS(ContextType p_context_type);
|
||||
~GLManager_MacOS();
|
||||
};
|
||||
|
|
|
@ -215,6 +215,15 @@ bool GLManager_MacOS::is_using_vsync() const {
|
|||
return use_vsync;
|
||||
}
|
||||
|
||||
NSOpenGLContext *GLManager_MacOS::get_context(DisplayServer::WindowID p_window_id) {
|
||||
if (!windows.has(p_window_id)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GLWindow &win = windows[p_window_id];
|
||||
return win.context;
|
||||
}
|
||||
|
||||
GLManager_MacOS::GLManager_MacOS(ContextType p_context_type) {
|
||||
context_type = p_context_type;
|
||||
}
|
||||
|
|
|
@ -741,9 +741,14 @@ int64_t DisplayServerWindows::window_get_native_handle(HandleType p_handle_type,
|
|||
case WINDOW_HANDLE: {
|
||||
return (int64_t)windows[p_window].hWnd;
|
||||
}
|
||||
#if defined(GLES3_ENABLED)
|
||||
case WINDOW_VIEW: {
|
||||
return 0; // Not supported.
|
||||
return (int64_t)gl_manager->get_hdc(p_window);
|
||||
}
|
||||
case OPENGL_CONTEXT: {
|
||||
return (int64_t)gl_manager->get_hglrc(p_window);
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -339,6 +339,16 @@ bool GLManager_Windows::is_using_vsync() const {
|
|||
return use_vsync;
|
||||
}
|
||||
|
||||
HDC GLManager_Windows::get_hdc(DisplayServer::WindowID p_window_id) {
|
||||
return get_window(p_window_id).hDC;
|
||||
}
|
||||
|
||||
HGLRC GLManager_Windows::get_hglrc(DisplayServer::WindowID p_window_id) {
|
||||
const GLWindow &win = get_window(p_window_id);
|
||||
const GLDisplay &disp = get_display(win.gldisplay_id);
|
||||
return disp.hRC;
|
||||
}
|
||||
|
||||
GLManager_Windows::GLManager_Windows(ContextType p_context_type) {
|
||||
context_type = p_context_type;
|
||||
|
||||
|
|
|
@ -113,6 +113,9 @@ public:
|
|||
void set_use_vsync(bool p_use);
|
||||
bool is_using_vsync() const;
|
||||
|
||||
HDC get_hdc(DisplayServer::WindowID p_window_id);
|
||||
HGLRC get_hglrc(DisplayServer::WindowID p_window_id);
|
||||
|
||||
GLManager_Windows(ContextType p_context_type);
|
||||
~GLManager_Windows();
|
||||
};
|
||||
|
|
|
@ -826,6 +826,7 @@ void DisplayServer::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(DISPLAY_HANDLE);
|
||||
BIND_ENUM_CONSTANT(WINDOW_HANDLE);
|
||||
BIND_ENUM_CONSTANT(WINDOW_VIEW);
|
||||
BIND_ENUM_CONSTANT(OPENGL_CONTEXT);
|
||||
|
||||
BIND_ENUM_CONSTANT(TTS_UTTERANCE_STARTED);
|
||||
BIND_ENUM_CONSTANT(TTS_UTTERANCE_ENDED);
|
||||
|
|
|
@ -70,6 +70,7 @@ public:
|
|||
DISPLAY_HANDLE,
|
||||
WINDOW_HANDLE,
|
||||
WINDOW_VIEW,
|
||||
OPENGL_CONTEXT,
|
||||
};
|
||||
|
||||
typedef DisplayServer *(*CreateFunction)(const String &, WindowMode, VSyncMode, uint32_t, const Point2i *, const Size2i &, Error &r_error);
|
||||
|
|
Loading…
Reference in New Issue