This mainly targets OpenGL ES 2.0 but it also supports compiling GLSL as
ESSL 3.00. It's missing support for framebuffer objects which should be
possible on ES 2. (Though using renderbuffers instead of textures.)
opengl1 cvars that are not supported will display a message and disable
the cvar. This has not been reviewed for new opengl2 cvars. Enabling
cvars may cause rendering issues. Some of the broken cvars may be
possible to support using OpenGL ES 3 features.
The game displays okay with the default cvars.
Don't draw the world scene to a separate FBO from the rest of the
screen.
This fixes the world scene having HOM instead of seeing through to the
previously drawn content. World of Padman uses this to have a separate
3D scene for the sky and world in wop_padship for dynamic skybox.
This also makes r_ext_framebuffer_multisample apply to HUD models
instead of depending on r_ext_multisample (which doesn't work on Linux
with some Intel graphics).
When r_ext_framebuffer_multisample > 0 was used, flares behind the
mirror in q3tourney6 were incorrectly visible. This was because it
checks scene depth in the depth prepass which only drew opaque
surfaces. It also needs to contain depth for mirror/portal surfaces.
tcGen environment generates texcoords in range of 0.0 to 1.0 and they
need to be offset to the position/size in the merged lightmap atlas.
This also needs to be after tcMods so they apply for the original range.
This fixes tcMod scale used by main_q3abanner and shinygrate1_4.
This issue was visible on the blue monitor (comp3c) near the plasmagun
in q3dm0 and the Quake III Arena banner in q3dm17.
Affected shaders in Quake 3 and Team Arena maps:
textures/base_wall/comp3
textures/base_wall/comp3b
textures/base_wall/comp3b_dark
textures/base_wall/comp3c
textures/base_wall/main_q3abanner
textures/base_wall/shinygrate1_4
textures/sfx/teslacoil
All of the shaders are used by q3dm0 but other maps also use some.
This fixes the texcoord range to be 0.0 to 1.0 for external lightmaps in
shaders that also have an internal lightmap. (Instead of 2.0 to 3.0 for
example.) This only affects clampMap as repeating wrapping sampled the
correct location. I haven't found such a shader but I need to get real
lightmap index for future merged lightmap hacks.
Using r_drawSunRays 1, r_hdr 0, cg_viewsize 50 caused the sun rays to
only draw properly in the bottom right quarter of the world viewport.
The scissor rectangle for the world viewport was applied to the first
FBO_FastBlit() in RB_SunRays().
Set glScissor() in FBO_FastBlit() as it's done in FBO_Blit() and
FBO_BlitFromTexture(). Sun rays probably worked correctly with r_hdr 1
because the blit for HDR changed the scissor state.
Shader stage tcMods for matrix and turb effects need to be applied in
order for turb to be correct and all tcMod turb need to be applied
instead of only the last one.
Quake 3's textures/liquids/slime1 had tcMod turb and then tcMod scale.
OpenGL2 applied the matrix first and then turb which had the wrong result.
If mapLightScale and shadowScale weren't included at the end of
q3gl2_sun, the next shader line was skipped by SkipRestOfLine().
COM_ParseExt() with allowLineBreaks=qfalse, returns "" once and
then goes to the next line anyway. (Doesn't work well multiple
"optional" tokens. It looks like a vanilla bug.)
Fixes World of Padman wop_trashmap.
For r_mergeLightmaps 1
- Fix tcMod transform on "map $lightmap" stages
- Fix external lightmap image texcoords if shader also has an internal
lightmap
For r_sunlightMode 1
- Fix "tcGen lightmap" stages with blendFunc GL_SRC_ALPHA GL_ONE being
converted to white image + modulate lightmap and drawing incorrectly
Generating cubemaps set backEnd.viewParms.isMirror = qtrue while the
loading screen said 'loading... maps/q3dm1.bsp' and it just stayed like
that until done loading (no additional messages or item icons) because
all 2D drawing was culled due to flipped culling for isMirror.
This was noticed because a recent commit fixed RB_ShowImages() to be
drawn to the screen instead of draw into renderFbo and never blit to
the screen. Now the loading screen draws over it as expected.
Mentioned commit: a81df34905
"OpenGL2: Fix border for cg_viewsize using HDR/FB-MSAA w/postProcess"
Fix r_ext_framebuffer_multisample > 0 causing the screen to always be
solid black when using AMD Windows driver.
The AMD Windows driver requires binding renderbuffer for it to be valid.
The OpenGL2 renderer uses GL_EXT_direct_state_access that shouldn't
require this. It would be required for Core/GL_ARB_direct_state_access.
It seems like a driver bug.
If using renderFBO (r_hdr 1 or r_ext_framebuffer_multisample > 0) and
r_postProcess 1, the viewport border (cg_viewsize < 100) which is drawn
before the world scene was drawn to the renderFBO but not copied to the
default framebuffer.
Now 2D before the world scene is drawn to the default framebuffer
directly for r_postProcess 1 like 2D drawn after the world scene.
GL_DEPTH_TEXTURE_MODE defaults to GL_LUMINANCE. Code sets it here as
part of a workaround old nvidia drivers (apparently? the URL in comment
is dead). GL_DEPTH_TEXTURE_MODE was removed in OpenGL 3.0 / 3.2 Core
contexts and may be treated as an error.
Printing GL_EXTENSIONS list might be cut off for OpenGL contexts
before 3.0 due to glConfig.extensions_string being a limited length.
Instead get the full extensions list directly.
This was already fixed for OpenGL 3.0 and later contexts.
Using LUMINANCE with OpenGL 3.2 Core contex results in all images being
solid black (in the menu, world, and the console). In the end the whole
screen was solid black except the intro video.
Store images in RGB and RGBA instead. This doesn't affect r_grayscale
visually. If there is issues with it now possibly using compressed
formats, then it would already be an issue for r_grayscale 0.9.
GL_CLAMP (clamp to border) was changed to GL_CLAMP_TO_EDGE in 2008
(f2baf359). In 2018 (ce1d5406) I made OpenGL 1.2 be required since
GL_CLAMP_TO_EDGE is used.
Restore support for GL_CLAMP in order to support OpenGL 1.1 like vanilla
Quake 3 does. This should allow using the default Microsoft Windows
GDI Generic OpenGL 1.1 driver (untested but it won't fail the version
check at least).
From gpuinfo.org, it looks like drivers stopped advertising support for
GL_SGIS_texture_edge_clamp so use a version check in addition to the
extension check.
r_allowExtensions 0 disables using GL_CLAMP_TO_EDGE in the opengl1
renderer. GL_CLAMP support wasn't added to the opengl2 renderer.
For lerped frames (refEntity_t frame not equal oldframe) IQM joint
matrices may have incorrect axis scale. This can cause significant model
distortion. The matrix lerp is linear causing each vector to move in a
straight line between frames instead of arcing like a circle. Each joint
frame can have a different scale so can't just normalize the joint
matrix.
Store joints as quaternions and spherical lerp between them and then
convert to a matrix. For my test model, setting up the skeleton is four
times slower now but it still seems to be fast enough to be usable.
r_cubeMapping requires textureCubeLod() which is only in OpenGL 3.0
(GLSL 1.30) and later. It's not in OpenGL ES 3.0 / GLSL ES 3.00.
This needs to be checked before R_InitImages() so can't just check in
GLSL_InitGPUShaders().
Bounds are optional for animated IQM models but are not possible to
include with unanimated models (seems intended for use with separate
model containing animations and bounds). Calculating bounds for
unanimated IQM models fixes culling and head model on HUD which
calculates position from model bounds.
The axis returned for IQM tag was the animation's joint rotation without
the base frame joint rotation. It only worked correct for models that
did not rotate the base frame joints.
Using GPU vertex skinning is significantly faster than CPU vertex
skinning. Especially since OpenGL2 has to run R_VaoPackNormal() and
R_VaoPackTangent() each vertex each frame which causes CPU vertex
skinning to be significantly slower than OpenGL1 renderer.
Only calculate vertex blend matrix for each unique bone indexes/weights
combination once per-surface instead of recalculating for each vertex.
For best performance the model surfaces needs to use few vertex bone
indexes and weights combinations.
Unroll loops so GCC better optimizes them.
In my tests drawing animated IQM may take 50% as long in opengl1 and
70% as long in opengl2. It will vary by model though and might not
help much at all.
Made unanimated IQM models skip matrix math altogether.
- Only allocate memory for vertex arrays that are present in the IQM
file and are actually used (may not have colors or blend index/weights,
don't load tangents in opengl1). (Colors is fixed to next commit.)
- Explicitly handle loading IQM files without meshes (bones only).
- Better IQM validation. Header data offset 0 mean data is not present
in file. Check if required vertex arrays are present.
This involved a lot of white space changes and moving code around.
Fix two constants in GLSL shaders. Remove f suffix from float and fix
int to float assignment. They were causing shader compile errors in
OpenGL ES 2 context.
Remove disabling clip plane. Clip plane is unused and never enabled in
the opengl2 renderer. Remove disabling it to avoid causing a GL error
when using OpenGL 3.2 core profile or OpenGL ES.
Make VAO cache vertex stride be size of srfVert_t since that is what
is uploaded to the GPU. No behavior change. There is a disabled debug
id in srfVert_t though which if enabled changes srfVert_t size.
OpenGL ES is only required to support unsigned short for element buffer
values.
R_DrawElements() firstIndex argument was glIndex_t which caused element
indexes to wrap around to 0 when glIndex_t is an unsigned short.
(glIndex_t is an index into the vertexes buffer, not element buffer.)
Change it to 'int' like tess.firstIndex which is passed to
R_DrawElements().
World VAO cache buffer size allowed storing more vertexes than unsigned
short glIndex_t could reference. This resulted in the vertex indexes in
the element buffer wrapping around to 0.
Load functions procs supported by OpenGL ES 2.0, though there is not a
compatible renderer yet. Change argument for GLimp_Init from coreContext
to fixedFunction.
Also declare the GL functions in tr_local.h so there is compile error
for non-core GL functions instead of SEGFAULT from dereferencing a NULL
pointer.
Disable the non-functional stencil shadow code that hasn't been updated
to use OpenGL 3.2 core compatible drawing.
If renderer is compiled into client (USE_RENDERER_DLOPEN=0) and after
start up set r_allowExtension to 0 and run vid_restart, some extension
were still used.