gl2_basic.cpp revision 18e24f952506beebe1eea5672a7dbf60c1040556
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 void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { 48 if (returnVal != EGL_TRUE) { 49 fprintf(stderr, "%s() returned %d\n", op, returnVal); 50 } 51 52 for (EGLint error = eglGetError(); error != EGL_SUCCESS; error 53 = eglGetError()) { 54 fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error), 55 error); 56 } 57} 58 59static void checkGlError(const char* op) { 60 for (GLint error = glGetError(); error; error 61 = glGetError()) { 62 fprintf(stderr, "after %s() glError (0x%x)\n", op, error); 63 } 64} 65 66static const char gVertexShader[] = "attribute vec4 vPosition;\n" 67 "void main() {\n" 68 " gl_Position = vPosition;\n" 69 "}\n"; 70 71static const char gFragmentShader[] = "precision mediump float;\n" 72 "void main() {\n" 73 " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n" 74 "}\n"; 75 76GLuint loadShader(GLenum shaderType, const char* pSource) { 77 GLuint shader = glCreateShader(shaderType); 78 if (shader) { 79 glShaderSource(shader, 1, &pSource, NULL); 80 glCompileShader(shader); 81 GLint compiled = 0; 82 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 83 if (!compiled) { 84 GLint infoLen = 0; 85 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 86 if (infoLen) { 87 char* buf = (char*) malloc(infoLen); 88 if (buf) { 89 glGetShaderInfoLog(shader, infoLen, NULL, buf); 90 fprintf(stderr, "Could not compile shader %d:\n%s\n", 91 shaderType, buf); 92 free(buf); 93 } 94 glDeleteShader(shader); 95 shader = 0; 96 } 97 } 98 } 99 return shader; 100} 101 102GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) { 103 GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); 104 if (!vertexShader) { 105 return 0; 106 } 107 108 GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); 109 if (!pixelShader) { 110 return 0; 111 } 112 113 GLuint program = glCreateProgram(); 114 if (program) { 115 glAttachShader(program, vertexShader); 116 checkGlError("glAttachShader"); 117 glAttachShader(program, pixelShader); 118 checkGlError("glAttachShader"); 119 glLinkProgram(program); 120 GLint linkStatus = GL_FALSE; 121 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 122 if (linkStatus != GL_TRUE) { 123 GLint bufLength = 0; 124 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 125 if (bufLength) { 126 char* buf = (char*) malloc(bufLength); 127 if (buf) { 128 glGetProgramInfoLog(program, bufLength, NULL, buf); 129 fprintf(stderr, "Could not link program:\n%s\n", buf); 130 free(buf); 131 } 132 } 133 glDeleteProgram(program); 134 program = 0; 135 } 136 } 137 return program; 138} 139 140GLuint gProgram; 141GLuint gvPositionHandle; 142 143bool setupGraphics(int w, int h) { 144 gProgram = createProgram(gVertexShader, gFragmentShader); 145 if (!gProgram) { 146 return false; 147 } 148 gvPositionHandle = glGetAttribLocation(gProgram, "vPosition"); 149 checkGlError("glGetAttribLocation"); 150 fprintf(stderr, "glGetAttribLocation(\"vPosition\") = %d\n", 151 gvPositionHandle); 152 153 glViewport(0, 0, w, h); 154 checkGlError("glViewport"); 155 return true; 156} 157 158const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f, 159 0.5f, -0.5f }; 160 161void renderFrame() { 162 glClearColor(0.0f, 0.0f, 1.0f, 1.0f); 163 checkGlError("glClearColor"); 164 glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 165 checkGlError("glClear"); 166 167 glUseProgram(gProgram); 168 checkGlError("glUseProgram"); 169 170 glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices); 171 checkGlError("glVertexAttribPointer"); 172 glEnableVertexAttribArray(gvPositionHandle); 173 checkGlError("glEnableVertexAttribArray"); 174 glDrawArrays(GL_TRIANGLES, 0, 3); 175 checkGlError("glDrawArrays"); 176} 177 178#if 0 179 180void PrintEGLConfig(EGLDisplay dpy, EGLConfig config) { 181 int attrib[] = {EGL_RED_SIZE, EGL_GREEN_SIZE, EGL_BLUE_SIZE, EGL_ALPHA_SIZE, 182 EGL_DEPTH_SIZE, EGL_SURFACE_TYPE, EGL_RENDERABLE_TYPE 183 }; 184 for(size_t i = 0; i < sizeof(attrib)/sizeof(attrib[0]); i++) { 185 int value = 0; 186 int a = attrib[i]; 187 if (eglGetConfigAttrib(dpy, config, a, &value)) { 188 printf(" 0x%04x: %d", a, value); 189 } 190 } 191 printf("\n"); 192} 193 194#endif 195 196int main(int argc, char** argv) { 197 EGLBoolean returnValue; 198 EGLConfig myConfig = {0}; 199 200 EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; 201 EGLint s_configAttribs[] = { 202 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT|EGL_WINDOW_BIT, 203 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 204 EGL_NONE }; 205 EGLint majorVersion; 206 EGLint minorVersion; 207 EGLContext context; 208 EGLSurface surface; 209 EGLint w, h; 210 211 EGLDisplay dpy; 212 213 checkEglError("<init>"); 214 dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 215 checkEglError("eglGetDisplay"); 216 if (dpy == EGL_NO_DISPLAY) { 217 printf("eglGetDisplay returned EGL_NO_DISPLAY.\n"); 218 return 0; 219 } 220 221 returnValue = eglInitialize(dpy, &majorVersion, &minorVersion); 222 checkEglError("eglInitialize", returnValue); 223 fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion); 224 if (returnValue != EGL_TRUE) { 225 printf("eglInitialize failed\n"); 226 return 0; 227 } 228 229 EGLNativeWindowType window = android_createDisplaySurface(); 230 returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig); 231 if (returnValue) { 232 printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue); 233 return 0; 234 } 235 236 surface = eglCreateWindowSurface(dpy, myConfig, window, NULL); 237 checkEglError("eglCreateWindowSurface"); 238 if (surface == EGL_NO_SURFACE) { 239 printf("gelCreateWindowSurface failed.\n"); 240 return 0; 241 } 242 243 context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, context_attribs); 244 checkEglError("eglCreateContext"); 245 if (context == EGL_NO_CONTEXT) { 246 printf("eglCreateContext failed\n"); 247 return 0; 248 } 249 returnValue = eglMakeCurrent(dpy, surface, surface, context); 250 checkEglError("eglMakeCurrent", returnValue); 251 if (returnValue != EGL_TRUE) { 252 return 0; 253 } 254 eglQuerySurface(dpy, surface, EGL_WIDTH, &w); 255 checkEglError("eglQuerySurface"); 256 eglQuerySurface(dpy, surface, EGL_HEIGHT, &h); 257 checkEglError("eglQuerySurface"); 258 GLint dim = w < h ? w : h; 259 260 fprintf(stderr, "Window dimensions: %d x %d\n", w, h); 261 262 printGLString("Version", GL_VERSION); 263 printGLString("Vendor", GL_VENDOR); 264 printGLString("Renderer", GL_RENDERER); 265 printGLString("Extensions", GL_EXTENSIONS); 266 267 if(!setupGraphics(w, h)) { 268 fprintf(stderr, "Could not set up graphics.\n"); 269 return 0; 270 } 271 272 for (;;) { 273 renderFrame(); 274 eglSwapBuffers(dpy, surface); 275 checkEglError("eglSwapBuffers"); 276 } 277 278 return 0; 279} 280