gl2_basic.cpp revision 919583553781f1e1885fa17f76d54008ebeca3c1
1/* 2 * Copyright (C) 2007 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 <stdlib.h> 18#include <stdio.h> 19#include <time.h> 20#include <sched.h> 21#include <sys/resource.h> 22 23#include <EGL/egl.h> 24#include <GLES2/gl2.h> 25#include <GLES2/gl2ext.h> 26 27#include <utils/Timers.h> 28 29#include <ui/FramebufferNativeWindow.h> 30#include <ui/EGLUtils.h> 31 32using namespace android; 33 34static void printGLString(const char *name, GLenum s) { 35 // fprintf(stderr, "printGLString %s, %d\n", name, s); 36 const char *v = (const char *) glGetString(s); 37 // int error = glGetError(); 38 // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error, 39 // (unsigned int) v); 40 // if ((v < (const char*) 0) || (v > (const char*) 0x10000)) 41 // fprintf(stderr, "GL %s = %s\n", name, v); 42 // else 43 // fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v); 44 fprintf(stderr, "GL %s = %s\n", name, v); 45} 46 47static const char* eglErrorToString[] = { 48 "EGL_SUCCESS", // 0x3000 12288 49 "EGL_NOT_INITIALIZED", 50 "EGL_BAD_ACCESS", // 0x3002 12290 51 "EGL_BAD_ALLOC", "EGL_BAD_ATTRIBUTE", 52 "EGL_BAD_CONFIG", 53 "EGL_BAD_CONTEXT", // 0x3006 12294 54 "EGL_BAD_CURRENT_SURFACE", "EGL_BAD_DISPLAY", "EGL_BAD_MATCH", 55 "EGL_BAD_NATIVE_PIXMAP", "EGL_BAD_NATIVE_WINDOW", "EGL_BAD_PARAMETER", // 0x300c 12300 56 "EGL_BAD_SURFACE" }; 57 58static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { 59 if (returnVal != EGL_TRUE) { 60 fprintf(stderr, "%s() returned %d\n", op, returnVal); 61 } 62 63 for (EGLint error = eglGetError(); error != EGL_SUCCESS; error 64 = eglGetError()) { 65 const char* errorString = "unknown"; 66 if (error >= EGL_SUCCESS && error <= EGL_BAD_SURFACE) { 67 errorString = eglErrorToString[error - EGL_SUCCESS]; 68 } 69 fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, errorString, 70 error); 71 } 72} 73 74static void checkGlError(const char* op) { 75 for (GLint error = glGetError(); error; error 76 = glGetError()) { 77 fprintf(stderr, "after %s() glError (0x%x)\n", op, error); 78 } 79} 80 81static const char gVertexShader[] = "attribute vec4 vPosition;\n" 82 "void main() {\n" 83 " gl_Position = vPosition;\n" 84 "}\n"; 85 86static const char gFragmentShader[] = "precision mediump float;\n" 87 "void main() {\n" 88 " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n" 89 "}\n"; 90 91GLuint loadShader(GLenum shaderType, const char* pSource) { 92 GLuint shader = glCreateShader(shaderType); 93 if (shader) { 94 glShaderSource(shader, 1, &pSource, NULL); 95 glCompileShader(shader); 96 GLint compiled = 0; 97 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 98 if (!compiled) { 99 GLint infoLen = 0; 100 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 101 if (infoLen) { 102 char* buf = (char*) malloc(infoLen); 103 if (buf) { 104 glGetShaderInfoLog(shader, infoLen, NULL, buf); 105 fprintf(stderr, "Could not compile shader %d:\n%s\n", 106 shaderType, buf); 107 free(buf); 108 } 109 glDeleteShader(shader); 110 shader = 0; 111 } 112 } 113 } 114 return shader; 115} 116 117GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) { 118 GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); 119 if (!vertexShader) { 120 return 0; 121 } 122 123 GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); 124 if (!pixelShader) { 125 return 0; 126 } 127 128 GLuint program = glCreateProgram(); 129 if (program) { 130 glAttachShader(program, vertexShader); 131 checkGlError("glAttachShader"); 132 glAttachShader(program, pixelShader); 133 checkGlError("glAttachShader"); 134 glLinkProgram(program); 135 GLint linkStatus = GL_FALSE; 136 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 137 if (linkStatus != GL_TRUE) { 138 GLint bufLength = 0; 139 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 140 if (bufLength) { 141 char* buf = (char*) malloc(bufLength); 142 if (buf) { 143 glGetProgramInfoLog(program, bufLength, NULL, buf); 144 fprintf(stderr, "Could not link program:\n%s\n", buf); 145 free(buf); 146 } 147 } 148 glDeleteProgram(program); 149 program = 0; 150 } 151 } 152 return program; 153} 154 155GLuint gProgram; 156GLuint gvPositionHandle; 157 158bool setupGraphics(int w, int h) { 159 gProgram = createProgram(gVertexShader, gFragmentShader); 160 if (!gProgram) { 161 return false; 162 } 163 gvPositionHandle = glGetAttribLocation(gProgram, "vPosition"); 164 checkGlError("glGetAttribLocation"); 165 fprintf(stderr, "glGetAttribLocation(\"vPosition\") = %d\n", 166 gvPositionHandle); 167 168 glViewport(0, 0, w, h); 169 checkGlError("glViewport"); 170 return true; 171} 172 173const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f, 174 0.5f, -0.5f }; 175 176void renderFrame() { 177 glClearColor(0.0f, 0.0f, 1.0f, 1.0f); 178 checkGlError("glClearColor"); 179 glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 180 checkGlError("glClear"); 181 182 glUseProgram(gProgram); 183 checkGlError("glUseProgram"); 184 185 glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices); 186 checkGlError("glVertexAttribPointer"); 187 glEnableVertexAttribArray(gvPositionHandle); 188 checkGlError("glEnableVertexAttribArray"); 189 glDrawArrays(GL_TRIANGLES, 0, 3); 190 checkGlError("glDrawArrays"); 191} 192 193int main(int argc, char** argv) { 194 EGLBoolean returnValue; 195 EGLConfig configs[2]; 196 EGLint config_count; 197 198 EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; 199 EGLint s_configAttribs[] = { EGL_BUFFER_SIZE, EGL_DONT_CARE, EGL_RED_SIZE, 200 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 8, 201 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; 202 203 EGLint s_configAttribs2[] = 204 { 205 EGL_DEPTH_SIZE, 16, 206 EGL_NONE 207 }; 208 209 EGLint majorVersion; 210 EGLint minorVersion; 211 EGLContext context; 212 EGLSurface surface; 213 EGLint w, h; 214 215 EGLDisplay dpy; 216 217 EGLNativeWindowType window = 0; 218 window = android_createDisplaySurface(); 219 220 checkEglError("<init>"); 221 dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 222 checkEglError("eglGetDisplay"); 223 if (dpy == EGL_NO_DISPLAY) { 224 printf("eglGetDisplay returned EGL_NO_DISPLAY.\n"); 225 return 0; 226 } 227 228 returnValue = eglInitialize(dpy, &majorVersion, &minorVersion); 229 checkEglError("eglInitialize", returnValue); 230 fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion); 231 if (returnValue != EGL_TRUE) { 232 printf("eglInitialize failed\n"); 233 return 0; 234 } 235 236 returnValue = eglGetConfigs(dpy, configs, 2, &config_count); 237 checkEglError("eglGetConfigs", returnValue); 238 fprintf(stderr, "Config count: %d\n", config_count); 239 for (int i = 0; i < config_count; i++) { 240 fprintf(stderr, "%d: 0x%08x\n", i, (unsigned int) configs[i]); 241 } 242 243#if 0 244 EGLConfig config; 245 EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config); 246 checkEglError("EGLUtils::selectConfigForNativeWindow"); 247#else 248 int chooseConfigResult = eglChooseConfig(dpy, s_configAttribs2, configs, 2, 249 &config_count); 250 checkEglError("eglChooseConfig", chooseConfigResult); 251 if (chooseConfigResult != EGL_TRUE) { 252 printf("eglChooseConfig failed\n"); 253 return 0; 254 } 255#endif 256 257 surface = eglCreateWindowSurface(dpy, configs[0], window, NULL); 258 checkEglError("eglCreateWindowSurface"); 259 if (surface == EGL_NO_SURFACE) { 260 printf("gelCreateWindowSurface failed.\n"); 261 return 0; 262 } 263 EGLint gl2_0Attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; 264 265 context = eglCreateContext(dpy, configs[0], EGL_NO_CONTEXT, context_attribs); 266 checkEglError("eglCreateContext"); 267 if (context == EGL_NO_CONTEXT) { 268 printf("eglCreateContext failed\n"); 269 return 0; 270 } 271 eglMakeCurrent(dpy, surface, surface, context); 272 checkEglError("eglMakeCurrent"); 273 eglQuerySurface(dpy, surface, EGL_WIDTH, &w); 274 checkEglError("eglQuerySurface"); 275 eglQuerySurface(dpy, surface, EGL_HEIGHT, &h); 276 checkEglError("eglQuerySurface"); 277 GLint dim = w < h ? w : h; 278 279 fprintf(stderr, "Window dimensions: %d x %d\n", w, h); 280 281 printGLString("Version", GL_VERSION); 282 printGLString("Vendor", GL_VENDOR); 283 printGLString("Renderer", GL_RENDERER); 284 printGLString("Extensions", GL_EXTENSIONS); 285 286 if(!setupGraphics(w, h)) { 287 fprintf(stderr, "Could not set up graphics.\n"); 288 return 0; 289 } 290 291 for (;;) { 292 renderFrame(); 293 eglSwapBuffers(dpy, surface); 294 checkEglError("eglSwapBuffers"); 295 } 296 297 return 0; 298} 299