1 /*
2  * Copyright 2012 The Emscripten Authors.  All rights reserved.
3  * Emscripten is available under two separate licenses, the MIT license and the
4  * University of Illinois/NCSA Open Source License.  Both these licenses can be
5  * found in the LICENSE file.
6  */
7 
8 /*
9 THIS WORK, INCLUDING THE SOURCE CODE, DOCUMENTATION
10 AND RELATED MEDIA AND DATA, IS PLACED INTO THE PUBLIC DOMAIN.
11 
12 THE ORIGINAL AUTHOR IS KYLE FOLEY.
13 
14 THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY
15 OF ANY KIND, NOT EVEN THE IMPLIED WARRANTY OF
16 MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE,
17 ASSUMES _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE
18 RESULTING FROM THE USE, MODIFICATION, OR
19 REDISTRIBUTION OF THIS SOFTWARE.
20 */
21 
22 #include "SDL/SDL.h"
23 #include "SDL/SDL_opengl.h"
24 
25 #include <stdio.h>
26 #include <string.h>
27 #include <assert.h>
28 
29 // GL_ARB_shading_language_100, GL_ARB_shader_objects, GL_ARB_fragment_shader, GL_ARB_vertex_shader
30 PFNGLCREATEPROGRAMOBJECTARBPROC       glCreateProgramObject_      = NULL;
31 PFNGLDELETEOBJECTARBPROC              glDeleteObject_             = NULL;
32 PFNGLUSEPROGRAMOBJECTARBPROC          glUseProgramObject_         = NULL;
33 PFNGLCREATESHADEROBJECTARBPROC        glCreateShaderObject_       = NULL;
34 PFNGLSHADERSOURCEARBPROC              glShaderSource_             = NULL;
35 PFNGLCOMPILESHADERARBPROC             glCompileShader_            = NULL;
36 PFNGLGETOBJECTPARAMETERIVARBPROC      glGetObjectParameteriv_     = NULL;
37 PFNGLATTACHOBJECTARBPROC              glAttachObject_             = NULL;
38 PFNGLGETINFOLOGARBPROC                glGetInfoLog_               = NULL;
39 PFNGLLINKPROGRAMARBPROC               glLinkProgram_              = NULL;
40 PFNGLGETUNIFORMLOCATIONARBPROC        glGetUniformLocation_       = NULL;
41 PFNGLUNIFORM1FARBPROC                 glUniform1f_                = NULL;
42 PFNGLUNIFORM2FARBPROC                 glUniform2f_                = NULL;
43 PFNGLUNIFORM3FARBPROC                 glUniform3f_                = NULL;
44 PFNGLUNIFORM4FARBPROC                 glUniform4f_                = NULL;
45 PFNGLUNIFORM1FVARBPROC                glUniform1fv_               = NULL;
46 PFNGLUNIFORM2FVARBPROC                glUniform2fv_               = NULL;
47 PFNGLUNIFORM3FVARBPROC                glUniform3fv_               = NULL;
48 PFNGLUNIFORM4FVARBPROC                glUniform4fv_               = NULL;
49 PFNGLUNIFORM1IARBPROC                 glUniform1i_                = NULL;
50 PFNGLBINDATTRIBLOCATIONARBPROC        glBindAttribLocation_       = NULL;
51 PFNGLGETACTIVEUNIFORMARBPROC          glGetActiveUniform_         = NULL;
52 
initARB()53 void initARB() {
54   glCreateProgramObject_ =        (PFNGLCREATEPROGRAMOBJECTARBPROC)     SDL_GL_GetProcAddress("glCreateProgramObjectARB");
55   glDeleteObject_ =               (PFNGLDELETEOBJECTARBPROC)            SDL_GL_GetProcAddress("glDeleteObjectARB");
56   glUseProgramObject_ =           (PFNGLUSEPROGRAMOBJECTARBPROC)        SDL_GL_GetProcAddress("glUseProgramObjectARB");
57   glCreateShaderObject_ =         (PFNGLCREATESHADEROBJECTARBPROC)      SDL_GL_GetProcAddress("glCreateShaderObjectARB");
58   glShaderSource_ =               (PFNGLSHADERSOURCEARBPROC)            SDL_GL_GetProcAddress("glShaderSourceARB");
59   glCompileShader_ =              (PFNGLCOMPILESHADERARBPROC)           SDL_GL_GetProcAddress("glCompileShaderARB");
60   glGetObjectParameteriv_ =       (PFNGLGETOBJECTPARAMETERIVARBPROC)    SDL_GL_GetProcAddress("glGetObjectParameterivARB");
61   glAttachObject_ =               (PFNGLATTACHOBJECTARBPROC)            SDL_GL_GetProcAddress("glAttachObjectARB");
62   glGetInfoLog_ =                 (PFNGLGETINFOLOGARBPROC)              SDL_GL_GetProcAddress("glGetInfoLogARB");
63   glLinkProgram_ =                (PFNGLLINKPROGRAMARBPROC)             SDL_GL_GetProcAddress("glLinkProgramARB");
64   glGetUniformLocation_ =         (PFNGLGETUNIFORMLOCATIONARBPROC)      SDL_GL_GetProcAddress("glGetUniformLocationARB");
65   glUniform1f_ =                  (PFNGLUNIFORM1FARBPROC)               SDL_GL_GetProcAddress("glUniform1fARB");
66   glUniform2f_ =                  (PFNGLUNIFORM2FARBPROC)               SDL_GL_GetProcAddress("glUniform2fARB");
67   glUniform3f_ =                  (PFNGLUNIFORM3FARBPROC)               SDL_GL_GetProcAddress("glUniform3fARB");
68   glUniform4f_ =                  (PFNGLUNIFORM4FARBPROC)               SDL_GL_GetProcAddress("glUniform4fARB");
69   glUniform1fv_ =                 (PFNGLUNIFORM1FVARBPROC)              SDL_GL_GetProcAddress("glUniform1fvARB");
70   glUniform2fv_ =                 (PFNGLUNIFORM2FVARBPROC)              SDL_GL_GetProcAddress("glUniform2fvARB");
71   glUniform3fv_ =                 (PFNGLUNIFORM3FVARBPROC)              SDL_GL_GetProcAddress("glUniform3fvARB");
72   glUniform4fv_ =                 (PFNGLUNIFORM4FVARBPROC)              SDL_GL_GetProcAddress("glUniform4fvARB");
73   glUniform1i_ =                  (PFNGLUNIFORM1IARBPROC)               SDL_GL_GetProcAddress("glUniform1iARB");
74   glBindAttribLocation_ =         (PFNGLBINDATTRIBLOCATIONARBPROC)      SDL_GL_GetProcAddress("glBindAttribLocationARB");
75   glGetActiveUniform_ =           (PFNGLGETACTIVEUNIFORMARBPROC)        SDL_GL_GetProcAddress("glGetActiveUniformARB");
76 }
77 
setShaders()78 void setShaders() {
79   GLuint v, f, p;
80   GLint ok;
81 
82 	const char *vv = "void main()                   \n"
83                    "{                             \n"
84 	                 "  gl_Position = ftransform() + vec4(0.1, -0.25, 0, 0); \n"
85                    "}";
86   const char *ff = "void main()                \n"
87                    "{	                         \n"
88 	                 "  gl_FragColor = vec4(gl_FragCoord.y/480.0, gl_FragCoord.x/640.0, 0.66, 1.0); \n"
89                    "}";
90 
91 	v = glCreateShaderObject_(GL_VERTEX_SHADER);
92 	f = glCreateShaderObject_(GL_FRAGMENT_SHADER);
93 
94 	glShaderSource_(v, 1, &vv,NULL);
95 	glShaderSource_(f, 1, &ff,NULL);
96 
97 	glCompileShader_(v);
98   glGetObjectParameteriv_(v, GL_OBJECT_COMPILE_STATUS_ARB, &ok);
99   if (!ok) {
100     char msg[512];
101     glGetShaderInfoLog(v, sizeof msg, NULL, msg);
102     printf("shader compilation issue: %s\n", msg);
103   }
104   assert(ok);
105 
106 	glCompileShader_(f);
107   glGetObjectParameteriv_(f, GL_OBJECT_COMPILE_STATUS_ARB, &ok);
108   assert(ok);
109 
110 	p = glCreateProgramObject_();
111 	glAttachObject_(p,f);
112 	glAttachObject_(p,v);
113 
114 	glLinkProgram_(p);
115   glGetObjectParameteriv_(p, GL_OBJECT_LINK_STATUS_ARB, &ok);
116   assert(ok);
117 
118 	glUseProgramObject_(p);
119 }
120 
main(int argc,char * argv[])121 int main(int argc, char *argv[])
122 {
123     SDL_Surface *screen;
124 
125     assert(SDL_Init(SDL_INIT_VIDEO) == 0);
126     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
127     screen = SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL );
128     assert(screen);
129 
130     glClearColor(0, 0, 0, 0);
131     glViewport(0, 0, 640, 480);
132     glMatrixMode(GL_PROJECTION);
133     glLoadIdentity();
134     glOrtho(0, 640, 480, 0, -1, 1);
135     glMatrixMode(GL_MODELVIEW);
136     glLoadIdentity();
137     glClear(GL_COLOR_BUFFER_BIT);
138 
139     initARB();
140     setShaders();
141 
142     glColor3f(0, 1, 1); // is overridden by the shader, useful for debugging native builds
143     glBegin( GL_TRIANGLES );
144       glTexCoord2i(0, 0); glVertex3f( 10,  10,  0);
145       glTexCoord2i(1, 0); glVertex3f( 300, 10,  0);
146       glTexCoord2i(1, 1); glVertex3f( 300, 328, 0);
147     glEnd();
148 
149     glColor3f(1, 1, 0); // is overridden by the shader, useful for debugging native builds
150     glBegin( GL_TRIANGLES );
151         glTexCoord2f(0, 0.5); glVertex3f(410, 10,  0);
152         glTexCoord2f(1, 0.5); glVertex3f(600, 10,  0);
153         glTexCoord2f(1, 1  ); glVertex3f(630, 400, 0);
154     glEnd();
155 
156     // Test https://github.com/emscripten-core/emscripten/issues/3693
157     glBegin( GL_TRIANGLES );
158     glEnd();
159 
160     SDL_GL_SwapBuffers();
161 
162 #ifndef __EMSCRIPTEN__
163     SDL_Delay(3000);
164 #endif
165 
166     SDL_Quit();
167     return 0;
168 }
169 
170