/* * @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; }
void R_ShutdownPrograms (void) { if (!qglDeleteProgram) return; if (!r_programs->integer) return; for (int i = 0; i < MAX_PROGRAMS; i++) { if (!r_state.programs[i].id) continue; R_ShutdownProgram(&r_state.programs[i]); } }
/* * @brief */ void R_ShutdownPrograms(void) { int32_t i; if (!qglDeleteProgram) return; R_UseProgram(NULL); for (i = 0; i < MAX_PROGRAMS; i++) { if (!r_state.programs[i].id) continue; R_ShutdownProgram(&r_state.programs[i]); } }
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; }