Files
bearstonem--openmohaa-vr/code/renderercommon/tr_common.h
T
bearstonemandClaude Opus 5 a8a1314c2d fix(vr): ask for an ES context for the fixed function renderer, and check it is current
Two problems the first device run found, one hiding the other.

GLimp_SetMode's fixedFunction branch offers exactly one context: desktop OpenGL
1.1. There is no such thing on Android, so window creation failed three times
over and R_Init gave up with "Couldn't get a visual". renderergl2 never met this
because it takes the other branch, which already knows how to ask for ES.

gl4es is what makes the request answerable, and it wants the opposite of what
the renderer believes it is getting: desktop GL 1.x presented upwards, OpenGL ES
underneath. So the fixed function branch now asks for ES 3.0 and then ES 2.0,
and the renderer is never told - it reads its version through gl4es, which
reports desktop GL, and takes the desktop fixed function path on the strength of
it.

That got the renderer up, and revealed the second problem: the OpenXR session
found no current EGL context. Which is where gl4es having its own opinion about
glGetString stops being convenient. The engine's proof that a context is live is
GL_VERSION coming back non-NULL, and gl4es answers VERSION, VENDOR and RENDERER
out of constants without asking the driver - so a context that was created but
never bound passes that test and is only noticed much later, somewhere else
entirely. GLimp_SetMode now asks SDL directly whether the context it just made
is current, restoring the check gl4es defeated.

The session no longer assumes one is bound either. Being current is per thread,
and a window that has not been shown yet has no surface to be current against,
so VR_CreateSession asks for the binding through GLimp_MakeCurrent rather than
requiring it to already be there, and reports the EGL handles when it cannot get
one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-26 22:02:44 -07:00

208 lines
7.0 KiB
C

/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Quake III Arena source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#ifndef TR_COMMON_H
#define TR_COMMON_H
#include "../qcommon/q_shared.h"
#include "../renderercommon/tr_public.h"
#include "qgl.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum
{
IMGTYPE_COLORALPHA, // for color, lightmap, diffuse, and specular
IMGTYPE_NORMAL,
IMGTYPE_NORMALHEIGHT,
IMGTYPE_DELUXE, // normals are swizzled, deluxe are not
} imgType_t;
typedef enum
{
IMGFLAG_NONE = 0x0000,
IMGFLAG_MIPMAP = 0x0001,
IMGFLAG_PICMIP = 0x0002,
IMGFLAG_CUBEMAP = 0x0004,
IMGFLAG_NO_COMPRESSION = 0x0010,
IMGFLAG_NOLIGHTSCALE = 0x0020,
IMGFLAG_CLAMPTOEDGE = 0x0040,
IMGFLAG_GENNORMALMAP = 0x0080,
} imgFlags_t;
typedef struct image_s {
char imgName[MAX_QPATH]; // game path, including extension
int width, height; // source image
int uploadWidth, uploadHeight; // after power of two and picmip but not including clamp to MAX_TEXTURE_SIZE
GLuint texnum; // gl texture binding
int frameUsed; // for texture usage in frame statistics
int internalFormat;
int TMU; // only needed for voodoo2
imgType_t type;
imgFlags_t flags;
struct image_s* next;
int bytesUsed;
int numMipmaps;
qboolean dynamicallyUpdated;
qboolean allowPicmip;
qboolean force32bit;
int wrapClampModeX;
int wrapClampModeY;
int r_sequence;
int UseCount;
} image_t;
// any change in the LIGHTMAP_* defines here MUST be reflected in
// R_FindShader() in tr_bsp.c
#define LIGHTMAP_2D -4 // shader is for 2D rendering
#define LIGHTMAP_BY_VERTEX -3 // pre-lit triangle models
#define LIGHTMAP_WHITEIMAGE -2
#define LIGHTMAP_NONE -1
extern refimport_t ri;
extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared during ref re-init
// These variables should live inside glConfig but can't because of
// compatibility issues to the original ID vms. If you release a stand-alone
// game and your mod uses tr_types.h from this build you can safely move them
// to the glconfig_t struct.
extern qboolean textureFilterAnisotropic;
extern int maxAnisotropy;
extern float displayAspect;
extern qboolean haveClampToEdge;
//
// cvars
//
extern cvar_t *r_stencilbits; // number of desired stencil bits
extern cvar_t *r_depthbits; // number of desired depth bits
extern cvar_t *r_colorbits; // number of desired color bits, only relevant for fullscreen
extern cvar_t *r_texturebits; // number of desired texture bits
extern cvar_t *r_ext_multisample;
// 0 = use framebuffer depth
// 16 = use 16-bit textures
// 32 = use 32-bit textures
// all else = error
extern cvar_t *r_mode; // video mode
extern cvar_t *r_noborder;
extern cvar_t *r_fullscreen;
extern cvar_t *r_ignorehwgamma; // overrides hardware gamma capabilities
extern cvar_t *r_drawBuffer;
extern cvar_t *r_swapInterval;
extern cvar_t *r_allowExtensions; // global enable/disable of OpenGL extensions
extern cvar_t *r_ext_compressed_textures; // these control use of specific extensions
extern cvar_t *r_ext_multitexture;
extern cvar_t *r_ext_compiled_vertex_array;
extern cvar_t *r_ext_texture_env_add;
extern cvar_t *r_ext_texture_filter_anisotropic;
extern cvar_t *r_ext_max_anisotropy;
extern cvar_t *r_stereoEnabled;
extern cvar_t *r_saveFontData;
qboolean R_GetModeInfo( int *width, int *height, float *windowAspect, int mode );
float R_NoiseGet4f( float x, float y, float z, double t );
void R_NoiseInit( void );
image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags );
image_t *R_RefreshImageFile( const char *name, imgType_t type, imgFlags_t flags );
image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgType_t type, imgFlags_t flags, int internalFormat );
void R_IssuePendingRenderCommands( void );
qhandle_t RE_RegisterShaderLightMap( const char *name, int lightmapIndex );
qhandle_t RE_RegisterShader( const char *name );
qhandle_t RE_RegisterShaderNoMip( const char *name );
qhandle_t RE_RegisterShaderFromImage(const char *name, int lightmapIndex, image_t *image, qboolean mipRawImage);
// font stuff
void R_InitFreeType( void );
void R_DoneFreeType( void );
void RE_RegisterFont(const char *fontName, int pointSize, fontInfo_t *font);
/*
=============================================================
IMAGE LOADERS
=============================================================
*/
void R_LoadBMP( const char *name, byte **pic, int *width, int *height );
void R_LoadJPG( const char *name, byte **pic, int *width, int *height );
void R_LoadPCX( const char *name, byte **pic, int *width, int *height );
void R_LoadPNG( const char *name, byte **pic, int *width, int *height );
void R_LoadPVR( const char *name, byte **pic, int *width, int *height );
void R_LoadTGA( const char *name, byte **pic, int *width, int *height );
/*
====================================================================
IMPLEMENTATION SPECIFIC FUNCTIONS
====================================================================
*/
void GLimp_Init( qboolean fixedFunction );
void GLimp_Shutdown( void );
void GLimp_EndFrame( void );
// When something other than the window presents the finished frame - a VR
// compositor reading the eye textures - swapping the window as well presents
// a surface nothing is looking at, and blocks on the display's own refresh
// while doing it. Two presentation paths then run at unrelated rates, which
// shows up as flicker.
void GLimp_SetPresentsToWindow( qboolean presents );
// The renderer's one way of asking for a GL entry point. Everything the
// renderer calls has to come from the same implementation - see
// GLimp_GL4ES_GetProcAddress for what goes wrong when it does not.
void *GLimp_GetProcAddress( const char *name );
// Bind the window's GL context to the calling thread again. The VR layer needs
// one current to give the OpenXR session; see GLimp_MakeCurrent.
qboolean GLimp_MakeCurrent( void );
void GLimp_LogComment( char *comment );
void GLimp_Minimize(void);
void GLimp_SetGamma( unsigned char red[256],
unsigned char green[256],
unsigned char blue[256] );
#ifdef __cplusplus
}
#endif
#endif