Home | History | Annotate | Download | only in GLES_V2
      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 
     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 
     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 
    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 
    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 
    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 
    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 //
    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 //
    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
    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
    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