@@ -456,6 +456,137 @@ static qboolean R_GLSL_LoadProgram(glslProgram_t *program, const char *name, con
456456#endif
457457}
458458
459+ static qboolean R_GLSL_LoadProgramRaw (glslProgram_t * program , const char * name , const char * programVertexObjects , int numVertexObjects , const char * programFragmentObjects , int numFragmentObjects ) {
460+ #ifdef GLSL_BACKEND
461+ GLcharARB * buffer_vp [MAX_PROGRAM_OBJECTS ];
462+ GLcharARB * buffer_fp [MAX_PROGRAM_OBJECTS ];
463+ GLcharARB * buffer ;
464+ GLhandleARB shader_vp ;
465+ GLhandleARB shader_fp ;
466+ GLint status ;
467+ char * str ;
468+ int size = 0 ;
469+ int i ;
470+
471+
472+ /* create program */
473+ program -> program = qglCreateProgramObjectARB ();
474+
475+ /* vertex program */
476+ for (i = 0 , str = (const char * )programVertexObjects ; i < numVertexObjects ; i ++ , str += MAX_QPATH ) {
477+ buffer_vp [i ] = str ;
478+ size += sizeof (str )* 32 ;
479+ if (!buffer_vp [i ]) {
480+ ri .Printf ( PRINT_WARNING , "Couldn't load %s" , str );
481+ return qfalse ;
482+ }
483+
484+ /* compile vertex shader */
485+ shader_vp = qglCreateShaderObjectARB (GL_VERTEX_SHADER_ARB );
486+ qglShaderSourceARB (shader_vp , 1 , (const GLcharARB * * )& buffer_vp , NULL );
487+ qglCompileShaderARB (shader_vp );
488+
489+ /* check for errors in vertex shader */
490+ qglGetObjectParameterivARB (shader_vp , GL_OBJECT_COMPILE_STATUS_ARB , & status );
491+ if (!status ) {
492+ int length ;
493+ char * msg ;
494+
495+ /* print glsl error message */
496+ qglGetObjectParameterivARB (shader_vp , GL_OBJECT_INFO_LOG_LENGTH_ARB , & length );
497+ msg = ri .Hunk_AllocateTempMemory (length );
498+ qglGetInfoLogARB (shader_vp , length , & length , msg );
499+ ri .Printf (PRINT_ALL , "Error:\n%s\n" , msg );
500+ ri .Hunk_FreeTempMemory (msg );
501+
502+ /* exit */
503+ ri .Printf ( PRINT_WARNING , "Couldn't compile vertex shader for program %s" , name );
504+ return qfalse ;
505+ }
506+
507+ /* attach vertex shader to program */
508+ qglAttachObjectARB (program -> program , shader_vp );
509+ qglDeleteObjectARB (shader_vp );
510+ }
511+
512+ /* fragment program */
513+ for (i = 0 , str = (const char * )programFragmentObjects ; i < numFragmentObjects ; i ++ , str += MAX_QPATH ) {
514+ buffer_fp [i ] = str ;
515+ size += sizeof (str )* 32 ;
516+ if (!buffer_fp [i ]) {
517+ ri .Printf ( PRINT_WARNING , "Couldn't load %s" , str );
518+ return qfalse ;
519+ }
520+
521+ /* compile fragment shader */
522+ shader_fp = qglCreateShaderObjectARB (GL_FRAGMENT_SHADER_ARB );
523+ qglShaderSourceARB (shader_fp , 1 , (const GLcharARB * * )& buffer_fp [i ], NULL );
524+ qglCompileShaderARB (shader_fp );
525+
526+ /* check for errors in fragment shader */
527+ qglGetObjectParameterivARB (shader_fp , GL_OBJECT_COMPILE_STATUS_ARB , & status );
528+ if (!status ) {
529+ int length ;
530+ char * msg ;
531+
532+ /* print glsl error message */
533+
534+ qglGetObjectParameterivARB (shader_fp , GL_OBJECT_INFO_LOG_LENGTH_ARB , & length );
535+ msg = ri .Hunk_AllocateTempMemory (length );
536+ qglGetInfoLogARB (shader_fp , length , & length , msg );
537+ ri .Printf (PRINT_ALL , "Error:\n%s\n" , msg );
538+ ri .Hunk_FreeTempMemory (msg );
539+ ri .Printf (PRINT_DEVELOPER , "oops\n" );
540+ /* exit */
541+ ri .Printf ( PRINT_WARNING , "Couldn't compile fragment shader for program %s" , name );
542+ return qfalse ;
543+ }
544+
545+ /* attach fragment shader to program */
546+ qglAttachObjectARB (program -> program , shader_fp );
547+ qglDeleteObjectARB (shader_fp );
548+ }
549+
550+ /* link complete program */
551+ qglLinkProgramARB (program -> program );
552+ /* check for linking errors */
553+ qglGetObjectParameterivARB (program -> program , GL_OBJECT_LINK_STATUS_ARB , & status );
554+ if (!status ) {
555+ int length ;
556+ char * msg ;
557+ /* print glsl error message */
558+ qglGetObjectParameterivARB (program -> program , GL_OBJECT_INFO_LOG_LENGTH_ARB , & length );
559+ msg = ri .Hunk_AllocateTempMemory (length );
560+ qglGetInfoLogARB (program -> program , length , & length , msg );
561+ ri .Printf (PRINT_ALL , "Error:\n%s\n" , msg );
562+ ri .Hunk_FreeTempMemory (msg );
563+
564+ /* exit */
565+ ri .Printf ( PRINT_WARNING , "Couldn't link shaders for program %s" , name );
566+ return qfalse ;
567+ }
568+ /* build single large program file for parsing */
569+ buffer = ri .Hunk_AllocateTempMemory (++ size );
570+
571+ Q_strncpyz (buffer , buffer_vp [0 ], size );
572+
573+ for (i = 1 ; i < numVertexObjects ; i ++ )
574+ strncat (buffer , buffer_vp [i ], size );
575+ for (i = 0 ; i < numFragmentObjects ; i ++ )
576+ strncat (buffer , buffer_fp [i ], size );
577+ /* get uniform locations */
578+ qglUseProgramObjectARB (program -> program );
579+ R_GLSL_ParseProgram (program , buffer );
580+ qglUseProgramObjectARB (0 );
581+ /* clean up */
582+ ri .Hunk_FreeTempMemory (buffer );
583+
584+ return qtrue ;
585+ #endif
586+ }
587+
588+
589+
459590/*
460591 * RE_GLSL_RegisterProgram
461592 * Loads in a program of given name
@@ -514,6 +645,65 @@ qhandle_t RE_GLSL_RegisterProgram(const char *name, const char *programVertexObj
514645}
515646
516647
648+ /*
649+ * RE_GLSL_RegisterProgram
650+ * Loads in a program of given name
651+ */
652+ qhandle_t RE_GLSL_RegisterProgramRaw (const char * name , const char * programVertexObjects , int numVertexObjects , const char * programFragmentObjects , int numFragmentObjects ) {
653+ #ifdef GLSL_BACKEND
654+ glslProgram_t * program ;
655+ qhandle_t hProgram ;
656+
657+ if (!vertexShaders )
658+ return 0 ;
659+
660+ if (!name || !name [0 ]) {
661+ ri .Printf (PRINT_ALL , "RE_GLSL_RegisterProgram: NULL name\n" );
662+ return 0 ;
663+ }
664+
665+ if (strlen (name ) >= MAX_QPATH ) {
666+ Com_Printf ("Program name exceeds MAX_QPATH\n" );
667+ return 0 ;
668+ }
669+
670+ /* search the currently loaded programs */
671+ for (hProgram = 0 ; hProgram < tr .numPrograms ; hProgram ++ ) {
672+ program = tr .programs [hProgram ];
673+ if (!strcmp (program -> name , name )) {
674+ if (!program -> valid )
675+ return 0 ;
676+
677+ return hProgram ;
678+ }
679+ }
680+
681+ /* allocate a new glslProgram_t */
682+ if ((program = R_GLSL_AllocProgram ()) == NULL ) {
683+ ri .Printf (PRINT_WARNING , "RE_GLSL_RegisterProgram: R_GLSL_AllocProgram() failed for '%s'\n" , name );
684+ return 0 ;
685+ }
686+
687+ /* only set the name after the program has successfully loaded */
688+ Q_strncpyz (program -> name , name , sizeof (program -> name ));
689+
690+ R_IssuePendingRenderCommands ();
691+
692+ /* load the files */
693+ if (!R_GLSL_LoadProgramRaw (program , name , (const char * )programVertexObjects , numVertexObjects , (const char * )programFragmentObjects , numFragmentObjects )) {
694+ qglDeleteObjectARB (program -> program );
695+ program -> valid = qfalse ;
696+ //vertexShaders=0; //If program in error disable the glsl feature altogether
697+ return 0 ;
698+ }
699+
700+ program -> valid = qtrue ;
701+ return program -> index ;
702+ #endif
703+ }
704+
705+
706+
517707void R_RemapShader (const char * shaderName , const char * newShaderName , const char * timeOffset ) {
518708 char strippedName [MAX_QPATH ];
519709 int hash ;
0 commit comments