bool BootAnimation::android() { initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png"); initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png"); // clear screen glDisable(GL_DITHER); glDisable(GL_SCISSOR_TEST); glClear(GL_COLOR_BUFFER_BIT); eglSwapBuffers(mDisplay, mSurface); const GLint xc = (mWidth - mAndroid[0].w) / 2; const GLint yc = (mHeight - mAndroid[0].h) / 2; const Rect updateRect(xc, yc, xc + mAndroid[0].w, yc + mAndroid[0].h); // draw and update only what we need mNativeWindowSurface->setSwapRectangle(updateRect.left, updateRect.top, updateRect.width(), updateRect.height()); glScissor(updateRect.left, mHeight - updateRect.bottom, updateRect.width(), updateRect.height()); // Blend state glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); const nsecs_t startTime = systemTime(); do { nsecs_t now = systemTime(); double time = now - startTime; float t = 4.0f * float(time / us2ns(16667)) / mAndroid[1].w; GLint offset = (1 - (t - floorf(t))) * mAndroid[1].w; GLint x = xc - offset; glDisable(GL_SCISSOR_TEST); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_SCISSOR_TEST); glDisable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, mAndroid[1].name); glDrawTexiOES(x, yc, 0, mAndroid[1].w, mAndroid[1].h); glDrawTexiOES(x + mAndroid[1].w, yc, 0, mAndroid[1].w, mAndroid[1].h); glEnable(GL_BLEND); glBindTexture(GL_TEXTURE_2D, mAndroid[0].name); glDrawTexiOES(xc, yc, 0, mAndroid[0].w, mAndroid[0].h); EGLBoolean res = eglSwapBuffers(mDisplay, mSurface); if (res == EGL_FALSE) break; // 12fps: don't animate too fast to preserve CPU const nsecs_t sleepTime = 83333 - ns2us(systemTime() - now); if (sleepTime > 0) usleep(sleepTime); } while (!exitPending()); glDeleteTextures(1, &mAndroid[0].name); glDeleteTextures(1, &mAndroid[1].name); return false; }
static int display_bitmap(PrivInfo* priv, FtkBitmap* bitmap, int x, int y, int width, int height, int xoffset, int yoffset) { GLint crop[4] = {0}; crop[0] = x; crop[1] = y; crop[2] = width; crop[3] = height; if(Android_PreRender() != RET_OK) { return 0; } glColor4f(1,1,1,1); glBindTexture(GL_TEXTURE_2D, 0); glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glEnable(GL_TEXTURE_2D); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ftk_bitmap_width(bitmap), ftk_bitmap_height(bitmap), 0, GL_RGBA, GL_UNSIGNED_BYTE, ftk_bitmap_lock(bitmap)); glDrawTexiOES(xoffset, yoffset, 0, width, height); Android_Render(); return 0; }
int createTexture(AndroidContext *rc) { if (!rc) return 0; if ( rc->texID >= 0 ) releaseTexture(rc); LOG( ANDROID_LOG_INFO, TAG, "Android Create Texture Size: WxH: %dx%d", rc->tex_width, rc->tex_height); glGenTextures( 1, &(rc->texID) ); rc->texData = (GLubyte*)gf_malloc( 4 * rc->tex_width * rc->tex_height ); memset(rc->texData, 255, 4 * rc->tex_width * rc->tex_height ); //memset(data, 0, 4 * width * height/2 ); glBindTexture( GL_TEXTURE_2D, rc->texID); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, rc->tex_width, rc->tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL/*rc->texData*/ ); glBindTexture( GL_TEXTURE_2D, 0); LOG( ANDROID_LOG_VERBOSE, TAG, "Android Create Texture DONE"); return 0; }
void RSTexEnv::set(){ if ( _dataType == X ){ glTexEnvx(GL_TEXTURE_ENV, _pname, _xParam); }else{ glTexEnvf(GL_TEXTURE_ENV, _pname, _fParam); } }
status_t BootAnimation::readyToRun() { mAssets.addDefaultAssets(); DisplayInfo dinfo; status_t status = session()->getDisplayInfo(0, &dinfo); if (status) return -1; // create the native surface sp<Surface> s = session()->createSurface(getpid(), 0, dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565, ISurfaceComposer::eGPU); session()->openTransaction(); s->setLayer(0x40000000); session()->closeTransaction(); // initialize opengl and egl const EGLint attribs[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 0, EGL_NONE }; EGLint w, h, dummy; EGLint numConfigs; EGLConfig config; EGLSurface surface; EGLContext context; EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); eglInitialize(display, 0, 0); eglChooseConfig(display, attribs, &config, 1, &numConfigs); mNativeWindowSurface = new EGLNativeWindowSurface(s); surface = eglCreateWindowSurface(display, config, mNativeWindowSurface.get(), NULL); context = eglCreateContext(display, config, NULL, NULL); eglQuerySurface(display, surface, EGL_WIDTH, &w); eglQuerySurface(display, surface, EGL_HEIGHT, &h); eglMakeCurrent(display, surface, surface, context); mDisplay = display; mContext = context; mSurface = surface; mWidth = w; mHeight = h; mFlingerSurface = s; mAndroidAnimation = false; status_t err = mZip.open("/data/local/bootanimation.zip"); if (err != NO_ERROR) { err = mZip.open("/system/media/bootanimation.zip"); if (err != NO_ERROR) { mAndroidAnimation = true; } } // initialize GL glShadeModel(GL_FLAT); glEnable(GL_TEXTURE_2D); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); return NO_ERROR; }
void video_init(void) { int tex_width, tex_height; GLint crop[4] = { VIDEO_WIDTH, 0, -VIDEO_WIDTH, VIDEO_HEIGHT }; INFO("initializing OpenGL video rendering...\n"); // FIXME: this should be computed (smallest power of 2 > dimension) tex_width = 256; tex_height = 256; otick = 0; if (!pixbuf) { pixbuf = malloc(tex_width * tex_height * 2); assert(pixbuf); //memcpy(pixbuf, default_image, VIDEO_WIDTH*VIDEO_HEIGHT*2); } glEnable(GL_TEXTURE_2D); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glDeleteTextures(1, &texture); glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); // Call glTexImage2D only once, and use glTexSubImage2D later glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex_width, tex_height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixbuf); glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VIDEO_WIDTH, VIDEO_HEIGHT, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, default_image); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glDisable(GL_BLEND); glDisable(GL_DITHER); glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glDisable(GL_CULL_FACE); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glShadeModel(GL_FLAT); glClear(GL_COLOR_BUFFER_BIT); }
/* * Draw a bitmap character */ void FGAPIENTRY glutBitmapCharacterTex(void* fontID, int x, int y, int character) { #if (GL_OES_VERSION_1_1 >= 1) const GLubyte* face; SFG_Font* font = fghFontByID(fontID); GLint v[] = {0, 0, _INT2FIXED(64), _INT2FIXED(64)}; //face[0], font->Height}; GLubyte buff[64*64]; GLuint tid; if(!font) return; if(!(character >= 1)&&(character < 256)) return; /* * Find the character we want to draw (???) */ face = font->Characters[ character - 1 ]; memset(buff, 0, 64*64*sizeof(GLubyte)); BitsToBytes(face+1, face[0], font->Height, buff, 64, 64); glGenTextures(1, &tid); glBindTexture(GL_TEXTURE_2D, tid); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 64, 64, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buff); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glEnable(GL_TEXTURE_2D); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable(GL_ALPHA_TEST); glAlphaFuncx(GL_EQUAL, 0); glTexParameterxv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, v); glDrawTexxOES(_INT2FIXED(x), _INT2FIXED(y), _INT2FIXED(0), _INT2FIXED(16), _INT2FIXED(16)); //face[0], font->Height); glDisable(GL_ALPHA_TEST); glDisable(GL_TEXTURE_2D); glDeleteTextures(1, &tid); #endif }
int initGL(int w_orig, int h_orig) { checkGLVersion(); GLint crop[4] = { 0, h_orig, w_orig, -h_orig }; glBindTexture(GL_TEXTURE_2D, 0); glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glEnable(GL_TEXTURE_2D); glColor4f(1,1,1,1); CHECK_GL_ERROR(); return 1; }
int update() { glClearColor(0.0, 1.0, 0.0, 1.0); glClear( GL_COLOR_BUFFER_BIT ); glRotatef(g->roll, 0.0f, 0.0f, 1.0f); glEnable(GL_TEXTURE_2D); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glBindTexture(GL_TEXTURE_2D, g->clientbuf); glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 ); eglSwapBuffers(g->display, g->surface); g->roll = -0.005; }
void create_texture(void) { const unsigned int on = 0xff0000ff; const unsigned int off = 0xffffffff; const unsigned int pixels[] = { on, off, on, off, on, off, on, off, off, on, off, on, off, on, off, on, on, off, on, off, on, off, on, off, off, on, off, on, off, on, off, on, on, off, on, off, on, off, on, off, off, on, off, on, off, on, off, on, on, off, on, off, on, off, on, off, off, on, off, on, off, on, off, on, }; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); }
/*********************************************************** * Name: redraw_scene * * Arguments: * CUBE_STATE_T *state - holds OGLES model info * * Description: Draws the model and calls eglSwapBuffers * to render to screen * * Returns: void * ***********************************************************/ static void redraw_scene(CUBE_STATE_T *state) { // Start with a clear screen glClear( GL_COLOR_BUFFER_BIT ); glMatrixMode(GL_MODELVIEW); glEnable(GL_TEXTURE_2D); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // Draw first (front) face: // Bind texture surface to current vertices glBindTexture(GL_TEXTURE_2D, state->tex); // Need to rotate textures - do this by rotating each cube face glRotatef(270.f, 0.f, 0.f, 1.f ); // front face normal along z axis // draw first 4 vertices glDrawArrays( GL_TRIANGLE_STRIP, 0, 4); // same pattern for other 5 faces - rotation chosen to make image orientation 'nice' glRotatef(90.f, 0.f, 0.f, 1.f ); // back face normal along z axis glDrawArrays( GL_TRIANGLE_STRIP, 4, 4); glRotatef(90.f, 1.f, 0.f, 0.f ); // left face normal along x axis glDrawArrays( GL_TRIANGLE_STRIP, 8, 4); glRotatef(90.f, 1.f, 0.f, 0.f ); // right face normal along x axis glDrawArrays( GL_TRIANGLE_STRIP, 12, 4); glRotatef(270.f, 0.f, 1.f, 0.f ); // top face normal along y axis glDrawArrays( GL_TRIANGLE_STRIP, 16, 4); glRotatef(90.f, 0.f, 1.f, 0.f ); // bottom face normal along y axis glDrawArrays( GL_TRIANGLE_STRIP, 20, 4); glDisable(GL_TEXTURE_2D); eglSwapBuffers(state->display, state->surface); }
void LayerBase::drawWithOpenGL(const Region& clip, GLint textureName, const GGLSurface& t) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const State& s(drawingState()); // bind our texture validateTexture(textureName); glEnable(GL_TEXTURE_2D); // Dithering... if (s.flags & ISurfaceComposer::eLayerDither) { glEnable(GL_DITHER); } else { glDisable(GL_DITHER); } if (UNLIKELY(s.alpha < 0xFF)) { // We have an alpha-modulation. We need to modulate all // texture components by alpha because we're always using // premultiplied alpha. // If the texture doesn't have an alpha channel we can // use REPLACE and switch to non premultiplied alpha // blending (SRCA/ONE_MINUS_SRCA). GLenum env, src; if (needsBlending()) { env = GL_MODULATE; src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; } else { env = GL_REPLACE; src = GL_SRC_ALPHA; } const GGLfixed alpha = (s.alpha << 16)/255; glColor4x(alpha, alpha, alpha, alpha); glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env); } else { glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glColor4x(0x10000, 0x10000, 0x10000, 0x10000); if (needsBlending()) { GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } if (UNLIKELY(transformed() || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) { //StopWatch watch("GL transformed"); Region::iterator iterator(clip); if (iterator) { // always use high-quality filtering with fast configurations bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG); if (!fast && s.flags & ISurfaceComposer::eLayerFilter) { glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } const GLfixed texCoords[4][2] = { { 0, 0 }, { 0, 0x10000 }, { 0x10000, 0x10000 }, { 0x10000, 0 } }; glMatrixMode(GL_TEXTURE); glLoadIdentity(); if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) { // find the smallest power-of-two that will accommodate our surface GLuint tw = 1 << (31 - clz(t.width)); GLuint th = 1 << (31 - clz(t.height)); if (tw < t.width) tw <<= 1; if (th < t.height) th <<= 1; // this divide should be relatively fast because it's // a power-of-two (optimized path in libgcc) GLfloat ws = GLfloat(t.width) /tw; GLfloat hs = GLfloat(t.height)/th; glScalef(ws, hs, 1.0f); } glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FIXED, 0, mVertices); glTexCoordPointer(2, GL_FIXED, 0, texCoords); Rect r; while (iterator.iterate(&r)) { const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } if (!fast && s.flags & ISurfaceComposer::eLayerFilter) { glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } else { Region::iterator iterator(clip); if (iterator) { Rect r; GLint crop[4] = { 0, t.height, t.width, -t.height }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); int x = tx(); int y = ty(); y = fbHeight - (y + t.height); while (iterator.iterate(&r)) { const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawTexiOES(x, y, 0, t.width, t.height); } } } }
bool BootAnimation::movie() { ZipFileRO& zip(mZip); size_t numEntries = zip.getNumEntries(); ZipEntryRO desc = zip.findEntryByName("desc.txt"); FileMap* descMap = zip.createEntryFileMap(desc); LOGE_IF(!descMap, "descMap is null"); if (!descMap) { return false; } String8 desString((char const*)descMap->getDataPtr(), descMap->getDataLength()); char const* s = desString.string(); Animation animation; // Parse the description file for (;;) { const char* endl = strstr(s, "\n"); if (!endl) break; String8 line(s, endl - s); const char* l = line.string(); int fps, width, height, count, pause; char path[256]; if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) { //LOGD("> w=%d, h=%d, fps=%d", fps, width, height); animation.width = width; animation.height = height; animation.fps = fps; } if (sscanf(l, "p %d %d %s", &count, &pause, path) == 3) { //LOGD("> count=%d, pause=%d, path=%s", count, pause, path); Animation::Part part; part.count = count; part.pause = pause; part.path = path; animation.parts.add(part); } s = ++endl; } // read all the data structures const size_t pcount = animation.parts.size(); for (size_t i=0 ; i<numEntries ; i++) { char name[256]; ZipEntryRO entry = zip.findEntryByIndex(i); if (zip.getEntryFileName(entry, name, 256) == 0) { const String8 entryName(name); const String8 path(entryName.getPathDir()); const String8 leaf(entryName.getPathLeaf()); if (leaf.size() > 0) { for (int j=0 ; j<pcount ; j++) { if (path == animation.parts[j].path) { int method; // supports only stored png files if (zip.getEntryInfo(entry, &method, 0, 0, 0, 0, 0)) { if (method == ZipFileRO::kCompressStored) { FileMap* map = zip.createEntryFileMap(entry); if (map) { Animation::Frame frame; frame.name = leaf; frame.map = map; Animation::Part& part(animation.parts.editItemAt(j)); part.frames.add(frame); } } } } } } } } // clear screen glShadeModel(GL_FLAT); glDisable(GL_DITHER); glDisable(GL_SCISSOR_TEST); glDisable(GL_BLEND); glClear(GL_COLOR_BUFFER_BIT); eglSwapBuffers(mDisplay, mSurface); glBindTexture(GL_TEXTURE_2D, 0); glEnable(GL_TEXTURE_2D); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); const int xc = (mWidth - animation.width) / 2; const int yc = ((mHeight - animation.height) / 2); nsecs_t lastFrame = systemTime(); nsecs_t frameDuration = s2ns(1) / animation.fps; Region clearReg(Rect(mWidth, mHeight)); clearReg.subtractSelf(Region(Rect(xc, yc, xc+animation.width, yc+animation.height))); for (int i=0 ; i<pcount && !exitPending() ; i++) { const Animation::Part& part(animation.parts[i]); const size_t fcount = part.frames.size(); glBindTexture(GL_TEXTURE_2D, 0); for (int r=0 ; !part.count || r<part.count ; r++) { for (int j=0 ; j<fcount && !exitPending(); j++) { const Animation::Frame& frame(part.frames[j]); if (r > 0) { glBindTexture(GL_TEXTURE_2D, frame.tid); } else { if (part.count != 1) { glGenTextures(1, &frame.tid); glBindTexture(GL_TEXTURE_2D, frame.tid); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } initTexture( frame.map->getDataPtr(), frame.map->getDataLength()); } if (!clearReg.isEmpty()) { Rect r; Region::iterator head(clearReg); glEnable(GL_SCISSOR_TEST); while (head.iterate(&r)) { glScissor(r.left, mHeight - r.bottom, r.width(), r.height()); glClear(GL_COLOR_BUFFER_BIT); } glDisable(GL_SCISSOR_TEST); } glDrawTexiOES(xc, yc, 0, animation.width, animation.height); eglSwapBuffers(mDisplay, mSurface); nsecs_t now = systemTime(); nsecs_t delay = frameDuration - (now - lastFrame); lastFrame = now; long wait = ns2us(frameDuration); if (wait > 0) usleep(wait); } usleep(part.pause * ns2us(frameDuration)); } // free the textures for this part if (part.count != 1) { for (int j=0 ; j<fcount ; j++) { const Animation::Frame& frame(part.frames[j]); glDeleteTextures(1, &frame.tid); } } } return false; }
void drawGLScene(AndroidContext *rc) { #ifdef DROID_EXTREME_LOGS LOG( ANDROID_LOG_VERBOSE, TAG, "drawGLScene : start"); #endif /* DROID_EXTREME_LOGS */ #ifdef GPAC_USE_GLES2 GLuint loc_vertex_array, loc_texcoord_array; loc_vertex_array = loc_texcoord_array = -1; #endif GLfloat vertices[4][3]; GLfloat texcoord[4][2]; // int i, j; float rgba[4]; GL_CHECK_ERR // Reset states rgba[0] = rgba[1] = rgba[2] = 0.f; rgba[0] = 1.f; #ifndef GPAC_USE_GLES2 glColor4f(1.f, 1.f, 1.f, 1.f); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, rgba); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, rgba); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, rgba); #endif /* Clear The Screen And The Depth Buffer */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); GL_CHECK_ERR //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); #ifndef GPAC_USE_GLES2 glEnable(GL_TEXTURE_2D); #endif glUseProgram(rc->base_program); glActiveTexture(GL_TEXTURE0); glBindTexture( GL_TEXTURE_2D, rc->texID); GL_CHECK_ERR glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); #ifndef GPAC_USE_GLES2 glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); #endif glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // for ( i = 0; i < rc->height/2; i++ ) // for ( j = 0; j < rc->width; j++ ) // rc->texData[ i*rc->width*NBPP + j*NBPP + 3] = 200; // memset(rc->texData, 255, 4 * rc->width * rc->height ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, rc->tex_width, rc->tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rc->texData ); GL_CHECK_ERR if ( rc->draw_texture ) { GL_CHECK_ERR int cropRect[4] = {0,rc->height,rc->width,-rc->height}; #ifndef GPAC_USE_GLES2 glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); glDrawTexsOES(0, 0, 0, rc->width, rc->height); #endif } else { GL_CHECK_ERR #ifndef GPAC_USE_GLES2 /* Enable VERTEX array */ glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); /* Setup pointer to VERTEX array */ glVertexPointer(3, GL_FLOAT, 0, vertices); glTexCoordPointer(2, GL_FLOAT, 0, texcoord); /* Move Left 1.5 Units And Into The Screen 6.0 */ glLoadIdentity(); #else loc_vertex_array = glGetAttribLocation(rc->base_program, "gfVertex"); if(loc_vertex_array<0) return; glEnableVertexAttribArray(loc_vertex_array); glVertexAttribPointer(loc_vertex_array, 3, GL_FLOAT, GL_FALSE, 0, vertices); loc_texcoord_array = glGetAttribLocation(rc->base_program, "gfTexCoord"); if (loc_texcoord_array>=0) { glVertexAttribPointer(loc_texcoord_array, 2, GL_FLOAT, GL_FALSE, 0, texcoord); glEnableVertexAttribArray(loc_texcoord_array); } #endif //glTranslatef(0.0f, 0.0f, -3.3f); //glTranslatef(0.0f, 0.0f, -2.3f); /* Top Right Of The Quad */ vertices[0][0]=rc->tex_width; vertices[0][1]=rc->tex_height; vertices[0][2]=0.0f; texcoord[0][0]=1.f; texcoord[0][1]=0.f; /* Top Left Of The Quad */ vertices[1][0]=0.f; vertices[1][1]=rc->tex_height; vertices[1][2]=0.0f; texcoord[1][0]=0.f; texcoord[1][1]=0.f; /* Bottom Left Of The Quad */ vertices[2][0]=rc->tex_width; vertices[2][1]=0.f; vertices[2][2]=0.0f; texcoord[2][0]=1.f; texcoord[2][1]=1.f; /* Bottom Right Of The Quad */ vertices[3][0]=0.f; vertices[3][1]=0.f; vertices[3][2]=0.0f; texcoord[3][0]=0.f; texcoord[3][1]=1.f; /* Drawing using triangle strips, draw triangles using 4 vertices */ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); #ifndef GPAC_USE_GLES2 /* Disable vertex array */ glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); #endif } #ifndef GPAC_USE_GLES2 glDisable(GL_TEXTURE_2D); #endif GL_CHECK_ERR /* Flush all drawings */ glFinish(); #ifdef DROID_EXTREME_LOGS LOG( ANDROID_LOG_VERBOSE, TAG, "drawGLScene : end"); #endif /* DROID_EXTREME_LOGS */ }
void ftxRenderString(FontTex *ftx, const char *string, int len) { int i; int bound = -1; int index; int tex; int w; float cw; float cx, cy; GLubyte *color; gl2gles_vertex2v verts[6]; gl2gles_vertex2v texts[6]; if(!len) return; glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); w = ftx->texwidth / ftx->width; cw = (float)ftx->width / (float)ftx->texwidth; for(i = 0; i < len; i++) { if(string[i] == 3) { /* color code */ i++; if(i >= len) return; if(string[i] < color_base && string[i] > color_base + colors) continue; color = color_codes[ string[i] - color_base ]; //TODO: REmoved the color for now, returnted the color glColor3ubv(color); continue; } /* find out which texture it's in */ /* TODO(4): find out why the +1 is necessary */ index = string[i] - ftx->lower + 1; if(index >= ftx->upper) fprintf(stderr, FTX_ERR " index out of bounds"); tex = index / (w * w); /* bind texture */ if(tex != bound) { glBindTexture(GL_TEXTURE_2D, ftx->texID[tex]); //TODO: changed i tot x glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); bound = tex; } /* find texture coordinates */ index = index % (w * w); cx = (float)(index % w) / (float)w; cy = (float)(index / w) / (float)w; /* draw quad */ FillVertex2v(texts[0],cx,1 - cy - cw); FillVertex2v(verts[0],i,0); FillVertex2v(texts[1],cx + cw, 1 - cy - cw); FillVertex2v(verts[1],i + 1, 0); FillVertex2v(texts[2],cx + cw, 1 - cy); FillVertex2v(verts[2],i + 1, 1); FillVertex2v(texts[3],cx + cw, 1 - cy); FillVertex2v(verts[3],i + 1, 1); FillVertex2v(texts[4],cx, 1 - cy); FillVertex2v(verts[4],i, 1); FillVertex2v(texts[5],cx,1 - cy - cw); FillVertex2v(verts[5],i,0); glVertexPointer (2,GL_FLOAT,0,verts); glTexCoordPointer (2,GL_FLOAT,0,texts); glDrawArrays( GL_TRIANGLES , 0, 6 ); } /* checkGLError("FontTex.c ftxRenderString\n"); */ }
void LayerBase::drawWithOpenGL(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const State& s(drawingState()); GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; if (UNLIKELY(s.alpha < 0xFF)) { const GLfloat alpha = s.alpha * (1.0f/255.0f); if (mPremultipliedAlpha) { glColor4f(alpha, alpha, alpha, alpha); } else { glColor4f(1, 1, 1, alpha); } glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else { glColor4f(1, 1, 1, 1); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (!isOpaque()) { glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } struct TexCoords { GLfloat u; GLfloat v; }; TexCoords texCoords[4]; texCoords[0].u = 0; texCoords[0].v = 1; texCoords[1].u = 0; texCoords[1].v = 0; texCoords[2].u = 1; texCoords[2].v = 0; texCoords[3].u = 1; texCoords[3].v = 1; if (drawRotatedTexture) { int tWidth = mTransformedBounds.right - mTransformedBounds.left; int val = drawRotatedTexture(mOrientation, tWidth, fbHeight, clip, (GLfloat *) mVertices, (GLfloat *) texCoords); if (val == NO_ERROR) { return; } } glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVertices); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_BLEND); }
void LayerBlur::onDraw(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); int x = mTransformedBounds.left; int y = mTransformedBounds.top; int w = mTransformedBounds.width(); int h = mTransformedBounds.height(); GLint X = x; GLint Y = fbHeight - (y + h); if (X < 0) { w += X; X = 0; } if (Y < 0) { h += Y; Y = 0; } if (w<0 || h<0) { // we're outside of the framebuffer return; } if (mTextureName == -1U) { // create the texture name the first time // can't do that in the ctor, because it runs in another thread. glGenTextures(1, &mTextureName); } Region::iterator iterator(clip); if (iterator) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, mTextureName); if (mRefreshCache) { mRefreshCache = false; mAutoRefreshPending = false; // allocate enough memory for 4-bytes (2 pixels) aligned data const int32_t s = (w + 1) & ~1; uint16_t* const pixels = (uint16_t*)malloc(s*h*2); // This reads the frame-buffer, so a h/w GL would have to // finish() its rendering first. we don't want to do that // too often. Read data is 4-bytes aligned. glReadPixels(X, Y, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels); // blur that texture. GGLSurface bl; bl.version = sizeof(GGLSurface); bl.width = w; bl.height = h; bl.stride = s; bl.format = GGL_PIXEL_FORMAT_RGB_565; bl.data = (GGLubyte*)pixels; blurFilter(&bl, 8, 2); // NOTE: this works only because we have POT. we'd have to round the // texture size up, otherwise. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels); free((void*)pixels); } const State& s = drawingState(); if (UNLIKELY(s.alpha < 0xFF)) { const GGLfixed alpha = (s.alpha << 16)/255; glColor4x(0, 0, 0, alpha); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); } else { glDisable(GL_BLEND); } glDisable(GL_DITHER); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); if (UNLIKELY(transformed() || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) { // This is a very rare scenario. glMatrixMode(GL_TEXTURE); glLoadIdentity(); glScalef(1.0f/w, -1.0f/h, 1); glTranslatef(-x, -y, 0); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FIXED, 0, mVertices); glTexCoordPointer(2, GL_FIXED, 0, mVertices); Rect r; while (iterator.iterate(&r)) { const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } } else { Region::iterator iterator(clip); if (iterator) { // NOTE: this is marginally faster with the software gl, because // glReadPixels() reads the fb bottom-to-top, however we'll // skip all the jaccobian computations. Rect r; GLint crop[4] = { 0, 0, w, h }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); y = fbHeight - (y + h); while (iterator.iterate(&r)) { const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawTexiOES(x, y, 0, w, h); } } } } glDisableClientState(GL_TEXTURE_COORD_ARRAY); }
void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const State& s(drawingState()); // bind our texture TextureManager::activateTexture(texture, needsFiltering()); uint32_t width = texture.width; uint32_t height = texture.height; GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; int renderEffect = mFlinger->getRenderEffect(); int renderColorR = mFlinger->getRenderColorR(); int renderColorG = mFlinger->getRenderColorG(); int renderColorB = mFlinger->getRenderColorB(); bool noEffect = renderEffect == 0; if (UNLIKELY(s.alpha < 0xFF) && noEffect) { const GLfloat alpha = s.alpha * (1.0f/255.0f); if (mPremultipliedAlpha) { glColor4f(alpha, alpha, alpha, alpha); } else { glColor4f(1, 1, 1, alpha); } glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else if (noEffect) { glColor4f(1, 1, 1, 1); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (needsBlending()) { glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } else { // Apply a render effect, which is simple color masks for now. GLenum env, src; env = GL_MODULATE; src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; const GGLfixed alpha = (s.alpha << 16)/255; switch (renderEffect) { case RENDER_EFFECT_NIGHT: glColor4x(alpha, alpha*0.6204, alpha*0.3018, alpha); break; case RENDER_EFFECT_TERMINAL: glColor4x(0, alpha, 0, alpha); break; case RENDER_EFFECT_BLUE: glColor4x(0, 0, alpha, alpha); break; case RENDER_EFFECT_AMBER: glColor4x(alpha, alpha*0.75, 0, alpha); break; case RENDER_EFFECT_SALMON: glColor4x(alpha, alpha*0.5, alpha*0.5, alpha); break; case RENDER_EFFECT_FUSCIA: glColor4x(alpha, 0, alpha*0.5, alpha); break; case RENDER_EFFECT_N1_CALIBRATED_N: glColor4x(alpha*renderColorR/1000, alpha*renderColorG/1000, alpha*renderColorB/1000, alpha); break; case RENDER_EFFECT_N1_CALIBRATED_R: glColor4x(alpha*(renderColorR-50)/1000, alpha*renderColorG/1000, alpha*(renderColorB-30)/1000, alpha); break; case RENDER_EFFECT_N1_CALIBRATED_C: glColor4x(alpha*renderColorR/1000, alpha*renderColorG/1000, alpha*(renderColorB+30)/1000, alpha); break; case RENDER_EFFECT_RED: glColor4x(alpha, 0, 0, alpha); break; } glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env); } /* * compute texture coordinates * here, we handle NPOT, cropping and buffer transformations */ GLfloat cl, ct, cr, cb; if (!mBufferCrop.isEmpty()) { // source is cropped const GLfloat us = (texture.NPOTAdjust ? texture.wScale : 1.0f) / width; const GLfloat vs = (texture.NPOTAdjust ? texture.hScale : 1.0f) / height; cl = mBufferCrop.left * us; ct = mBufferCrop.top * vs; cr = mBufferCrop.right * us; cb = mBufferCrop.bottom * vs; } else { cl = 0; ct = 0; cr = (texture.NPOTAdjust ? texture.wScale : 1.0f); cb = (texture.NPOTAdjust ? texture.hScale : 1.0f); } /* * For the buffer transformation, we apply the rotation last. * Since we're transforming the texture-coordinates, we need * to apply the inverse of the buffer transformation: * inverse( FLIP_V -> FLIP_H -> ROT_90 ) * <=> inverse( ROT_90 * FLIP_H * FLIP_V ) * = inverse(FLIP_V) * inverse(FLIP_H) * inverse(ROT_90) * = FLIP_V * FLIP_H * ROT_270 * <=> ROT_270 -> FLIP_H -> FLIP_V * * The rotation is performed first, in the texture coordinate space. * */ struct TexCoords { GLfloat u; GLfloat v; }; enum { // name of the corners in the texture map LB = 0, // left-bottom LT = 1, // left-top RT = 2, // right-top RB = 3 // right-bottom }; // vertices in screen space int vLT = LB; int vLB = LT; int vRB = RT; int vRT = RB; // the texture's source is rotated uint32_t transform = mBufferTransform; if (transform & HAL_TRANSFORM_ROT_90) { vLT = RB; vLB = LB; vRB = LT; vRT = RT; } if (transform & HAL_TRANSFORM_FLIP_V) { swap(vLT, vLB); swap(vRT, vRB); } if (transform & HAL_TRANSFORM_FLIP_H) { swap(vLT, vRT); swap(vLB, vRB); } TexCoords texCoords[4]; texCoords[vLT].u = cl; texCoords[vLT].v = ct; texCoords[vLB].u = cl; texCoords[vLB].v = cb; texCoords[vRB].u = cr; texCoords[vRB].v = cb; texCoords[vRT].u = cr; texCoords[vRT].v = ct; if (needsDithering()) { glEnable(GL_DITHER); } else { glDisable(GL_DITHER); } glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVertices); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); }
void drawGLScene(AndroidContext *rc) { #ifdef DROID_EXTREME_LOGS LOG( ANDROID_LOG_VERBOSE, TAG, "drawGLScene : start"); #endif /* DROID_EXTREME_LOGS */ GLfloat vertices[4][3]; GLfloat texcoord[4][2]; // int i, j; float rgba[4]; #ifdef GLES_FRAMEBUFFER_TEST glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); #endif // Reset states rgba[0] = rgba[1] = rgba[2] = 0.f; rgba[0] = 1.f; glColor4f(1.f, 1.f, 1.f, 1.f); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, rgba); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, rgba); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, rgba); glDisable(GL_CULL_FACE | GL_NORMALIZE | GL_LIGHTING | GL_BLEND | GL_FOG | GL_COLOR_MATERIAL | GL_TEXTURE_2D); /* Clear The Screen And The Depth Buffer */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glEnable(GL_BLEND); //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_TEXTURE_2D); glBindTexture( GL_TEXTURE_2D, rc->texID); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // for ( i = 0; i < rc->height/2; i++ ) // for ( j = 0; j < rc->width; j++ ) // rc->texData[ i*rc->width*NBPP + j*NBPP + 3] = 200; // memset(rc->texData, 255, 4 * rc->width * rc->height ); #ifndef GLES_FRAMEBUFFER_TEST glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, rc->tex_width, rc->tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, rc->texData ); #endif if ( rc->draw_texture ) { int cropRect[4] = {0,rc->height,rc->width,-rc->height}; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); glDrawTexsOES(0, 0, 0, rc->width, rc->height); } else { /* Enable VERTEX array */ glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); /* Setup pointer to VERTEX array */ glVertexPointer(3, GL_FLOAT, 0, vertices); glTexCoordPointer(2, GL_FLOAT, 0, texcoord); /* Move Left 1.5 Units And Into The Screen 6.0 */ glLoadIdentity(); //glTranslatef(0.0f, 0.0f, -3.3f); //glTranslatef(0.0f, 0.0f, -2.3f); /* Top Right Of The Quad */ vertices[0][0]=rc->tex_width; vertices[0][1]=rc->tex_height; vertices[0][2]=0.0f; texcoord[0][0]=1.f; texcoord[0][1]=0.f; /* Top Left Of The Quad */ vertices[1][0]=0.f; vertices[1][1]=rc->tex_height; vertices[1][2]=0.0f; texcoord[1][0]=0.f; texcoord[1][1]=0.f; /* Bottom Left Of The Quad */ vertices[2][0]=rc->tex_width; vertices[2][1]=0.f; vertices[2][2]=0.0f; texcoord[2][0]=1.f; texcoord[2][1]=1.f; /* Bottom Right Of The Quad */ vertices[3][0]=0.f; vertices[3][1]=0.f; vertices[3][2]=0.0f; texcoord[3][0]=0.f; texcoord[3][1]=1.f; /* Drawing using triangle strips, draw triangles using 4 vertices */ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); /* Disable vertex array */ glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); } glDisable(GL_TEXTURE_2D); /* Flush all drawings */ glFinish(); #ifdef GLES_FRAMEBUFFER_TEST glBindFramebufferOES(GL_FRAMEBUFFER_OES, rc->framebuff); #endif #ifdef DROID_EXTREME_LOGS LOG( ANDROID_LOG_VERBOSE, TAG, "drawGLScene : end"); #endif /* DROID_EXTREME_LOGS */ }
bool BootAnimation::movie() { char bootenabled[PROPERTY_VALUE_MAX]; char bootsound[PROPERTY_VALUE_MAX]; char bootvolume[PROPERTY_VALUE_MAX]; property_get("persist.sys.boot_enabled", bootenabled, "1"); property_get("persist.sys.boot_sound", bootsound, "1"); property_get("persist.sys.boot_volume", bootvolume, "0.2"); bool bootEnabled = atoi(bootenabled) != 0; bool enableSound = atoi(bootsound) != 0; float bootVolume = strtof(bootvolume, NULL); if(!bootEnabled) { return false; } if(enableSound){ sp<MediaPlayer> mediaplay = new MediaPlayer(); mediaplay->setDataSource ("/system/media/audio.mp3", NULL); mediaplay->setVolume (bootVolume, bootVolume); mediaplay->prepare(); mediaplay->start(); } ZipFileRO& zip(mZip); size_t numEntries = zip.getNumEntries(); ZipEntryRO desc = zip.findEntryByName("desc.txt"); FileMap* descMap = zip.createEntryFileMap(desc); ALOGE_IF(!descMap, "descMap is null"); if (!descMap) { return false; } String8 desString((char const*)descMap->getDataPtr(), descMap->getDataLength()); char const* s = desString.string(); Animation animation; float r = 0.0f; float g = 0.0f; float b = 0.0f; // Parse the description file for (;;) { const char* endl = strstr(s, "\n"); if (!endl) break; String8 line(s, endl - s); const char* l = line.string(); int fps, width, height, count, pause, red, green, blue; char path[256]; char pathType; if (sscanf(l, "%d %d %d %d %d %d", &width, &height, &fps, &red, &green, &blue) == 6) { //ALOGD("> w=%d, h=%d, fps=%d, rgb=(%d, %d, %d)", width, height, fps, red, green, blue); animation.width = width; animation.height = height; animation.fps = fps; r = (float) red / 255.0f; g = (float) green / 255.0f; b = (float) blue / 255.0f; } else if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) { //LOGD("> w=%d, h=%d, fps=%d", width, height, fps); animation.width = width; animation.height = height; animation.fps = fps; } else if (sscanf(l, " %c %d %d %s", &pathType, &count, &pause, path) == 4) { //LOGD("> type=%c, count=%d, pause=%d, path=%s", pathType, count, pause, path); Animation::Part part; part.playUntilComplete = pathType == 'c'; part.count = count; part.pause = pause; part.path = path; animation.parts.add(part); } s = ++endl; } // read all the data structures const size_t pcount = animation.parts.size(); for (size_t i=0 ; i<numEntries ; i++) { char name[256]; ZipEntryRO entry = zip.findEntryByIndex(i); if (zip.getEntryFileName(entry, name, 256) == 0) { const String8 entryName(name); const String8 path(entryName.getPathDir()); const String8 leaf(entryName.getPathLeaf()); if (leaf.size() > 0) { for (size_t j=0 ; j<pcount ; j++) { if (path == animation.parts[j].path) { int method; // supports only stored png files if (zip.getEntryInfo(entry, &method, 0, 0, 0, 0, 0)) { if (method == ZipFileRO::kCompressStored) { FileMap* map = zip.createEntryFileMap(entry); if (map) { Animation::Frame frame; frame.name = leaf; frame.map = map; Animation::Part& part(animation.parts.editItemAt(j)); part.frames.add(frame); } } } } } } } } #ifndef CONTINUOUS_SPLASH // clear screen glShadeModel(GL_FLAT); glDisable(GL_DITHER); glDisable(GL_SCISSOR_TEST); glDisable(GL_BLEND); glClearColor(r,g,b,1); glClear(GL_COLOR_BUFFER_BIT); eglSwapBuffers(mDisplay, mSurface); #endif glBindTexture(GL_TEXTURE_2D, 0); glEnable(GL_TEXTURE_2D); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); const int xc = (mWidth - animation.width) / 2; const int yc = ((mHeight - animation.height) / 2); nsecs_t lastFrame = systemTime(); nsecs_t frameDuration = s2ns(1) / animation.fps; Region clearReg(Rect(mWidth, mHeight)); clearReg.subtractSelf(Rect(xc, yc, xc+animation.width, yc+animation.height)); for (int i=0 ; i<pcount ; i++) { const Animation::Part& part(animation.parts[i]); const size_t fcount = part.frames.size(); // can be 1, 0, or not set #ifdef NO_TEXTURE_CACHE const int noTextureCache = NO_TEXTURE_CACHE; #else const int noTextureCache = ((animation.width * animation.height * fcount) > 48 * 1024 * 1024) ? 1 : 0; #endif glBindTexture(GL_TEXTURE_2D, 0); for (int r=0 ; !part.count || r<part.count ; r++) { // Exit any non playuntil complete parts immediately if(exitPending() && !part.playUntilComplete) break; for (int j=0 ; j<fcount && (!exitPending() || part.playUntilComplete) ; j++) { const Animation::Frame& frame(part.frames[j]); nsecs_t lastFrame = systemTime(); if (r > 0 && !noTextureCache) { glBindTexture(GL_TEXTURE_2D, frame.tid); } else { if (part.count != 1) { glGenTextures(1, &frame.tid); glBindTexture(GL_TEXTURE_2D, frame.tid); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } initTexture( frame.map->getDataPtr(), frame.map->getDataLength()); } if (!clearReg.isEmpty()) { Region::const_iterator head(clearReg.begin()); Region::const_iterator tail(clearReg.end()); glEnable(GL_SCISSOR_TEST); while (head != tail) { const Rect& r(*head++); glScissor(r.left, mHeight - r.bottom, r.width(), r.height()); glClear(GL_COLOR_BUFFER_BIT); } glDisable(GL_SCISSOR_TEST); } glDrawTexiOES(xc, yc, 0, animation.width, animation.height); eglSwapBuffers(mDisplay, mSurface); nsecs_t now = systemTime(); nsecs_t delay = frameDuration - (now - lastFrame); //ALOGD("%lld, %lld", ns2ms(now - lastFrame), ns2ms(delay)); lastFrame = now; if (delay > 0) { struct timespec spec; spec.tv_sec = (now + delay) / 1000000000; spec.tv_nsec = (now + delay) % 1000000000; int err; do { err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL); } while (err<0 && errno == EINTR); } checkExit(); if (noTextureCache) glDeleteTextures(1, &frame.tid); } usleep(part.pause * ns2us(frameDuration)); // For infinite parts, we've now played them at least once, so perhaps exit if(exitPending() && !part.count) break; } // free the textures for this part if (part.count != 1 && !noTextureCache) { for (size_t j=0 ; j<fcount ; j++) { const Animation::Frame& frame(part.frames[j]); glDeleteTextures(1, &frame.tid); } } } return false; }
bool BootAnimation::movie() { ZipEntryRO desc = mZip->findEntryByName("desc.txt"); ALOGE_IF(!desc, "couldn't find desc.txt"); if (!desc) { return false; } FileMap* descMap = mZip->createEntryFileMap(desc); mZip->releaseEntry(desc); ALOGE_IF(!descMap, "descMap is null"); if (!descMap) { return false; } String8 desString((char const*)descMap->getDataPtr(), descMap->getDataLength()); descMap->release(); char const* s = desString.string(); Animation animation; // Parse the description file for (;;) { const char* endl = strstr(s, "\n"); if (!endl) break; String8 line(s, endl - s); const char* l = line.string(); int fps, width, height, count, pause; char path[ANIM_ENTRY_NAME_MAX]; char pathType; if (sscanf(l, "%d %d %d", &width, &height, &fps) == 3) { //LOGD("> w=%d, h=%d, fps=%d", width, height, fps); animation.width = width; animation.height = height; animation.fps = fps; } else if (sscanf(l, " %c %d %d %s", &pathType, &count, &pause, path) == 4) { //LOGD("> type=%c, count=%d, pause=%d, path=%s", pathType, count, pause, path); Animation::Part part; part.playUntilComplete = pathType == 'c'; part.count = count; part.pause = pause; part.path = path; animation.parts.add(part); } s = ++endl; } // read all the data structures const size_t pcount = animation.parts.size(); void *cookie = NULL; if (!mZip->startIteration(&cookie)) { return false; } ZipEntryRO entry; char name[ANIM_ENTRY_NAME_MAX]; while ((entry = mZip->nextEntry(cookie)) != NULL) { const int foundEntryName = mZip->getEntryFileName(entry, name, ANIM_ENTRY_NAME_MAX); if (foundEntryName > ANIM_ENTRY_NAME_MAX || foundEntryName == -1) { ALOGE("Error fetching entry file name"); continue; } const String8 entryName(name); const String8 path(entryName.getPathDir()); const String8 leaf(entryName.getPathLeaf()); if (leaf.size() > 0) { for (size_t j=0 ; j<pcount ; j++) { if (path == animation.parts[j].path) { int method; // supports only stored png files if (mZip->getEntryInfo(entry, &method, NULL, NULL, NULL, NULL, NULL)) { if (method == ZipFileRO::kCompressStored) { FileMap* map = mZip->createEntryFileMap(entry); if (map) { Animation::Frame frame; frame.name = leaf; frame.map = map; Animation::Part& part(animation.parts.editItemAt(j)); part.frames.add(frame); } } } } } } } mZip->endIteration(cookie); // clear screen glShadeModel(GL_FLAT); glDisable(GL_DITHER); glDisable(GL_SCISSOR_TEST); glDisable(GL_BLEND); glClearColor(0,0,0,1); glClear(GL_COLOR_BUFFER_BIT); eglSwapBuffers(mDisplay, mSurface); glBindTexture(GL_TEXTURE_2D, 0); glEnable(GL_TEXTURE_2D); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); const int xc = (mWidth - animation.width) / 2; const int yc = ((mHeight - animation.height) / 2); nsecs_t lastFrame = systemTime(); nsecs_t frameDuration = s2ns(1) / animation.fps; Region clearReg(Rect(mWidth, mHeight)); clearReg.subtractSelf(Rect(xc, yc, xc+animation.width, yc+animation.height)); for (size_t i=0 ; i<pcount ; i++) { const Animation::Part& part(animation.parts[i]); const size_t fcount = part.frames.size(); glBindTexture(GL_TEXTURE_2D, 0); for (int r=0 ; !part.count || r<part.count ; r++) { // Exit any non playuntil complete parts immediately if(exitPending() && !part.playUntilComplete) break; for (size_t j=0 ; j<fcount && (!exitPending() || part.playUntilComplete) ; j++) { const Animation::Frame& frame(part.frames[j]); nsecs_t lastFrame = systemTime(); if (r > 0) { glBindTexture(GL_TEXTURE_2D, frame.tid); } else { if (part.count != 1) { glGenTextures(1, &frame.tid); glBindTexture(GL_TEXTURE_2D, frame.tid); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } initTexture(frame); } if (!clearReg.isEmpty()) { Region::const_iterator head(clearReg.begin()); Region::const_iterator tail(clearReg.end()); glEnable(GL_SCISSOR_TEST); while (head != tail) { const Rect& r(*head++); glScissor(r.left, mHeight - r.bottom, r.width(), r.height()); glClear(GL_COLOR_BUFFER_BIT); } glDisable(GL_SCISSOR_TEST); } glDrawTexiOES(xc, yc, 0, animation.width, animation.height); eglSwapBuffers(mDisplay, mSurface); nsecs_t now = systemTime(); nsecs_t delay = frameDuration - (now - lastFrame); //ALOGD("%lld, %lld", ns2ms(now - lastFrame), ns2ms(delay)); lastFrame = now; if (delay > 0) { struct timespec spec; spec.tv_sec = (now + delay) / 1000000000; spec.tv_nsec = (now + delay) % 1000000000; int err; do { err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL); } while (err<0 && errno == EINTR); } checkExit(); } usleep(part.pause * ns2us(frameDuration)); // For infinite parts, we've now played them at least once, so perhaps exit if(exitPending() && !part.count) break; } // free the textures for this part if (part.count != 1) { for (size_t j=0 ; j<fcount ; j++) { const Animation::Frame& frame(part.frames[j]); glDeleteTextures(1, &frame.tid); } } } return false; }
void LayerBase::drawWithOpenGL(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const State& s(drawingState()); GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; if (CC_UNLIKELY(s.alpha < 0xFF)) { const GLfloat alpha = s.alpha * (1.0f/255.0f); if (mPremultipliedAlpha) { glColor4f(alpha, alpha, alpha, alpha); } else { glColor4f(1, 1, 1, alpha); } glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else { glColor4f(1, 1, 1, 1); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (!isOpaque()) { glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } struct TexCoords { GLfloat u; GLfloat v; }; Rect crop(s.active.w, s.active.h); if (!s.active.crop.isEmpty()) { crop = s.active.crop; } GLfloat left = GLfloat(crop.left) / GLfloat(s.active.w); GLfloat top = GLfloat(crop.top) / GLfloat(s.active.h); GLfloat right = GLfloat(crop.right) / GLfloat(s.active.w); GLfloat bottom = GLfloat(crop.bottom) / GLfloat(s.active.h); TexCoords texCoords[4]; texCoords[0].u = left; texCoords[0].v = top; texCoords[1].u = left; texCoords[1].v = bottom; texCoords[2].u = right; texCoords[2].v = bottom; texCoords[3].u = right; texCoords[3].v = top; for (int i = 0; i < 4; i++) { texCoords[i].v = 1.0f - texCoords[i].v; } glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVertices); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); glDrawArrays(GL_TRIANGLE_FAN, 0, mNumVertices); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_BLEND); }
//end void LayerBase::drawWithOpenGL(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); const uint32_t fbWidth = hw.getWidth(); const State& s(drawingState()); const SurfaceFlinger::State& sSF = mFlinger->getDrawingState(); GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; if (UNLIKELY(s.alpha < 0xFF)) { const GLfloat alpha = s.alpha * (1.0f/255.0f); if (mPremultipliedAlpha) { glColor4f(alpha, alpha, alpha, alpha); } else { glColor4f(1, 1, 1, alpha); } glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else { glColor4f(1, 1, 1, 1); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (!isOpaque()) { glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } //first judge wheather is 3D module 40641 const uint32_t hw_w_half = hw.getWidth()/2; struct TexCoords { GLfloat u; GLfloat v; }; TexCoords texCoords[4]; //judge if 3D modle switch(sSF.composing3D){ case eSTEREO_OSD_3D_NONE: { drawNormal(clip,fbHeight,mDrawingState.flags); break; } case eSTEREO_OSD_3D_SBSHALFE_PR: { drawSideBySide(clip,hw_w_half,fbHeight,mDrawingState.flags); break; } case eSTEREO_OSD_3D_TPANDBT_PR: { drawTopAndBottom(clip,fbHeight,mDrawingState.flags); break; } default: break; } glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_BLEND); }
void LayerBlur::onDraw(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); int x = mTransformedBounds.left; int y = mTransformedBounds.top; int w = mTransformedBounds.width(); int h = mTransformedBounds.height(); GLint X = x; GLint Y = fbHeight - (y + h); if (X < 0) { w += X; X = 0; } if (Y < 0) { h += Y; Y = 0; } if (w<0 || h<0) { // we're outside of the framebuffer return; } if (mTextureName == -1U) { // create the texture name the first time // can't do that in the ctor, because it runs in another thread. glGenTextures(1, &mTextureName); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &mReadFormat); glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &mReadType); if (mReadFormat != GL_RGB || mReadType != GL_UNSIGNED_SHORT_5_6_5) { mReadFormat = GL_RGBA; mReadType = GL_UNSIGNED_BYTE; mBlurFormat = GGL_PIXEL_FORMAT_RGBX_8888; } } Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); if (it != end) { #if defined(GL_OES_EGL_image_external) if (GLExtensions::getInstance().haveTextureExternal()) { glDisable(GL_TEXTURE_EXTERNAL_OES); } #endif glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, mTextureName); if (mRefreshCache) { mRefreshCache = false; mAutoRefreshPending = false; int32_t pixelSize = 4; int32_t s = w; if (mReadType == GL_UNSIGNED_SHORT_5_6_5) { // allocate enough memory for 4-bytes (2 pixels) aligned data s = (w + 1) & ~1; pixelSize = 2; } uint16_t* const pixels = (uint16_t*)malloc(s*h*pixelSize); // This reads the frame-buffer, so a h/w GL would have to // finish() its rendering first. we don't want to do that // too often. Read data is 4-bytes aligned. glReadPixels(X, Y, w, h, mReadFormat, mReadType, pixels); // blur that texture. GGLSurface bl; bl.version = sizeof(GGLSurface); bl.width = w; bl.height = h; bl.stride = s; bl.format = mBlurFormat; bl.data = (GGLubyte*)pixels; blurFilter(&bl, 8, 2); if (GLExtensions::getInstance().haveNpot()) { glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, w, h, 0, mReadFormat, mReadType, pixels); mWidthScale = 1.0f / w; mHeightScale =-1.0f / h; mYOffset = 0; } else { GLuint tw = 1 << (31 - clz(w)); GLuint th = 1 << (31 - clz(h)); if (tw < GLuint(w)) tw <<= 1; if (th < GLuint(h)) th <<= 1; glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, tw, th, 0, mReadFormat, mReadType, NULL); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, mReadFormat, mReadType, pixels); mWidthScale = 1.0f / tw; mHeightScale =-1.0f / th; mYOffset = th-h; } free((void*)pixels); } const State& s = drawingState(); if (UNLIKELY(s.alpha < 0xFF)) { const GLfloat alpha = s.alpha * (1.0f/255.0f); glColor4f(0, 0, 0, alpha); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); } else { glDisable(GL_BLEND); } if (mFlags & DisplayHardware::SLOW_CONFIG) { glDisable(GL_DITHER); } else { glEnable(GL_DITHER); } glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); #ifdef AVOID_DRAW_TEXTURE if(UNLIKELY(transformed())) #endif { glMatrixMode(GL_TEXTURE); glLoadIdentity(); glScalef(mWidthScale, mHeightScale, 1); glTranslatef(-x, mYOffset - y, 0); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(2, GL_FLOAT, 0, mVertices); glTexCoordPointer(2, GL_FLOAT, 0, mVertices); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); } #ifdef AVOID_DRAW_TEXTURE else{ Rect r; GLint crop[4] = { 0, 0, w, h }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop); y = fbHeight - (y + h); while (it != end) { const Rect& r = *it++; const GLint sy = fbHeight - (r.top + r.height()); glScissor(r.left, sy, r.width(), r.height()); glDrawTexiOES(x, y, 0, w, h); } } #endif glLoadIdentity(); glMatrixMode(GL_MODELVIEW); } }
void LayerBase::drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& clip) const { const uint32_t fbHeight = hw->getHeight(); const State& s(drawingState()); GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA; if (CC_UNLIKELY(s.alpha < 0xFF)) { const GLfloat alpha = s.alpha * (1.0f/255.0f); if (mPremultipliedAlpha) { glColor4f(alpha, alpha, alpha, alpha); } else { glColor4f(1, 1, 1, alpha); } glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); } else { glColor4f(1, 1, 1, 1); glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); if (!isOpaque()) { glEnable(GL_BLEND); glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA); } else { glDisable(GL_BLEND); } } LayerMesh mesh; computeGeometry(hw, &mesh); // TODO: we probably want to generate the texture coords with the mesh // here we assume that we only have 4 vertices struct TexCoords { GLfloat u; GLfloat v; }; Rect win(s.active.w, s.active.h); if (!s.active.crop.isEmpty()) { win.intersect(s.active.crop, &win); } GLfloat left = GLfloat(win.left) / GLfloat(s.active.w); GLfloat top = GLfloat(win.top) / GLfloat(s.active.h); GLfloat right = GLfloat(win.right) / GLfloat(s.active.w); GLfloat bottom = GLfloat(win.bottom) / GLfloat(s.active.h); TexCoords texCoords[4]; texCoords[0].u = left; texCoords[0].v = top; texCoords[1].u = left; texCoords[1].v = bottom; texCoords[2].u = right; texCoords[2].v = bottom; texCoords[3].u = right; texCoords[3].v = top; for (int i = 0; i < 4; i++) { texCoords[i].v = 1.0f - texCoords[i].v; } glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices()); glDrawArrays(GL_TRIANGLE_FAN, 0, mesh.getVertexCount()); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_BLEND); }
void glTexEnvxLogged(GLenum target, GLenum pname, GLfixed param) { printf("glTexEnvx(%s, %s, %i)\n", GLEnumName(target), GLEnumName(pname), param); glTexEnvx(target, pname, param); }