rewrote memory system entirely (hunk, cache, and zone are gone, memory pools replaced...
[xonotic/darkplaces.git] / vid_shared.c
1
2 #include "quakedef.h"
3
4 // LordHavoc: these are only set in wgl
5 qboolean isG200 = false; // LordHavoc: the Matrox G200 can't do per pixel alpha, and it uses a D3D driver for GL... ugh...
6 qboolean isRagePro = false; // LordHavoc: the ATI Rage Pro has limitations with per pixel alpha (the color scaler does not apply to per pixel alpha images...), although not as bad as a G200.
7
8 // LordHavoc: GL_ARB_multitexture support
9 int gl_textureunits;
10 // LordHavoc: GL_ARB_texture_env_combine or GL_EXT_texture_env_combine support
11 int gl_combine_extension = false;
12 // LordHavoc: GL_EXT_compiled_vertex_array support
13 int gl_supportslockarrays = false;
14
15 cvar_t vid_mode = {0, "vid_mode", "0"};
16 cvar_t vid_mouse = {CVAR_SAVE, "vid_mouse", "1"};
17 cvar_t vid_fullscreen = {0, "vid_fullscreen", "1"};
18 cvar_t gl_combine = {0, "gl_combine", "1"};
19
20 // GL_ARB_multitexture
21 void (GLAPIENTRY *qglMultiTexCoord2f) (GLenum, GLfloat, GLfloat);
22 void (GLAPIENTRY *qglActiveTexture) (GLenum);
23 void (GLAPIENTRY *qglClientActiveTexture) (GLenum);
24
25 // GL_EXT_compiled_vertex_array
26 void (GLAPIENTRY *qglLockArraysEXT) (GLint first, GLint count);
27 void (GLAPIENTRY *qglUnlockArraysEXT) (void);
28
29 typedef struct
30 {
31         char *name;
32         void **funcvariable;
33 }
34 gl_extensionfunctionlist_t;
35
36 typedef struct
37 {
38         char *name;
39         gl_extensionfunctionlist_t *funcs;
40         int *enablevariable;
41         char *disableparm;
42 }
43 gl_extensioninfo_t;
44
45 static gl_extensionfunctionlist_t multitexturefuncs[] =
46 {
47         {"glMultiTexCoord2fARB", (void **) &qglMultiTexCoord2f},
48         {"glActiveTextureARB", (void **) &qglActiveTexture},
49         {"glClientActiveTextureARB", (void **) &qglClientActiveTexture},
50         {NULL, NULL}
51 };
52
53 static gl_extensionfunctionlist_t compiledvertexarrayfuncs[] =
54 {
55         {"glLockArraysEXT", (void **) &qglLockArraysEXT},
56         {"glUnlockArraysEXT", (void **) &qglUnlockArraysEXT},
57         {NULL, NULL}
58 };
59
60 #ifndef WIN32
61 #include <dlfcn.h>
62 #endif
63
64 static void *prjobj = NULL;
65
66 static void gl_getfuncs_begin(void)
67 {
68 #ifndef WIN32
69         if (prjobj)
70                 dlclose(prjobj);
71
72         prjobj = dlopen(NULL, RTLD_LAZY);
73         if (prjobj == NULL)
74         {
75                 Con_Printf("Unable to open symbol list for main program.\n");
76                 return;
77         }
78 #endif
79 }
80
81 static void gl_getfuncs_end(void)
82 {
83 #ifndef WIN32
84         if (prjobj)
85         {
86                 dlclose(prjobj);
87                 prjobj = NULL;
88         }
89 #endif
90 }
91
92 static void *gl_getfuncaddress(char *name)
93 {
94 #ifdef WIN32
95         return (void *) wglGetProcAddress(func->name);
96 #else
97         return (void *) dlsym(prjobj, name);
98 #endif
99 }
100
101 static int gl_checkextension(char *name, gl_extensionfunctionlist_t *funcs, char *disableparm)
102 {
103         gl_extensionfunctionlist_t *func;
104
105         Con_Printf("checking for %s...  ", name);
106
107         for (func = funcs;func && func->name;func++)
108                 *func->funcvariable = NULL;
109
110         if (disableparm && COM_CheckParm(disableparm))
111         {
112                 Con_Printf("disabled by commandline\n");
113                 return false;
114         }
115
116         if (strstr(gl_extensions, name))
117         {
118                 for (func = funcs;func && func->name != NULL;func++)
119                 {
120                         if (!(*func->funcvariable = (void *) gl_getfuncaddress(func->name)))
121                         {
122                                 Con_Printf("missing function \"%s\"!\n", func->name);
123                                 return false;
124                         }
125                 }
126                 Con_Printf("enabled\n");
127                 return true;
128         }
129         else
130         {
131                 Con_Printf("not detected\n");
132                 return false;
133         }
134 }
135
136 void VID_CheckExtensions(void)
137 {
138         Con_Printf("Checking OpenGL extensions...\n");
139
140         gl_getfuncs_begin();
141
142         gl_combine_extension = false;
143         gl_supportslockarrays = false;
144         gl_textureunits = 1;
145
146         if (gl_checkextension("GL_ARB_multitexture", multitexturefuncs, "-nomtex"))
147         {
148                 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &gl_textureunits);
149                 if (gl_textureunits > 1)
150                         gl_combine_extension = gl_checkextension("GL_ARB_texture_env_combine", NULL, "-nocombine") || gl_checkextension("GL_EXT_texture_env_combine", NULL, "-nocombine");
151                 else
152                         gl_textureunits = 1; // for sanity sake, make sure it's not 0
153         }
154
155         gl_supportslockarrays = gl_checkextension("GL_EXT_compiled_vertex_array", compiledvertexarrayfuncs, "-nocva");
156
157         gl_getfuncs_end();
158 }
159
160 void Force_CenterView_f (void)
161 {
162         cl.viewangles[PITCH] = 0;
163 }
164
165 void VID_InitCvars(void)
166 {
167         Cvar_RegisterVariable(&vid_mode);
168         Cvar_RegisterVariable(&vid_mouse);
169         Cvar_RegisterVariable(&vid_fullscreen);
170         Cvar_RegisterVariable(&gl_combine);
171         Cmd_AddCommand("force_centerview", Force_CenterView_f);
172 }