/* * Copyright 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include //#define GL_API //#define GL_APIENTRY #undef ANDROID #include #include #ifdef __APPLE__ extern "C" void * createGLView(void *nsWindowPtr, int x, int y, int width, int height); #endif #undef HAVE_MALLOC_H #include #include #define WINDOW_WIDTH 500 #define WINDOW_HEIGHT 500 #define TEX_WIDTH 256 #define TEX_HEIGHT 256 #define F_to_X(d) ((d) > 32767.65535 ? 32767 * 65536 + 65535 : \ (d) < -32768.65535 ? -32768 * 65536 + 65535 : \ ((GLfixed) ((d) * 65536))) #define X_to_F(x) ((float)(x))/65536.0f //#define __FIXED__ const char *def_vShaderStr = "attribute vec4 vPosition; \n" "void main() \n" "{ \n" " gl_Position = vPosition; \n" "} \n"; const char *def_fShaderStr = "precision mediump float; \n" "void main() \n" "{ \n" #ifndef __FIXED__ " gl_FragColor = vec4(0.2, 0.5, 0.1, 1.0); \n" #else " gl_FragColor = vec4(0.4, 0.3, 0.7, 1.0); \n" #endif "} \n"; static EGLint const attribute_list[] = { EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, EGL_NONE }; unsigned char *genTexture(int width, int height, int comp) { unsigned char *img = new unsigned char[width * height * comp]; unsigned char *ptr = img; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { unsigned char col = ((i / 8 + j / 8) % 2) * 255 ; for (int c = 0; c < comp; c++) { *ptr = col; ptr++; } } } return img; } unsigned char *genRedTexture(int width, int height, int comp) { unsigned char *img = new unsigned char[width * height * comp]; memset(img,0,width*height*comp); unsigned char *ptr = img; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { unsigned char col = ((i / 8 + j / 8) % 2) * 255 ; *ptr = col; ptr+=comp; } } return img; } void printUsage(const char *progname) { fprintf(stderr, "usage: %s [options]\n", progname); fprintf(stderr, "\t-vs - vertex shader to use\n"); fprintf(stderr, "\t-fs - fragment shader to use\n"); } GLuint LoadShader(GLenum type,const char *shaderSrc) { GLuint shader; GLint compiled; // Create the shader object shader = glCreateShader(type); if(shader == 0) return 0; // Load the shader source glShaderSource(shader, 1, &shaderSrc, NULL); // Compile the shader glCompileShader(shader); // Check the compile status glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); if(!compiled) { GLint infoLen = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); if(infoLen > 1) { char* infoLog = (char*)malloc(sizeof(char) * infoLen); glGetShaderInfoLog(shader, infoLen, NULL, infoLog); printf("Error compiling shader:\n%s\n", infoLog); free(infoLog); } glDeleteShader(shader); return 0; } return shader; } const char *readShader(const char *fileName) { FILE *fp = fopen(fileName, "rb"); if (!fp) return NULL; int bSize = 1024; int nBufs = 1; char *buf = (char *)malloc(bSize); int n; int len = 0; n = fread(&buf[0], 1, bSize, fp); while( n == bSize ) { len += n; nBufs++; buf = (char *)realloc(buf, bSize * nBufs); n = fread(&buf[len], 1, bSize, fp); } len += n; buf[len] = '\0'; return (const char *)buf; } void dumpUniforms(GLuint program) { GLint numU; glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numU); printf("==== Program %d has %d active uniforms ===\n", program, numU); char name[512]; GLsizei len; GLint size; GLenum type; for (int i=0; i 1) { char* infoLog = (char*)malloc(sizeof(char) * infoLen); glGetProgramInfoLog(programObject, infoLen, NULL, infoLog); printf("Error linking program:\n%s\n", infoLog); free(infoLog); } glDeleteProgram(programObject); return -1; } // dump active uniforms dumpUniforms(programObject); // Store the program object #ifndef __FIXED__ glClearColor(0.0f, 0.0f, 1.0f, 1.0f); #else glClearColor(1.0f, 0.0f, 0.0f, 1.0f); #endif return programObject; } /// // Draw a triangle using the shader pair created in Init() // void Draw(EGLDisplay display,EGLSurface surface,int width,int height,GLuint program) { #ifndef __FIXED__ GLfloat vVertices[] = {0.0f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f}; #else GLfixed vVertices[] = {F_to_X(0.0f), F_to_X(0.5f),F_to_X(0.0f), F_to_X(-0.5f),F_to_X(-0.5f), F_to_X(0.0f), F_to_X(0.5f),F_to_X(-0.5f),F_to_X(0.0f)}; #endif // Set the viewport glViewport(0, 0,width,height); // Clear the color buffer glClear(GL_COLOR_BUFFER_BIT); // Use the program object glUseProgram(program); // Load the vertex data #ifndef __FIXED__ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices); #else glVertexAttribPointer(0, 3, GL_FIXED, GL_FALSE, 0, vVertices); #endif glEnableVertexAttribArray(0); glDrawArrays(GL_TRIANGLES, 0, 3); eglSwapBuffers(display,surface); } #ifdef _WIN32 char **parseCmdLine(char *cmdLine, int *argc) { int argvSize = 10; char **argv = (char **)malloc(argvSize * sizeof(char *)); *argc = 0; int i=0; bool prevIsSpace = true; int argStart = 0; argv[(*argc)++] = strdup("playdump"); while(cmdLine[i] != '\0') { bool isSpace = (cmdLine[i] == ' ' || cmdLine[i] == '\t'); if ( !isSpace && prevIsSpace ) { argStart = i; } else if (isSpace && !prevIsSpace) { cmdLine[i] = '\0'; if (*argc >= argvSize) { argvSize *= 2; argv = (char **)realloc(argv, argvSize * sizeof(char *)); } argv[(*argc)++] = &cmdLine[argStart]; argStart = i+1; } prevIsSpace = isSpace; i++; } if (i > argStart) { argv[(*argc)++] = &cmdLine[argStart]; } return argv; } #endif #ifdef _WIN32 int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) #else int main(int argc, char **argv) #endif { GLuint ui32Vbo = 0; // Vertex buffer object handle GLuint ui32IndexVbo; GLuint ui32Texture; int nframes = 100; bool immidateMode = false; bool useIndices = false; bool useTexture = true; bool useCompTexture = false; bool useFixed = true; bool usePoints = false; bool useCopy = false; bool useSubCopy = false; #ifdef _WIN32 int argc; char **argv = parseCmdLine(lpCmdLine, &argc); #endif const char *vShader = def_vShaderStr; const char *fShader = def_fShaderStr; for (int i=1; i= argc) { printUsage(argv[0]); return -1; } vShader = readShader(argv[i]); if (!vShader) { vShader = def_vShaderStr; printf("Failed to load vshader %s, using defualt\n", argv[i]); } else { printf("Using vshader %s\n", argv[i]); } } else if (!strcmp(argv[i],"-fs")) { if (++i >= argc) { printUsage(argv[0]); return -1; } fShader = readShader(argv[i]); if (!fShader) { fShader = def_fShaderStr; printf("Failed to load fshader %s, using defualt\n", argv[i]); } else { printf("Using fshader %s\n", argv[i]); } } else { printUsage(argv[0]); return -1; } } #ifdef _WIN32 HWND windowId = NULL; #elif __linux__ Window windowId = NULL; #elif __APPLE__ void* windowId = NULL; #endif // // Inialize SDL window // if (SDL_Init(SDL_INIT_NOPARACHUTE | SDL_INIT_VIDEO)) { fprintf(stderr,"SDL init failed: %s\n", SDL_GetError()); return -1; } SDL_Surface *surface = SDL_SetVideoMode(WINDOW_WIDTH,WINDOW_HEIGHT, 32, SDL_HWSURFACE); if (surface == NULL) { fprintf(stderr,"Failed to set video mode: %s\n", SDL_GetError()); return -1; } SDL_SysWMinfo wminfo; memset(&wminfo, 0, sizeof(wminfo)); SDL_GetWMInfo(&wminfo); #ifdef _WIN32 windowId = wminfo.window; #elif __linux__ windowId = wminfo.info.x11.window; #elif __APPLE__ windowId = createGLView(wminfo.nsWindowPtr,0,0,WINDOW_WIDTH,WINDOW_HEIGHT); #endif int major,minor,num_config; int attrib_list[] ={ EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLConfig configs[150]; EGLSurface egl_surface; EGLContext ctx; EGLDisplay d = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(d,&major,&minor); printf("DISPLAY == %p major =%d minor = %d\n",d,major,minor); eglChooseConfig(d, attribute_list, configs, 150, &num_config); printf("config returned %d\n",num_config); egl_surface = eglCreateWindowSurface(d,configs[0],windowId,NULL); ctx = eglCreateContext(d,configs[0],EGL_NO_CONTEXT,attrib_list); printf("SURFACE == %p CONTEXT == %p\n",egl_surface,ctx); if(eglMakeCurrent(d,egl_surface,egl_surface,ctx)!= EGL_TRUE){ printf("make current failed\n"); return false; } printf("after make current\n"); GLenum err = glGetError(); if(err != GL_NO_ERROR) { printf("error before drawing ->>> %d \n",err); } else { printf("no error before drawing\n"); } int program = Init(vShader, fShader); if(program < 0){ printf("failed init shaders\n"); return false; } Draw(d,egl_surface,WINDOW_WIDTH,WINDOW_HEIGHT,program); err = glGetError(); if(err != GL_NO_ERROR) printf("error ->>> %d \n",err); eglDestroySurface(d,egl_surface); eglDestroyContext(d,ctx); // Just wait until the window is closed SDL_Event ev; while( SDL_WaitEvent(&ev) ) { if (ev.type == SDL_QUIT) { break; } } return 0; }