|
1 /* |
|
2 * Small SDL example to demonstrate dynamically loading |
|
3 * OpenGL lib and functions |
|
4 * |
|
5 * (FYI it was supposed to look like snow in the wind or something...) |
|
6 * |
|
7 * Compile with : |
|
8 * gcc testdyngl.c `sdl-config --libs --cflags` -o testdyngl -DHAVE_OPENGL |
|
9 * |
|
10 * You can specify a different OpenGL lib on the command line, i.e. : |
|
11 * ./testdyngl /usr/X11R6/lib/libGL.so.1.2 |
|
12 * or |
|
13 * ./testdyngl /usr/lib/libGL.so.1.0.4496 |
|
14 * |
|
15 */ |
|
16 |
|
17 #include <stdio.h> |
|
18 #include <stdlib.h> |
|
19 |
|
20 #include "SDL.h" |
|
21 |
|
22 #ifdef __MACOS__ |
|
23 #define HAVE_OPENGL |
|
24 #endif |
|
25 |
|
26 #ifdef HAVE_OPENGL |
|
27 |
|
28 #include "SDL_opengl.h" |
|
29 |
|
30 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */ |
|
31 static void quit(int rc) |
|
32 { |
|
33 SDL_Quit(); |
|
34 exit(rc); |
|
35 } |
|
36 |
|
37 void* get_funcaddr(const char* p) |
|
38 { |
|
39 void* f=SDL_GL_GetProcAddress(p); |
|
40 if (f) |
|
41 { |
|
42 return f; |
|
43 } |
|
44 else |
|
45 { |
|
46 printf("Unable to get function pointer for %s\n",p); |
|
47 quit(1); |
|
48 } |
|
49 return NULL; |
|
50 } |
|
51 |
|
52 typedef struct |
|
53 { |
|
54 void(APIENTRY*glBegin)(GLenum); |
|
55 void(APIENTRY*glEnd)(); |
|
56 void(APIENTRY*glVertex3f)(GLfloat, GLfloat, GLfloat); |
|
57 void(APIENTRY*glClearColor)(GLfloat, GLfloat, GLfloat, GLfloat); |
|
58 void(APIENTRY*glClear)(GLbitfield); |
|
59 void(APIENTRY*glDisable)(GLenum); |
|
60 void(APIENTRY*glEnable)(GLenum); |
|
61 void(APIENTRY*glColor4ub)(GLubyte,GLubyte,GLubyte,GLubyte); |
|
62 void(APIENTRY*glPointSize)(GLfloat); |
|
63 void(APIENTRY*glHint)(GLenum,GLenum); |
|
64 void(APIENTRY*glBlendFunc)(GLenum,GLenum); |
|
65 void(APIENTRY*glMatrixMode)(GLenum); |
|
66 void(APIENTRY*glLoadIdentity)(); |
|
67 void(APIENTRY*glOrtho)(GLdouble,GLdouble,GLdouble,GLdouble,GLdouble,GLdouble); |
|
68 void(APIENTRY*glRotatef)(GLfloat,GLfloat,GLfloat,GLfloat); |
|
69 void(APIENTRY*glViewport)(GLint,GLint,GLsizei,GLsizei); |
|
70 void(APIENTRY*glFogf)(GLenum,GLfloat); |
|
71 } |
|
72 glfuncs; |
|
73 |
|
74 void init_glfuncs(glfuncs* f) |
|
75 { |
|
76 f->glBegin=get_funcaddr("glBegin"); |
|
77 f->glEnd=get_funcaddr("glEnd"); |
|
78 f->glVertex3f=get_funcaddr("glVertex3f"); |
|
79 f->glClearColor=get_funcaddr("glClearColor"); |
|
80 f->glClear=get_funcaddr("glClear"); |
|
81 f->glDisable=get_funcaddr("glDisable"); |
|
82 f->glEnable=get_funcaddr("glEnable"); |
|
83 f->glColor4ub=get_funcaddr("glColor4ub"); |
|
84 f->glPointSize=get_funcaddr("glPointSize"); |
|
85 f->glHint=get_funcaddr("glHint"); |
|
86 f->glBlendFunc=get_funcaddr("glBlendFunc"); |
|
87 f->glMatrixMode=get_funcaddr("glMatrixMode"); |
|
88 f->glLoadIdentity=get_funcaddr("glLoadIdentity"); |
|
89 f->glOrtho=get_funcaddr("glOrtho"); |
|
90 f->glRotatef=get_funcaddr("glRotatef"); |
|
91 f->glViewport=get_funcaddr("glViewport"); |
|
92 f->glFogf=get_funcaddr("glFogf"); |
|
93 } |
|
94 |
|
95 #define NB_PIXELS 1000 |
|
96 |
|
97 int main(int argc,char *argv[]) |
|
98 { |
|
99 glfuncs f; |
|
100 int i; |
|
101 SDL_Event event; |
|
102 int done=0; |
|
103 GLfloat pixels[NB_PIXELS*3]; |
|
104 const char *gl_library = NULL; /* Use the default GL library */ |
|
105 |
|
106 if (argv[1]) { |
|
107 gl_library = argv[1]; |
|
108 } |
|
109 |
|
110 if (SDL_Init(SDL_INIT_VIDEO)<0) |
|
111 { |
|
112 printf("Unable to init SDL : %s\n",SDL_GetError()); |
|
113 return(1); |
|
114 } |
|
115 |
|
116 if (SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1)<0) |
|
117 { |
|
118 printf("Unable to set GL attribute : %s\n",SDL_GetError()); |
|
119 quit(1); |
|
120 } |
|
121 |
|
122 if (SDL_GL_LoadLibrary(gl_library)<0) |
|
123 { |
|
124 printf("Unable to dynamically open GL lib : %s\n",SDL_GetError()); |
|
125 quit(1); |
|
126 } |
|
127 |
|
128 if (SDL_SetVideoMode(640,480,0,SDL_OPENGL)==NULL) |
|
129 { |
|
130 printf("Unable to open video mode : %s\n",SDL_GetError()); |
|
131 quit(1); |
|
132 } |
|
133 |
|
134 /* Set the window manager title bar */ |
|
135 SDL_WM_SetCaption( "SDL Dynamic OpenGL Loading Test", "testdyngl" ); |
|
136 |
|
137 init_glfuncs(&f); |
|
138 |
|
139 for(i=0;i<NB_PIXELS;i++) |
|
140 { |
|
141 pixels[3*i]=rand()%250-125; |
|
142 pixels[3*i+1]=rand()%250-125; |
|
143 pixels[3*i+2]=rand()%250-125; |
|
144 } |
|
145 |
|
146 f.glViewport(0,0,640,480); |
|
147 |
|
148 f.glMatrixMode(GL_PROJECTION); |
|
149 f.glLoadIdentity(); |
|
150 f.glOrtho(-100,100,-100,100,-500,500); |
|
151 |
|
152 f.glMatrixMode(GL_MODELVIEW); |
|
153 f.glLoadIdentity(); |
|
154 |
|
155 f.glEnable(GL_DEPTH_TEST); |
|
156 f.glDisable(GL_TEXTURE_2D); |
|
157 f.glEnable(GL_BLEND); |
|
158 f.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
|
159 |
|
160 f.glClearColor(0.0f,0.0f,0.0f,0.0f); |
|
161 f.glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); |
|
162 |
|
163 f.glEnable(GL_POINT_SMOOTH); |
|
164 f.glHint(GL_POINT_SMOOTH_HINT,GL_NICEST); |
|
165 f.glPointSize(5.0f); |
|
166 f.glEnable(GL_FOG); |
|
167 f.glFogf(GL_FOG_START,-500); |
|
168 f.glFogf(GL_FOG_END,500); |
|
169 f.glFogf(GL_FOG_DENSITY,0.005); |
|
170 |
|
171 do |
|
172 { |
|
173 f.glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); |
|
174 |
|
175 f.glRotatef(2.0,1.0,1.0,1.0); |
|
176 f.glRotatef(1.0,0.0,1.0,1.0); |
|
177 |
|
178 f.glColor4ub(255,255,255,255); |
|
179 f.glBegin(GL_POINTS); |
|
180 for(i=0;i<NB_PIXELS;i++) |
|
181 { |
|
182 f.glVertex3f(pixels[3*i],pixels[3*i+1],pixels[3*i+2]); |
|
183 } |
|
184 f.glEnd(); |
|
185 SDL_GL_SwapBuffers(); |
|
186 |
|
187 while(SDL_PollEvent(&event)) |
|
188 { |
|
189 if(event.type & SDL_KEYDOWN) |
|
190 done=1; |
|
191 } |
|
192 |
|
193 SDL_Delay(20); |
|
194 } |
|
195 while(!done); |
|
196 |
|
197 SDL_Quit(); |
|
198 return 0; |
|
199 } |
|
200 |
|
201 #else /* HAVE_OPENGL */ |
|
202 |
|
203 int main(int argc, char *argv[]) |
|
204 { |
|
205 printf("No OpenGL support on this system\n"); |
|
206 return 1; |
|
207 } |
|
208 |
|
209 #endif /* HAVE_OPENGL */ |