/* * @brief */ static r_program_t *R_LoadProgram(const char *name, void(*Init)(void)) { r_program_t *prog; char log[MAX_STRING_CHARS]; uint32_t e; int32_t i; for (i = 0; i < MAX_PROGRAMS; i++) { prog = &r_state.programs[i]; if (!prog->id) break; } if (i == MAX_PROGRAMS) { Com_Warn("MAX_PROGRAMS reached\n"); return NULL; } g_strlcpy(prog->name, name, sizeof(prog->name)); prog->id = qglCreateProgram(); prog->v = R_LoadShader(GL_VERTEX_SHADER, va("%s_vs.glsl", name)); prog->f = R_LoadShader(GL_FRAGMENT_SHADER, va("%s_fs.glsl", name)); if (prog->v) qglAttachShader(prog->id, prog->v->id); if (prog->f) qglAttachShader(prog->id, prog->f->id); qglLinkProgram(prog->id); qglGetProgramiv(prog->id, GL_LINK_STATUS, &e); if (!e) { qglGetProgramInfoLog(prog->id, sizeof(log) - 1, NULL, log); Com_Warn("%s: %s\n", prog->name, log); R_ShutdownProgram(prog); return NULL; } prog->Init = Init; if (prog->Init) { // invoke initialization function R_UseProgram(prog); prog->Init(); R_UseProgram(NULL); } R_GetError(prog->name); return prog; }
/* * R_InitCoronas */ void R_InitCoronas( void ) { int i; r_coronaShader = R_LoadShader( "***r_coronaTexture***", SHADER_TYPE_CORONA, qtrue ); for( i = 0; i < MAX_DLIGHTS; i++ ) { r_coronaSurfs[i] = ST_CORONA; } }
/* * R_InitOcclusionQueries */ void R_InitOcclusionQueries( void ) { meshbuffer_t *meshbuf = &r_occluderMB; if( !r_occlusionShader ) r_occlusionShader = R_LoadShader( "***r_occlusion***", SHADER_OPAQUE_OCCLUDER, qfalse, 0, SHADER_INVALID, NULL ); if( !glConfig.ext.occlusion_query ) return; qglGenQueriesARB( MAX_OQ_TOTAL, r_occlusionQueries ); meshbuf->sortkey = MB_ENTITY2NUM( r_worldent ) | MB_MODEL; meshbuf->shaderkey = r_occlusionShader->sortkey; }
r_program_t* R_LoadProgram (const char* name, programInitFunc_t init, programUseFunc_t use) { r_program_t* prog; unsigned e; int i; /* shaders are deactivated */ if (!r_programs->integer) return nullptr; /* search existing one */ for (i = 0; i < MAX_PROGRAMS; i++) { prog = &r_state.programs[i]; if (Q_streq(prog->name, name)) return prog; } /* search free slot */ for (i = 0; i < MAX_PROGRAMS; i++) { prog = &r_state.programs[i]; if (!prog->id) break; } if (i == MAX_PROGRAMS) { Com_Printf("R_LoadProgram: MAX_PROGRAMS reached.\n"); return nullptr; } Q_strncpyz(prog->name, name, sizeof(prog->name)); prog->id = qglCreateProgram(); prog->v = R_LoadShader(GL_VERTEX_SHADER, va("%s_vs.glsl", name)); prog->f = R_LoadShader(GL_FRAGMENT_SHADER, va("%s_fs.glsl", name)); if (prog->v) qglAttachShader(prog->id, prog->v->id); if (prog->f) qglAttachShader(prog->id, prog->f->id); qglLinkProgram(prog->id); qglGetProgramiv(prog->id, GL_LINK_STATUS, &e); if (!e || !prog->v || !prog->f) { char log[MAX_STRING_CHARS]; qglGetProgramInfoLog(prog->id, sizeof(log) - 1, nullptr, log); Com_Printf("R_LoadProgram: %s: %s\n", prog->name, log); R_ShutdownProgram(prog); return nullptr; } prog->init = init; if (prog->init) { /* invoke initialization function */ R_UseProgram(prog); prog->init(prog); R_UseProgram(nullptr); } prog->use = use; Com_Printf("R_LoadProgram: '%s' loaded.\n", name); return prog; }