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. */
31static void quit(int rc)
32{
33	SDL_Quit();
34	exit(rc);
35}
36
37void* 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
52typedef 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}
72glfuncs;
73
74void 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
97int 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
203int main(int argc, char *argv[])
204{
205	printf("No OpenGL support on this system\n");
206	return 1;
207}
208
209#endif /* HAVE_OPENGL */
210