Browse Source

ref: gl: add immediate mode shim for psvita

pull/2/head
fgsfds 2 years ago committed by Alibek Omarov
parent
commit
5a3e3b3977
  1. 18
      engine/platform/psvita/sys_psvita.c
  2. 6
      ref/gl/gl_local.h
  3. 6
      ref/gl/gl_opengl.c
  4. 3
      ref/gl/gl_rmain.c
  5. 21
      ref/gl/gl_studio.c
  6. 2
      ref/gl/wscript
  7. 46
      utils/vgl_shim/vgl_shaders/fragment.cg.inc
  8. 49
      utils/vgl_shim/vgl_shaders/vertex.cg.inc
  9. 532
      utils/vgl_shim/vgl_shim.c
  10. 24
      utils/vgl_shim/vgl_shim.h
  11. 25
      utils/vgl_shim/wscript
  12. 3
      wscript

18
engine/platform/psvita/sys_psvita.c

@ -25,22 +25,12 @@ GNU General Public License for more details.
#define DATA_PATH "data/xash3d" #define DATA_PATH "data/xash3d"
// 200MB libc heap, 512K main thread stack, 32MB for loading game DLLs, 8MB vertex pool // 200MB libc heap, 512K main thread stack, 40MB for loading game DLLs
// the rest goes to vitaGL // the rest goes to vitaGL
SceUInt32 sceUserMainThreadStackSize = 512 * 1024; SceUInt32 sceUserMainThreadStackSize = 512 * 1024;
unsigned int _pthread_stack_default_user = 512 * 1024; unsigned int _pthread_stack_default_user = 512 * 1024;
unsigned int _newlib_heap_size_user = 200 * 1024 * 1024; unsigned int _newlib_heap_size_user = 200 * 1024 * 1024;
#define VGL_MEM_THRESHOLD ( 40 * 1024 * 1024 ) #define VGL_MEM_THRESHOLD ( 40 * 1024 * 1024 )
#define VGL_VERTEX_POOL_SIZE ( 4 * 1024 * 1024 )
/* HACK: stubs for GL functions that are missing from vitaGL */
static void glDrawBuffer( GLenum which )
{
/* nada */
}
/* end of GL stubs*/
/* HACKHACK: force-export stuff required by the dynamic libs */ /* HACKHACK: force-export stuff required by the dynamic libs */
@ -73,7 +63,7 @@ static const vrtld_export_t aux_exports[] =
VRTLD_EXPORT_SYMBOL( strchrnul ), VRTLD_EXPORT_SYMBOL( strchrnul ),
VRTLD_EXPORT_SYMBOL( rand ), VRTLD_EXPORT_SYMBOL( rand ),
VRTLD_EXPORT_SYMBOL( srand ), VRTLD_EXPORT_SYMBOL( srand ),
VRTLD_EXPORT_SYMBOL( glDrawBuffer ), VRTLD_EXPORT_SYMBOL( sceGxmMapMemory ), // needed by vgl_shim
VRTLD_EXPORT( "dlopen", vrtld_dlopen ), VRTLD_EXPORT( "dlopen", vrtld_dlopen ),
VRTLD_EXPORT( "dlclose", vrtld_dlclose ), VRTLD_EXPORT( "dlclose", vrtld_dlclose ),
VRTLD_EXPORT( "dlsym", vrtld_dlsym ), VRTLD_EXPORT( "dlsym", vrtld_dlsym ),
@ -112,11 +102,11 @@ void PSVita_Init( void )
Sys_Error( "Could not init vrtld: %s\n", vrtld_dlerror( ) ); Sys_Error( "Could not init vrtld: %s\n", vrtld_dlerror( ) );
} }
// init vitaGL with some memory budget for immediate mode vertices // init vitaGL, leaving some memory for DLL mapping
// TODO: we don't need to do this for ref_soft // TODO: we don't need to do this for ref_soft
vglUseVram( GL_TRUE ); vglUseVram( GL_TRUE );
vglUseExtraMem( GL_TRUE ); vglUseExtraMem( GL_TRUE );
vglInitExtended( VGL_VERTEX_POOL_SIZE, 960, 544, VGL_MEM_THRESHOLD, 0 ); vglInitExtended( 0, 960, 544, VGL_MEM_THRESHOLD, 0 );
} }
void PSVita_Shutdown( void ) void PSVita_Shutdown( void )

6
ref/gl/gl_local.h

@ -35,6 +35,12 @@ GNU General Public License for more details.
#include "gl_export.h" #include "gl_export.h"
#include "wadfile.h" #include "wadfile.h"
#if XASH_PSVITA
int VGL_ShimInit( void );
void VGL_ShimShutdown( void );
void VGL_ShimEndFrame( void );
#endif
#ifndef offsetof #ifndef offsetof
#ifdef __GNUC__ #ifdef __GNUC__
#define offsetof(s,m) __builtin_offsetof(s,m) #define offsetof(s,m) __builtin_offsetof(s,m)

6
ref/gl/gl_opengl.c

@ -755,6 +755,8 @@ void GL_InitExtensionsBigGL( void )
#if XASH_PSVITA #if XASH_PSVITA
// NPOT textures are actually supported, but the extension is not listed in GL_EXTENSIONS // NPOT textures are actually supported, but the extension is not listed in GL_EXTENSIONS
GL_SetExtension( GL_ARB_TEXTURE_NPOT_EXT, true ); GL_SetExtension( GL_ARB_TEXTURE_NPOT_EXT, true );
// init our immediate mode override
VGL_ShimInit();
#endif #endif
} }
#endif #endif
@ -824,6 +826,10 @@ void GL_ClearExtensions( void )
// now all extensions are disabled // now all extensions are disabled
memset( glConfig.extension, 0, sizeof( glConfig.extension )); memset( glConfig.extension, 0, sizeof( glConfig.extension ));
glw_state.initialized = false; glw_state.initialized = false;
#if XASH_PSVITA
// deinit our immediate mode override
VGL_ShimShutdown();
#endif
} }
//======================================================================= //=======================================================================

3
ref/gl/gl_rmain.c

@ -1124,6 +1124,9 @@ R_EndFrame
*/ */
void R_EndFrame( void ) void R_EndFrame( void )
{ {
#if XASH_PSVITA
VGL_ShimEndFrame();
#endif
// flush any remaining 2D bits // flush any remaining 2D bits
R_Set2DMode( false ); R_Set2DMode( false );
gEngfuncs.GL_SwapBuffers(); gEngfuncs.GL_SwapBuffers();

21
ref/gl/gl_studio.c

@ -25,6 +25,14 @@ GNU General Public License for more details.
#define EVENT_CLIENT 5000 // less than this value it's a server-side studio events #define EVENT_CLIENT 5000 // less than this value it's a server-side studio events
#define MAX_LOCALLIGHTS 4 #define MAX_LOCALLIGHTS 4
#if XASH_PSVITA
// save some address space by decreasing .bss size
// we're not gonna be using the array renderer anyway
#define MAXARRAYVERTS 1
#else
#define MAXARRAYVERTS MAXSTUDIOVERTS
#endif
typedef struct typedef struct
{ {
char name[MAX_OSPATH]; char name[MAX_OSPATH];
@ -112,10 +120,10 @@ typedef struct
player_model_t player_models[MAX_CLIENTS]; player_model_t player_models[MAX_CLIENTS];
// drawelements renderer // drawelements renderer
vec3_t arrayverts[MAXSTUDIOVERTS]; vec3_t arrayverts[MAXARRAYVERTS];
vec2_t arraycoord[MAXSTUDIOVERTS]; vec2_t arraycoord[MAXARRAYVERTS];
unsigned short arrayelems[MAXSTUDIOVERTS*6]; unsigned short arrayelems[MAXARRAYVERTS*6];
GLubyte arraycolor[MAXSTUDIOVERTS][4]; GLubyte arraycolor[MAXARRAYVERTS][4];
uint numverts; uint numverts;
uint numelems; uint numelems;
} studio_draw_state_t; } studio_draw_state_t;
@ -150,6 +158,11 @@ void R_StudioInit( void )
r_studio_sort_textures = gEngfuncs.Cvar_Get( "r_studio_sort_textures", "0", FCVAR_GLCONFIG, "change draw order for additive meshes" ); r_studio_sort_textures = gEngfuncs.Cvar_Get( "r_studio_sort_textures", "0", FCVAR_GLCONFIG, "change draw order for additive meshes" );
r_studio_drawelements = gEngfuncs.Cvar_Get( "r_studio_drawelements", "1", FCVAR_GLCONFIG, "use glDrawElements for studiomodels" ); r_studio_drawelements = gEngfuncs.Cvar_Get( "r_studio_drawelements", "1", FCVAR_GLCONFIG, "use glDrawElements for studiomodels" );
#if XASH_PSVITA
// don't do the same array-building work twice since that's what our FFP shim does anyway
gEngfuncs.Cvar_SetValue( "r_studio_drawelements", 0 );
#endif
Matrix3x4_LoadIdentity( g_studio.rotationmatrix ); Matrix3x4_LoadIdentity( g_studio.rotationmatrix );
// g-cont. cvar disabled by Valve // g-cont. cvar disabled by Valve

2
ref/gl/wscript

@ -35,7 +35,7 @@ def build(bld):
libs = [ 'engine_includes' ] libs = [ 'engine_includes' ]
# on PSVita do not link any libraries that are already in the main executable, but add the includes target # on PSVita do not link any libraries that are already in the main executable, but add the includes target
if bld.env.DEST_OS == 'psvita': if bld.env.DEST_OS == 'psvita':
libs += [ 'sdk_includes' ] libs += [ 'sdk_includes', 'vgl_shim' ]
else: else:
libs += [ 'public', 'M' ] libs += [ 'public', 'M' ]

46
utils/vgl_shim/vgl_shaders/fragment.cg.inc

@ -0,0 +1,46 @@
R""(
#if ATTR_TEXCOORD0
uniform sampler2D uTex0 : TEXUNIT0;
#endif
#if ATTR_TEXCOORD1
uniform sampler2D uTex1 : TEXUNIT1;
#endif
#if FEAT_ALPHA_TEST
uniform float uAlphaTest;
#endif
float4 main(
uniform float4 uColor
#if ATTR_COLOR
, float4 vColor : COLOR
#endif
#if ATTR_TEXCOORD0
, float2 vTexCoord0 : TEXCOORD0
#endif
#if ATTR_TEXCOORD1
, float2 vTexCoord1 : TEXCOORD1
#endif
#if ATTR_NORMAL
, float3 vNormal : TEXCOORD2
#endif
) {
#if ATTR_COLOR
float4 c = vColor;
#else
float4 c = uColor;
#endif
#if ATTR_TEXCOORD0
c *= tex2D(uTex0, vTexCoord0);
#endif
#if ATTR_TEXCOORD1
c *= tex2D(uTex1, vTexCoord1);
#endif
#if FEAT_ALPHA_TEST
if (c.a <= uAlphaTest)
discard;
#endif
return c;
}
)""

49
utils/vgl_shim/vgl_shaders/vertex.cg.inc

@ -0,0 +1,49 @@
R""(
// has to be called this for VGL to fill it in automatically
uniform float4x4 gl_ModelViewProjectionMatrix;
void main(
float3 inPosition
#if ATTR_COLOR
, float4 inColor
#endif
#if ATTR_NORMAL
, float3 inNormal
#endif
#if ATTR_TEXCOORD0
, float2 inTexCoord0
#endif
#if ATTR_TEXCOORD1
, float2 inTexCoord1
#endif
, float4 out vPosition : POSITION
#if ATTR_COLOR
, float4 out vColor : COLOR
#endif
#if ATTR_TEXCOORD0
, float2 out vTexCoord0 : TEXCOORD0
#endif
#if ATTR_TEXCOORD1
, float2 out vTexCoord1 : TEXCOORD1
#endif
#if ATTR_NORMAL
, float3 out vNormal : TEXCOORD2
#endif
) {
vPosition = mul(gl_ModelViewProjectionMatrix, float4(inPosition, 1.f));
#if ATTR_COLOR
vColor = inColor;
#endif
#if ATTR_NORMAL
vNormal = inNormal;
#endif
#if ATTR_TEXCOORD0
vTexCoord0 = inTexCoord0;
#endif
#if ATTR_TEXCOORD1
vTexCoord1 = inTexCoord1;
#endif
}
)""

532
utils/vgl_shim/vgl_shim.c

@ -0,0 +1,532 @@
/*
vgl_shim.c - vitaGL custom immediate mode shim
Copyright (C) 2023 fgsfds
This program 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 3 of the License, or
(at your option) any later version.
This program 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.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <vitaGL.h>
#include "port.h"
#include "xash3d_types.h"
#include "cvardef.h"
#include "const.h"
#include "com_model.h"
#include "cl_entity.h"
#include "render_api.h"
#include "protocol.h"
#include "dlight.h"
#include "ref_api.h"
#include "com_strings.h"
#include "vgl_shim.h"
#define MAX_SHADERLEN 4096
#define MAX_PROGS 32
extern ref_api_t gEngfuncs;
enum vgl_attrib_e
{
VGL_ATTR_POS = 0, // 1
VGL_ATTR_COLOR = 1, // 2
VGL_ATTR_TEXCOORD0 = 2, // 4
VGL_ATTR_TEXCOORD1 = 3, // 8
VGL_ATTR_NORMAL = 4, // 16
VGL_ATTR_MAX
};
// continuation of previous enum
enum vgl_flag_e
{
VGL_FLAG_ALPHA_TEST = VGL_ATTR_MAX,
VGL_FLAG_MAX
};
typedef struct
{
GLuint flags;
GLint attridx[VGL_ATTR_MAX];
GLuint glprog;
GLint ucolor;
GLint ualpha;
GLint utex0;
GLint utex1;
} vgl_prog_t;
static const char *vgl_vert_src =
#include "vgl_shaders/vertex.cg.inc"
;
static const char *vgl_frag_src =
#include "vgl_shaders/fragment.cg.inc"
;
static int vgl_init = 0;
static struct
{
GLfloat *attrbuf[VGL_ATTR_MAX];
GLuint cur_flags;
GLint begin;
GLint end;
GLenum prim;
GLfloat color[4];
GLfloat alpharef;
vgl_prog_t progs[MAX_PROGS];
vgl_prog_t *cur_prog;
GLboolean uchanged;
} vgl;
static const int vgl_attr_size[VGL_ATTR_MAX] = { 3, 4, 2, 2, 3 };
static const char *vgl_flag_name[VGL_FLAG_MAX] =
{
"ATTR_POSITION",
"ATTR_COLOR",
"ATTR_TEXCOORD0",
"ATTR_TEXCOORD1",
"ATTR_NORMAL",
"FEAT_ALPHA_TEST",
};
static const char *vgl_attr_name[VGL_ATTR_MAX] =
{
"inPosition",
"inColor",
"inTexCoord0",
"inTexCoord1",
"inNormal",
};
// HACK: borrow alpha test flag from internal vitaGL state
extern GLboolean alpha_test_state;
static GLuint VGL_GenerateShader( const vgl_prog_t *prog, GLenum type )
{
char *shader, shader_buf[MAX_SHADERLEN + 1];
char tmp[256];
int i;
GLint status, len;
GLuint id;
shader = shader_buf;
shader[0] = '\n';
shader[1] = 0;
for ( i = 0; i < VGL_FLAG_MAX; ++i )
{
snprintf( tmp, sizeof( tmp ), "#define %s %d\n", vgl_flag_name[i], prog->flags & ( 1 << i ) );
strncat( shader, tmp, MAX_SHADERLEN );
}
if ( type == GL_FRAGMENT_SHADER )
strncat( shader, vgl_frag_src, MAX_SHADERLEN );
else
strncat( shader, vgl_vert_src, MAX_SHADERLEN );
id = glCreateShader( type );
len = strlen( shader );
glShaderSource( id, 1, (const void *)&shader, &len );
glCompileShader( id );
glGetShaderiv( id, GL_COMPILE_STATUS, &status );
if ( status == GL_FALSE )
{
gEngfuncs.Con_Reportf( S_ERROR "VGL_GenerateShader( 0x%04x, 0x%x ): compile failed:\n", prog->flags, type );
gEngfuncs.Con_Printf( "Shader text:\n%s\n\n", shader );
glDeleteShader( id );
return 0;
}
return id;
}
static vgl_prog_t *VGL_GetProg( const GLuint flags )
{
int i, loc, status;
GLuint vp, fp, glprog;
vgl_prog_t *prog;
// try to find existing prog matching this feature set
if ( vgl.cur_prog && vgl.cur_prog->flags == flags )
return vgl.cur_prog;
for ( i = 0; i < MAX_PROGS; ++i )
{
if ( vgl.progs[i].flags == flags )
return &vgl.progs[i];
else if ( vgl.progs[i].flags == 0 )
break;
}
if ( i == MAX_PROGS )
{
gEngfuncs.Host_Error( "VGL_GetProg(): Ran out of program slots for 0x%04x\n", flags );
return NULL;
}
// new prog; generate shaders
gEngfuncs.Con_DPrintf( S_NOTE "VGL_GetProg(): Generating progs for 0x%04x\n", flags );
prog = &vgl.progs[i];
prog->flags = flags;
vp = VGL_GenerateShader( prog, GL_VERTEX_SHADER );
fp = VGL_GenerateShader( prog, GL_FRAGMENT_SHADER );
if ( !vp || !fp )
{
prog->flags = 0;
return NULL;
}
glprog = glCreateProgram();
glAttachShader( glprog, vp );
glAttachShader( glprog, fp );
loc = 0;
for ( i = 0; i < VGL_ATTR_MAX; ++i )
{
if ( flags & ( 1 << i ) )
{
prog->attridx[i] = loc;
glBindAttribLocation( glprog, loc++, vgl_attr_name[i] );
}
else
{
prog->attridx[i] = -1;
}
}
glLinkProgram( glprog );
glDeleteShader( vp );
glDeleteShader( fp );
glGetProgramiv( glprog, GL_LINK_STATUS, &status );
if ( status == GL_FALSE )
{
gEngfuncs.Con_Reportf( S_ERROR "VGL_GetProg( 0x%04x ): link failed!\n", prog->flags );
prog->flags = 0;
glDeleteProgram( glprog );
return NULL;
}
prog->ucolor = glGetUniformLocation( glprog, "uColor" );
prog->ualpha = glGetUniformLocation( glprog, "uAlphaTest" );
prog->utex0 = glGetUniformLocation( glprog, "uTex0" );
prog->utex1 = glGetUniformLocation( glprog, "uTex1" );
// these never change
if ( prog->utex0 >= 0 )
glUniform1i( prog->utex0, 0 );
if ( prog->utex1 >= 0 )
glUniform1i( prog->utex1, 1 );
prog->glprog = glprog;
gEngfuncs.Con_DPrintf( S_NOTE "VGL_GetProg(): Generated progs for 0x%04x: glprog=%u ucolor=%d ualpha=%d\n", flags, glprog, prog->ucolor, prog->ualpha );
return prog;
}
static vgl_prog_t *VGL_SetProg( const GLuint flags )
{
vgl_prog_t *prog = NULL;
if ( flags && ( prog = VGL_GetProg( flags ) ) )
{
if ( prog != vgl.cur_prog )
{
glUseProgram( prog->glprog );
vgl.uchanged = GL_TRUE;
}
if ( vgl.uchanged )
{
if ( prog->ualpha >= 0 )
glUniform1f( prog->ualpha, vgl.alpharef );
if ( prog->ucolor >= 0 )
glUniform4fv( prog->ucolor, 1, vgl.color );
vgl.uchanged = GL_FALSE;
}
}
else
{
glUseProgram( 0 );
}
vgl.cur_prog = prog;
return prog;
}
int VGL_ShimInit( void )
{
int i;
GLuint total, size;
if ( vgl_init )
return 0;
memset( &vgl, 0, sizeof( vgl ) );
vgl.color[0] = 1.f;
vgl.color[1] = 1.f;
vgl.color[2] = 1.f;
vgl.color[3] = 1.f;
vgl.uchanged = GL_TRUE;
total = 0;
for ( i = 0; i < VGL_ATTR_MAX; ++i )
{
size = VGL_MAX_VERTS * vgl_attr_size[i] * sizeof( GLfloat );
vgl.attrbuf[i] = memalign( 0x100, size );
total += size;
}
VGL_ShimInstall();
gEngfuncs.Con_DPrintf( S_NOTE "VGL_ShimInit(): %u bytes allocated for vertex buffer\n", total );
vgl_init = 1;
return 0;
}
void VGL_ShimShutdown( void )
{
int i;
if ( !vgl_init )
return;
glFinish();
glUseProgram( 0 );
for ( i = 0; i < MAX_PROGS; ++i )
{
if ( vgl.progs[i].flags )
glDeleteProgram( vgl.progs[i].glprog );
}
for ( i = 0; i < VGL_ATTR_MAX; ++i )
free( vgl.attrbuf[i] );
memset( &vgl, 0, sizeof( vgl ) );
vgl_init = 0;
}
void VGL_ShimEndFrame( void )
{
vgl.end = vgl.begin = 0;
}
void VGL_Begin( GLenum prim )
{
int i;
vgl.prim = prim;
vgl.begin = vgl.end;
// pos always enabled
vgl.cur_flags = 1 << VGL_ATTR_POS;
// disable all vertex attrib pointers
for ( i = 0; i < VGL_ATTR_MAX; ++i )
glDisableVertexAttribArray( i );
}
void VGL_End( void )
{
int i;
vgl_prog_t *prog;
GLuint flags = vgl.cur_flags;
GLint count = vgl.end - vgl.begin;
if ( !vgl.prim || !count )
goto _leave; // end without begin
if ( vgl.end > VGL_MAX_VERTS )
{
gEngfuncs.Con_Reportf( S_ERROR "VGL_End(): Ran out of vertex space (%d overhead)\n", vgl.end - VGL_MAX_VERTS );
vgl.end = 0;
goto _leave;
}
// enable alpha test if needed
if ( alpha_test_state )
flags |= 1 << VGL_FLAG_ALPHA_TEST;
prog = VGL_SetProg( flags );
if ( !prog )
{
gEngfuncs.Host_Error( "VGL_End(): Could not find program for flags 0x%04x!\n", flags );
goto _leave;
}
for ( i = 0; i < VGL_ATTR_MAX; ++i )
{
if ( prog->attridx[i] >= 0 )
{
glEnableVertexAttribArray( prog->attridx[i] );
glVertexAttribPointer( prog->attridx[i], vgl_attr_size[i], GL_FLOAT, GL_FALSE, 0, vgl.attrbuf[i] + vgl_attr_size[i] * vgl.begin );
}
}
glDrawArrays( vgl.prim, 0, count );
_leave:
vgl.prim = GL_NONE;
vgl.begin = vgl.end;
vgl.cur_flags = 0;
}
void VGL_Vertex3f( GLfloat x, GLfloat y, GLfloat z )
{
GLfloat *p = vgl.attrbuf[VGL_ATTR_POS] + vgl.end * 3;
*p++ = x;
*p++ = y;
*p++ = z;
++vgl.end;
if ( vgl.end >= VGL_MAX_VERTS )
{
gEngfuncs.Con_Reportf( S_ERROR "VGL_Vertex3f(): Vertex buffer overflow!\n" );
vgl.end = vgl.begin = 0;
}
}
void VGL_Vertex2f( GLfloat x, GLfloat y )
{
VGL_Vertex3f( x, y, 0.f );
}
void VGL_Vertex3fv( const GLfloat *v )
{
VGL_Vertex3f( v[0], v[1], v[2] );
}
void VGL_Color4f( GLfloat r, GLfloat g, GLfloat b, GLfloat a )
{
vgl.color[0] = r;
vgl.color[1] = g;
vgl.color[2] = b;
vgl.color[3] = a;
vgl.uchanged = GL_TRUE;
if ( vgl.prim )
{
// HACK: enable color attribute if we're using color inside a Begin-End pair
GLfloat *p = vgl.attrbuf[VGL_ATTR_COLOR] + vgl.end * 4;
vgl.cur_flags |= 1 << VGL_ATTR_COLOR;
*p++ = r;
*p++ = g;
*p++ = b;
*p++ = a;
}
}
void VGL_Color3f( GLfloat r, GLfloat g, GLfloat b )
{
VGL_Color4f( r, g, b, 1.f );
}
void VGL_Color4ub( GLubyte r, GLubyte g, GLubyte b, GLubyte a )
{
VGL_Color4f( (GLfloat)r / 255.f, (GLfloat)g / 255.f, (GLfloat)b / 255.f, (GLfloat)a / 255.f );
}
void VGL_Color4ubv( const GLubyte *v )
{
VGL_Color4ub( v[0], v[1], v[2], v[3] );
}
void VGL_TexCoord2f( GLfloat u, GLfloat v )
{
// by spec glTexCoord always updates texunit 0
GLfloat *p = vgl.attrbuf[VGL_ATTR_TEXCOORD0] + vgl.end * 2;
vgl.cur_flags |= 1 << VGL_ATTR_TEXCOORD0;
*p++ = u;
*p++ = v;
}
void VGL_MultiTexCoord2f( GLenum tex, GLfloat u, GLfloat v )
{
GLfloat *p;
// assume there can only be two
if ( tex == GL_TEXTURE0 )
{
p = vgl.attrbuf[VGL_ATTR_TEXCOORD0] + vgl.end * 2;
vgl.cur_flags |= 1 << VGL_ATTR_TEXCOORD0;
}
else
{
p = vgl.attrbuf[VGL_ATTR_TEXCOORD1] + vgl.end * 2;
vgl.cur_flags |= 1 << VGL_ATTR_TEXCOORD1;
}
*p++ = u;
*p++ = v;
}
void VGL_Normal3fv( const GLfloat *v )
{
/* not sure if we actually need these */
}
void VGL_ShadeModel( GLenum unused )
{
/* this doesn't do anything in vitaGL except spit errors in debug mode, so stub it out */
}
void VGL_AlphaFunc( GLenum mode, GLfloat ref )
{
vgl.alpharef = ref;
vgl.uchanged = GL_TRUE;
// mode is always GL_GREATER
}
void VGL_DrawBuffer( GLenum mode )
{
/* unsupported */
}
#define VGL_DECLARE_PTR( name ) extern void *pgl ## name
#define VGL_OVERRIDE_PTR( name ) pgl ## name = VGL_ ## name
void VGL_ShimInstall( void )
{
VGL_DECLARE_PTR( Vertex2f );
VGL_DECLARE_PTR( Vertex3f );
VGL_DECLARE_PTR( Vertex3fv );
VGL_DECLARE_PTR( Color3f );
VGL_DECLARE_PTR( Color4f );
VGL_DECLARE_PTR( Color4ub );
VGL_DECLARE_PTR( Color4ubv );
VGL_DECLARE_PTR( Normal3fv );
VGL_DECLARE_PTR( TexCoord2f );
VGL_DECLARE_PTR( MultiTexCoord2f );
VGL_DECLARE_PTR( ShadeModel );
VGL_DECLARE_PTR( DrawBuffer );
VGL_DECLARE_PTR( AlphaFunc );
VGL_DECLARE_PTR( Begin );
VGL_DECLARE_PTR( End );
VGL_OVERRIDE_PTR( Vertex2f );
VGL_OVERRIDE_PTR( Vertex3f );
VGL_OVERRIDE_PTR( Vertex3fv );
VGL_OVERRIDE_PTR( Color3f );
VGL_OVERRIDE_PTR( Color4f );
VGL_OVERRIDE_PTR( Color4ub );
VGL_OVERRIDE_PTR( Color4ubv );
VGL_OVERRIDE_PTR( Normal3fv );
VGL_OVERRIDE_PTR( TexCoord2f );
VGL_OVERRIDE_PTR( MultiTexCoord2f );
VGL_OVERRIDE_PTR( ShadeModel );
VGL_OVERRIDE_PTR( DrawBuffer );
VGL_OVERRIDE_PTR( AlphaFunc );
VGL_OVERRIDE_PTR( Begin );
VGL_OVERRIDE_PTR( End );
}

24
utils/vgl_shim/vgl_shim.h

@ -0,0 +1,24 @@
/*
vgl_shim.h - vitaGL custom immediate mode shim
Copyright (C) 2023 fgsfds
This program 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 3 of the License, or
(at your option) any later version.
This program 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.
*/
#pragma once
// max verts in a single frame
#define VGL_MAX_VERTS 16384
int VGL_ShimInit( void );
void VGL_ShimInstall( void );
void VGL_ShimShutdown( void );
void VGL_ShimEndFrame( void );

25
utils/vgl_shim/wscript

@ -0,0 +1,25 @@
#! /usr/bin/env python
# encoding: utf-8
import os
def options(opt):
pass
def configure(conf):
conf.define('REF_DLL', 1)
def build(bld):
source = bld.path.ant_glob( [ '*.c' ] )
includes = [ '.' ]
libs = [ 'engine_includes', 'sdk_includes' ]
bld.env.LDFLAGS += ['-fPIC']
bld.env.CFLAGS += ['-fPIC']
bld.stlib(
source = source,
target = 'vgl_shim',
features = 'c',
includes = includes,
use = libs,
subsystem = bld.env.MSVC_SUBSYSTEM
)

3
wscript

@ -55,6 +55,9 @@ SUBDIRS = [
# enabled optionally # enabled optionally
Subproject('utils/mdldec', lambda x: x.env.ENABLE_UTILS), Subproject('utils/mdldec', lambda x: x.env.ENABLE_UTILS),
Subproject('utils/run-fuzzer', lambda x: x.env.ENABLE_FUZZER), Subproject('utils/run-fuzzer', lambda x: x.env.ENABLE_FUZZER),
# enabled on PSVita only
Subproject('utils/vgl_shim', lambda x: x.env.DEST_OS == 'psvita'),
] ]
def options(opt): def options(opt):

Loading…
Cancel
Save