• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17 #include <stdio.h>
18 #include <string.h>
19 #include <stdlib.h>
20 #include <unistd.h>
21 
22 //#define GL_API
23 //#define GL_APIENTRY
24 
25 #undef ANDROID
26 #include <EGL/egl.h>
27 #include <GLES2/gl2.h>
28 
29 #ifdef __APPLE__
30 extern "C" void * createGLView(void *nsWindowPtr, int x, int y, int width, int height);
31 #endif
32 
33 #undef HAVE_MALLOC_H
34 #include <SDL.h>
35 #include <SDL_syswm.h>
36 
37 
38 #define WINDOW_WIDTH    500
39 #define WINDOW_HEIGHT   500
40 
41 #define TEX_WIDTH 256
42 #define TEX_HEIGHT 256
43 
44 
45 #define F_to_X(d) ((d) > 32767.65535 ? 32767 * 65536 + 65535 :  \
46                (d) < -32768.65535 ? -32768 * 65536 + 65535 : \
47                ((GLfixed) ((d) * 65536)))
48 #define X_to_F(x)  ((float)(x))/65536.0f
49 
50 //#define __FIXED__
51 
52 const char *def_vShaderStr =
53        "attribute vec4 vPosition;   \n"
54        "void main()                 \n"
55        "{                           \n"
56        "   gl_Position = vPosition; \n"
57        "}                           \n";
58 
59 const char *def_fShaderStr =
60        "precision mediump float;                   \n"
61        "void main()                                \n"
62        "{                                          \n"
63 #ifndef __FIXED__
64        " gl_FragColor = vec4(0.2, 0.5, 0.1, 1.0); \n"
65 #else
66        " gl_FragColor = vec4(0.4, 0.3, 0.7, 1.0); \n"
67 #endif
68        "}                                          \n";
69 
70 static EGLint const attribute_list[] = {
71     EGL_RED_SIZE, 1,
72     EGL_GREEN_SIZE, 1,
73     EGL_BLUE_SIZE, 1,
74     EGL_NONE
75 };
76 
genTexture(int width,int height,int comp)77 unsigned char *genTexture(int width, int height, int comp)
78 {
79     unsigned char *img = new unsigned char[width * height * comp];
80     unsigned char *ptr = img;
81     for (int i = 0; i < height; i++) {
82         for (int j = 0; j < width; j++) {
83             unsigned char col = ((i / 8 + j / 8) % 2) * 255 ;
84             for (int c = 0; c < comp; c++) {
85                 *ptr = col; ptr++;
86             }
87         }
88     }
89     return img;
90 }
91 
genRedTexture(int width,int height,int comp)92 unsigned char *genRedTexture(int width, int height, int comp)
93 {
94     unsigned char *img = new unsigned char[width * height * comp];
95         memset(img,0,width*height*comp);
96     unsigned char *ptr = img;
97     for (int i = 0; i < height; i++) {
98         for (int j = 0; j < width; j++) {
99             unsigned char col = ((i / 8 + j / 8) % 2) * 255 ;
100                         *ptr = col;
101                          ptr+=comp;
102         }
103     }
104     return img;
105 }
106 
107 
printUsage(const char * progname)108 void printUsage(const char *progname)
109 {
110     fprintf(stderr, "usage: %s [options]\n", progname);
111     fprintf(stderr, "\t-vs <filename>  - vertex shader to use\n");
112     fprintf(stderr, "\t-fs <filename>  - fragment shader to use\n");
113 }
114 
115 
116 
LoadShader(GLenum type,const char * shaderSrc)117 GLuint LoadShader(GLenum type,const char *shaderSrc)
118 {
119    GLuint shader;
120    GLint compiled;
121    // Create the shader object
122     shader = glCreateShader(type);
123    if(shader == 0)
124        return 0;
125    // Load the shader source
126    glShaderSource(shader, 1, &shaderSrc, NULL);
127     // Compile the shader
128    glCompileShader(shader);
129     // Check the compile status
130    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
131    if(!compiled)
132    {
133        GLint infoLen = 0;
134        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
135        if(infoLen > 1)
136        {
137           char* infoLog = (char*)malloc(sizeof(char) * infoLen);
138           glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
139           printf("Error compiling shader:\n%s\n", infoLog);
140           free(infoLog);
141        }
142        glDeleteShader(shader);
143        return 0;
144    }
145    return shader;
146 }
147 
readShader(const char * fileName)148 const char *readShader(const char *fileName)
149 {
150     FILE *fp = fopen(fileName, "rb");
151     if (!fp) return NULL;
152 
153     int bSize = 1024;
154     int nBufs = 1;
155     char *buf = (char *)malloc(bSize);
156     int n;
157     int len = 0;
158     n = fread(&buf[0], 1, bSize, fp);
159     while( n == bSize ) {
160         len += n;
161         nBufs++;
162         buf = (char *)realloc(buf, bSize * nBufs);
163         n = fread(&buf[len], 1, bSize, fp);
164     }
165     len += n;
166 
167     buf[len] = '\0';
168     return (const char *)buf;
169 }
170 
dumpUniforms(GLuint program)171 void dumpUniforms(GLuint program)
172 {
173     GLint numU;
174     glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numU);
175     printf("==== Program %d has %d active uniforms ===\n", program, numU);
176     char name[512];
177     GLsizei len;
178     GLint size;
179     GLenum type;
180     for (int i=0; i<numU; i++) {
181         glGetActiveUniform(program, i,
182                            512, &len, &size, &type, name);
183         printf("\t%s : type=0x%x size=%d\n", name, type, size);
184     }
185 }
186 
187 ///
188 // Initialize the shader and program object
189 //
Init(const char * vShaderStr,const char * fShaderStr)190 int Init(const char *vShaderStr, const char *fShaderStr)
191 {
192    GLuint vertexShader;
193    GLuint fragmentShader;
194    GLuint programObject;
195    GLint linked;
196   // Load the vertex/fragment shaders
197   vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr);
198   fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fShaderStr);
199   // Create the program object
200   programObject = glCreateProgram();
201   if(programObject == 0)
202      return -1;
203   glAttachShader(programObject, vertexShader);
204   glAttachShader(programObject, fragmentShader);
205   // Bind vPosition to attribute 0
206   glBindAttribLocation(programObject, 0, "vPosition");
207   // Link the program
208   glLinkProgram(programObject);
209   // Check the link status
210   glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
211   if(!linked)
212   {
213      GLint infoLen = 0;
214      glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);
215      if(infoLen > 1)
216      {
217         char* infoLog = (char*)malloc(sizeof(char) * infoLen);
218         glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);
219         printf("Error linking program:\n%s\n", infoLog);
220         free(infoLog);
221      }
222      glDeleteProgram(programObject);
223      return -1;
224   }
225 
226   // dump active uniforms
227   dumpUniforms(programObject);
228 
229   // Store the program object
230 #ifndef __FIXED__
231   glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
232 #else
233   glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
234 #endif
235   return programObject;
236 }
237 
238 
239 ///
240 // Draw a triangle using the shader pair created in Init()
241 //
Draw(EGLDisplay display,EGLSurface surface,int width,int height,GLuint program)242 void Draw(EGLDisplay display,EGLSurface surface,int width,int height,GLuint program)
243 {
244 #ifndef __FIXED__
245    GLfloat vVertices[] = {0.0f, 0.5f, 0.0f,
246                            -0.5f, -0.5f, 0.0f,
247                            0.5f, -0.5f, 0.0f};
248 #else
249 
250    GLfixed vVertices[] = {F_to_X(0.0f), F_to_X(0.5f),F_to_X(0.0f),
251                            F_to_X(-0.5f),F_to_X(-0.5f), F_to_X(0.0f),
252                            F_to_X(0.5f),F_to_X(-0.5f),F_to_X(0.0f)};
253 #endif
254 
255     // Set the viewport
256    glViewport(0, 0,width,height);
257     // Clear the color buffer
258    glClear(GL_COLOR_BUFFER_BIT);
259     // Use the program object
260    glUseProgram(program);
261    // Load the vertex data
262 #ifndef __FIXED__
263    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
264 #else
265    glVertexAttribPointer(0, 3, GL_FIXED, GL_FALSE, 0, vVertices);
266 #endif
267    glEnableVertexAttribArray(0);
268    glDrawArrays(GL_TRIANGLES, 0, 3);
269    eglSwapBuffers(display,surface);
270 }
271 
272 #ifdef _WIN32
parseCmdLine(char * cmdLine,int * argc)273 char **parseCmdLine(char *cmdLine, int *argc)
274 {
275     int argvSize = 10;
276     char **argv = (char **)malloc(argvSize * sizeof(char *));
277     *argc = 0;
278     int i=0;
279     bool prevIsSpace = true;
280     int argStart = 0;
281 
282     argv[(*argc)++] = strdup("playdump");
283 
284     while(cmdLine[i] != '\0') {
285         bool isSpace = (cmdLine[i] == ' ' || cmdLine[i] == '\t');
286         if ( !isSpace && prevIsSpace ) {
287             argStart = i;
288         }
289         else if (isSpace && !prevIsSpace) {
290             cmdLine[i] = '\0';
291             if (*argc >= argvSize) {
292                 argvSize *= 2;
293                 argv = (char **)realloc(argv, argvSize * sizeof(char *));
294             }
295             argv[(*argc)++] = &cmdLine[argStart];
296             argStart = i+1;
297         }
298 
299         prevIsSpace = isSpace;
300         i++;
301     }
302 
303     if (i > argStart) {
304         argv[(*argc)++] = &cmdLine[argStart];
305     }
306     return argv;
307 }
308 #endif
309 
310 #ifdef _WIN32
WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)311 int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
312 #else
313 int main(int argc, char **argv)
314 #endif
315 {
316 #ifdef _WIN32
317     int argc;
318     char **argv = parseCmdLine(lpCmdLine, &argc);
319 #endif
320     const char *vShader = def_vShaderStr;
321     const char *fShader = def_fShaderStr;
322 
323     for (int i=1; i<argc; i++) {
324         if (!strcmp(argv[i],"-vs")) {
325             if (++i >= argc) {
326                 printUsage(argv[0]);
327                 return -1;
328             }
329             vShader = readShader(argv[i]);
330             if (!vShader) {
331                 vShader = def_vShaderStr;
332                 printf("Failed to load vshader %s, using defualt\n", argv[i]);
333             }
334             else {
335                 printf("Using vshader %s\n", argv[i]);
336             }
337         }
338         else if (!strcmp(argv[i],"-fs")) {
339             if (++i >= argc) {
340                 printUsage(argv[0]);
341                 return -1;
342             }
343             fShader = readShader(argv[i]);
344             if (!fShader) {
345                 fShader = def_fShaderStr;
346                 printf("Failed to load fshader %s, using defualt\n", argv[i]);
347             }
348             else {
349                 printf("Using fshader %s\n", argv[i]);
350             }
351         }
352         else {
353             printUsage(argv[0]);
354             return -1;
355         }
356     }
357 
358     #ifdef _WIN32
359         HWND   windowId = NULL;
360     #elif __linux__
361         Window windowId = 0;
362     #elif __APPLE__
363         void* windowId  = NULL;
364     #endif
365 
366         //      // Inialize SDL window
367         //
368         if (SDL_Init(SDL_INIT_NOPARACHUTE | SDL_INIT_VIDEO)) {
369             fprintf(stderr,"SDL init failed: %s\n", SDL_GetError());
370             return -1;
371         }
372 
373         SDL_Surface *surface = SDL_SetVideoMode(WINDOW_WIDTH,WINDOW_HEIGHT, 32, SDL_HWSURFACE);
374         if (surface == NULL) {
375             fprintf(stderr,"Failed to set video mode: %s\n", SDL_GetError());
376             return -1;
377         }
378 
379         SDL_SysWMinfo  wminfo;
380         memset(&wminfo, 0, sizeof(wminfo));
381         SDL_GetWMInfo(&wminfo);
382     #ifdef _WIN32
383         windowId = wminfo.window;
384     #elif __linux__
385         windowId = wminfo.info.x11.window;
386     #elif __APPLE__
387         windowId = createGLView(wminfo.nsWindowPtr,0,0,WINDOW_WIDTH,WINDOW_HEIGHT);
388     #endif
389 
390         int major,minor,num_config;
391         int attrib_list[] ={
392                                 EGL_CONTEXT_CLIENT_VERSION, 2,
393                                 EGL_NONE
394                            };
395         EGLConfig configs[150];
396         EGLSurface egl_surface;
397         EGLContext ctx;
398         EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY);
399         eglInitialize(d,&major,&minor);
400         printf("DISPLAY == %p major =%d minor = %d\n",d,major,minor);
401         eglChooseConfig(d, attribute_list, configs, 150, &num_config);
402         printf("config returned %d\n",num_config);
403         egl_surface = eglCreateWindowSurface(d,configs[0],windowId,NULL);
404         ctx = eglCreateContext(d,configs[0],EGL_NO_CONTEXT,attrib_list);
405         printf("SURFACE == %p CONTEXT == %p\n",egl_surface,ctx);
406         if(eglMakeCurrent(d,egl_surface,egl_surface,ctx)!= EGL_TRUE){
407             printf("make current failed\n");
408             return false;
409         }
410         printf("after make current\n");
411 
412         GLenum err = glGetError();
413         if(err != GL_NO_ERROR) {
414         printf("error before drawing ->>> %d  \n",err);
415         } else {
416         printf("no error before drawing\n");
417         }
418 
419         int program = Init(vShader, fShader);
420         if(program  < 0){
421             printf("failed init shaders\n");
422             return false;
423         }
424 
425         Draw(d,egl_surface,WINDOW_WIDTH,WINDOW_HEIGHT,program);
426 
427                 err = glGetError();
428                 if(err != GL_NO_ERROR)
429             printf("error ->>> %d  \n",err);
430         eglDestroySurface(d,egl_surface);
431         eglDestroyContext(d,ctx);
432 
433 // Just wait until the window is closed
434         SDL_Event ev;
435         while( SDL_WaitEvent(&ev) ) {
436             if (ev.type == SDL_QUIT) {
437                 break;
438             }
439         }
440     return 0;
441 }
442 
443 
444