void DrawLine( GLuint rgba, float ax, float ay, float bx, float by, float lineWidth ) { SetupOrtho(); glDisable( GL_TEXTURE_2D ); glEnableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); GLfloat vertices[] = { ax,ay, 0, bx, by, 0 }; glLineWidth(lineWidth); glEnable (GL_LINE_SMOOTH); //glDisable(GL_LINE_SMOOTH); glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); glVertexPointer(3, GL_FLOAT, 0, vertices); //glColor4f(1, 1, 1, 1); glEnable( GL_BLEND ); glColor4x( (rgba >>8 & 0xFF)*256, (rgba>>16& 0xFF)*256, (rgba>>24& 0xFF)*256, (rgba&0xFF)*256); glDrawArrays(GL_LINES, 0, 2); glColor4x(1 << 16, 1 << 16, 1 << 16, 1 << 16); glDisable( GL_BLEND ); glEnable( GL_TEXTURE_2D ); glEnableClientState(GL_TEXTURE_COORD_ARRAY); CHECK_GL_ERROR(); }
static void ANDROID_FlipHWSurfaceInternal() { //__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROID_FlipHWSurface()"); if( SDL_CurrentVideoSurface->hwdata && SDL_CurrentVideoSurface->pixels && ! ( SDL_CurrentVideoSurface->flags & SDL_HWSURFACE ) ) { SDL_Rect rect; rect.x = 0; rect.y = 0; rect.w = SDL_CurrentVideoSurface->w; rect.h = SDL_CurrentVideoSurface->h; SDL_UpdateTexture((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, SDL_CurrentVideoSurface->pixels, SDL_CurrentVideoSurface->pitch); SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &rect, &rect); if( SDL_ANDROID_ShowScreenUnderFinger && SDL_ANDROID_ShowScreenUnderFingerRect.w > 0 ) { SDL_RenderCopy((struct SDL_Texture *)SDL_CurrentVideoSurface->hwdata, &SDL_ANDROID_ShowScreenUnderFingerRectSrc, &SDL_ANDROID_ShowScreenUnderFingerRect); SDL_Rect frame = SDL_ANDROID_ShowScreenUnderFingerRect; // For some reason this code fails - it just outputs nothing to screen /* SDL_SetRenderDrawColor(0, 0, 0, SDL_ALPHA_OPAQUE); SDL_RenderFillRect(&SDL_ANDROID_ShowScreenUnderFingerRect); SDL_SetRenderDrawColor(255, 255, 255, SDL_ALPHA_OPAQUE); SDL_RenderDrawRect(&SDL_ANDROID_ShowScreenUnderFingerRectSrc); SDL_SetRenderDrawColor(0, 0, 0, SDL_ALPHA_OPAQUE); SDL_RenderDrawRect(&frame); */ // Do it old-fashioned way with direct GL calls glPushMatrix(); glLoadIdentity(); glOrthox( 0, SDL_ANDROID_sFakeWindowWidth * 0x10000, SDL_ANDROID_sFakeWindowHeight * 0x10000, 0, 0, 1 * 0x10000 ); glColor4x(0, 0, 0, 0x10000); glEnableClientState(GL_VERTEX_ARRAY); glColor4x(0, 0, 0, 0x10000); GLshort vertices[] = { frame.x, frame.y, frame.x + frame.w, frame.y, frame.x + frame.w, frame.y + frame.h, frame.x, frame.y + frame.h }; glVertexPointer(2, GL_SHORT, 0, vertices); glDrawArrays(GL_LINE_LOOP, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); glFlush(); } } };
/** * Configures this color in the OpenGL context. */ void Set() const { #ifdef HAVE_GLES /* on Android, glColor4ub() is not implemented, and we're forced to use floating point math for something as trivial as configuring a RGB color value */ glColor4x(r, g, b, a); #else glColor4ub(r, g, b, a); #endif }
/** * Configures this color in the OpenGL context. */ void Bind() const { #ifdef USE_GLSL VertexAttrib(OpenGL::Attribute::COLOR); #elif defined(HAVE_GLES) /* on Android, glColor4ub() is not implemented, and we're forced to use floating point math for something as trivial as configuring a RGB color value */ glColor4x(r, g, b, a); #else glColor4ub(r, g, b, a); #endif }
// Draws a char on screen using embedded line font, (x, y) are center of char, not upper-left corner // TODO: use SDL 1.3 renderer routines? It will not be pixel-aligned then, if the screen is resized static inline void drawCharWireframe(int idx, Uint16 x, Uint16 y, int rotation, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { glColor4x(r * 0x100, g * 0x100, b * 0x100, a * 0x100); glVertexPointer(2, GL_SHORT, 0, fontGL[idx]); glPopMatrix(); glPushMatrix(); glTranslatex( x * 0x10000, y * 0x10000, 0 ); if(rotation != 0) glRotatex( rotation, 0, 0, 0x10000 ); glDrawArrays(GL_LINES, 0, fontGL[idx][FONT_CHAR_LINES_COUNT]); }
void GenerateFillRect( GLuint rgba, float x, float y, float w, float h ) { SetupOrtho(); //disable depth testing and depth writing glDisable( GL_TEXTURE_2D ); if (BaseApp::GetBaseApp()->GetDisableSubPixelBlits()) { //fix issue for cracks when scaling when 2d tile blits x = ceil(x); y = ceil(y); w = ceil(w); h = ceil(h); } //3 2 //0 1 GLfloat vertices[] = { x, y, 0.0, x + w, y, 0.0, x +w, y+h, 0.0, x , y+h, 0.0 }; glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 0, vertices); //glColor4f(1, 1, 1, 1); assert((rgba&0xFF)*256 != 0 && "Why send something with zero alpha?"); glEnable( GL_BLEND ); glDisable( GL_TEXTURE_2D ); glEnable(GL_ALPHA_TEST); glColor4x( (rgba >>8 & 0xFF)*256, (rgba>>16& 0xFF)*256, (rgba>>24& 0xFF)*256, (rgba&0xFF)*256); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glColor4x(1 << 16, 1 << 16, 1 << 16, 1 << 16); glDisable( GL_BLEND ); glEnable( GL_TEXTURE_2D ); glDisable(GL_ALPHA_TEST); glEnableClientState(GL_TEXTURE_COORD_ARRAY); CHECK_GL_ERROR(); }
int SDL_ANDROID_CallJavaSwapBuffers() { if( !glContextLost ) { SDL_ANDROID_drawTouchscreenKeyboard(); } // Clear part of screen not used by SDL - on Android the screen contains garbage after each frame if( SDL_ANDROID_ForceClearScreenRect.w != 0 && SDL_ANDROID_ForceClearScreenRect.h != 0 ) { glPushMatrix(); glLoadIdentity(); glOrthox( 0, (SDL_ANDROID_sRealWindowWidth) * 0x10000, SDL_ANDROID_sRealWindowHeight * 0x10000, 0, 0, 1 * 0x10000 ); glColor4x(0, 0, 0, 0x10000); glEnableClientState(GL_VERTEX_ARRAY); GLshort vertices[] = { SDL_ANDROID_ForceClearScreenRect.x, SDL_ANDROID_ForceClearScreenRect.y, SDL_ANDROID_ForceClearScreenRect.x + SDL_ANDROID_ForceClearScreenRect.w, SDL_ANDROID_ForceClearScreenRect.y, SDL_ANDROID_ForceClearScreenRect.x + SDL_ANDROID_ForceClearScreenRect.w, SDL_ANDROID_ForceClearScreenRect.y + SDL_ANDROID_ForceClearScreenRect.h, SDL_ANDROID_ForceClearScreenRect.x, SDL_ANDROID_ForceClearScreenRect.y + SDL_ANDROID_ForceClearScreenRect.h }; glVertexPointer(2, GL_SHORT, 0, vertices); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); } if( ! (*JavaEnv)->CallIntMethod( JavaEnv, JavaRenderer, JavaSwapBuffers ) ) return 0; if( glContextLost ) { glContextLost = 0; __android_log_print(ANDROID_LOG_INFO, "libSDL", "OpenGL context recreated, refreshing textures"); SDL_ANDROID_VideoContextRecreated(); appRestoredCallback(); if(openALRestoredCallback) openALRestoredCallback(); } if( showScreenKeyboardDeferred ) { showScreenKeyboardDeferred = 0; (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaShowScreenKeyboard, (*JavaEnv)->NewStringUTF(JavaEnv, showScreenKeyboardOldText), showScreenKeyboardSendBackspace ); } SDL_ANDROID_ProcessDeferredEvents(); return 1; }
static inline void drawCharTex(GLTexture_t * tex, SDL_Rect * src, SDL_Rect * dest, Uint8 r, Uint8 g, Uint8 b, Uint8 a) { GLint cropRect[4]; /* GLfloat texColor[4]; static const float onediv255 = 1.0f / 255.0f; */ if( !dest->h || !dest->w ) return; glBindTexture(GL_TEXTURE_2D, tex->id); glColor4x(r * 0x100, g * 0x100, b * 0x100, a * 0x100 ); //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); /* texColor[0] = r * onediv255; texColor[1] = g * onediv255; texColor[2] = b * onediv255; texColor[3] = a * onediv255; glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, texColor); */ cropRect[0] = 0; cropRect[1] = tex->h; cropRect[2] = tex->w; cropRect[3] = -tex->h; if(src) { cropRect[0] = src->x; cropRect[1] = src->h; // TODO: check if height works as expected in inverted GL coords cropRect[2] = src->w; cropRect[3] = -src->h; // TODO: check if height works as expected in inverted GL coords } glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); glDrawTexiOES(dest->x, SDL_ANDROID_sWindowHeight - dest->y - dest->h, 0, dest->w, dest->h); }
static void drawFadeQuad() { static const GLfixed quadVertices[] = { -0x10000, -0x10000, 0x10000, -0x10000, -0x10000, 0x10000, 0x10000, -0x10000, 0x10000, 0x10000, -0x10000, 0x10000 }; const int beginFade = sTick - sCurrentCamTrackStartTick; const int endFade = sNextCamTrackStartTick - sTick; const int minFade = beginFade < endFade ? beginFade : endFade; if (minFade < 1024) { const GLfixed fadeColor = minFade << 6; glColor4x(fadeColor, fadeColor, fadeColor, 0); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_ZERO, GL_SRC_COLOR); glDisable(GL_LIGHTING); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glVertexPointer(2, GL_FIXED, 0, quadVertices); glDrawArrays(GL_TRIANGLES, 0, 6); glEnableClientState(GL_COLOR_ARRAY); glMatrixMode(GL_MODELVIEW); glEnable(GL_LIGHTING); glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); } }
void LayerBase::clearWithOpenGL(const Region& clip) const { const DisplayHardware& hw(graphicPlane(0).displayHardware()); const uint32_t fbHeight = hw.getHeight(); glColor4x(0,0,0,0); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); glDisable(GL_DITHER); Rect r; Region::iterator iterator(clip); if (iterator) { glVertexPointer(2, GL_FIXED, 0, mVertices); 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); } } }
void BaseApp::InitializeGLDefaults() { glMatrixMode(GL_MODELVIEW); glDepthMask(GL_TRUE); glEnable(GL_TEXTURE_2D); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glEnable(GL_DEPTH_TEST); glDisable(GL_ALPHA_TEST); glDisable( GL_BLEND ); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisable( GL_LIGHTING ); glDepthFunc(GL_LEQUAL); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glColor4x(1 << 16, 1 << 16, 1 << 16, 1 << 16); glClearColor(0,0,0,255); }
void DrawEllipse (const int segments, CL_Vec2f vPos, float radianWidth, float radiusHeight, bool vFilled, uint32 color) { SetupOrtho(); glPushMatrix(); glTranslatef(vPos.x, vPos.y, 0.0); vector<float> vertices; vertices.resize(segments*2); glEnable (GL_LINE_SMOOTH); int count=0; for (GLfloat i = 0; i < 360.0f; i+=(360.0f/segments)) { vertices[count++] = (float(cos(DEG2RAD(i)))*radianWidth); vertices[count++] = (float(sin(DEG2RAD(i)))*radiusHeight); } glColor4x( (color >>8 & 0xFF)*256, (color>>16& 0xFF)*256, (color>>24& 0xFF)*256, (color&0xFF)*256); if (GET_ALPHA(color) != 255) { glEnable(GL_BLEND); glEnable(GL_ALPHA_TEST); } glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_TEXTURE_2D); glVertexPointer (2, GL_FLOAT , 0, &vertices.at(0)); glDrawArrays ((vFilled) ? GL_TRIANGLE_FAN : GL_LINE_LOOP, 0, segments); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_TEXTURE_2D); if (GET_ALPHA(color) != 255) { glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); } glColor4x(1 << 16, 1 << 16, 1 << 16, 1 << 16); glPopMatrix(); }
static void ogl_setAlpha(int a) { sAlpha = a; glColor4x(sColorR<<8, sColorG<<8, sColorB<<8, sAlpha<<8); }
static void ogl_setColor(int r, int g, int b) { sColorR = r; sColorG = g; sColorB = b; glColor4x(sColorR<<8, sColorG<<8, sColorB<<8, sAlpha<<8); }
/*! * \brief Updates the OpenGL ES state * \param width Rendering width. * \param height Rendering height. *//*-------------------------------------------------------------------*/ static void updateOpenGLESState(int width, int height) { /* Define lights and materials for the OpenGL ES scene */ static const GLfixed light_position[] = { F2F(-50.f), F2F(50.f), F2F(50.f), F2F(0.0f) }; static const GLfixed light_ambient[] = { F2F(0.125f), F2F(0.125f), F2F(0.125f), F2F(1.0f) }; static const GLfixed light_diffuse[] = { F2F(0.7f), F2F(0.7f), F2F(0.7f), F2F(1.0f) }; static const GLfixed material_spec[] = { F2F(0.7f), F2F(0.7f), F2F(0.7f), F2F(0.0f) }; static const GLfixed zero_vec4[] = { F2F(0.0f), F2F(0.0f), F2F(0.0f), F2F(0.0f) }; /* Define the aspect ratio for the perpective calculations so that no distortion happens when the screen is resized */ float aspect = height ? (float)width/(float)height : 1.0f; glViewport (0, 0, width, height); glScissor (0, 0, width, height); /* Set the matrix mode to world coordinates */ glMatrixMode (GL_MODELVIEW); glLoadIdentity (); /* Setup lights and materials with the values given above */ glLightxv (GL_LIGHT0, GL_POSITION, light_position); glLightxv (GL_LIGHT0, GL_AMBIENT, light_ambient); glLightxv (GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightxv (GL_LIGHT0, GL_SPECULAR, zero_vec4); glMaterialxv (GL_FRONT_AND_BACK, GL_SPECULAR, material_spec); /* Enable ligting, materials, backface culling and textures */ glDisable (GL_NORMALIZE); glEnable (GL_LIGHTING); glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ZERO); glEnable (GL_LIGHT0); glEnable (GL_COLOR_MATERIAL); glEnable (GL_CULL_FACE); glEnable (GL_TEXTURE_2D); /* Tell OpenGL to use nicest perspective correction */ glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); /* Use flat shading and disable dithering */ glShadeModel (GL_FLAT); glDisable (GL_DITHER); /* Setup the clear color and the current color for the OpenGL context */ glClearColorx (F2F(0.1f), F2F(0.2f), F2F(0.4f), F2F(1.f)); glColor4x (0x10000, 0x10000, 0x10000, 0x10000); /* Enable the use of vertex, normal and texture coordinate arrays */ glEnableClientState (GL_VERTEX_ARRAY); glEnableClientState (GL_NORMAL_ARRAY); glEnableClientState (GL_TEXTURE_COORD_ARRAY); /* Mipmaps do not work on all BREW devices, so disable it */ /* glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);*/ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* Update the projection matrix */ glMatrixMode (GL_PROJECTION); glLoadIdentity (); setGLESperspective (60.f, aspect, 0.1f, 100.f); }
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 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 SkGL::SetAlpha(U8CPU alpha) { SkFixed fa = byte2fixed(alpha); glColor4x(fa, fa, fa, fa); }
static inline void gl_pmcolor(U8CPU r, U8CPU g, U8CPU b, U8CPU a) { glColor4x(byte2fixed(r), byte2fixed(g), byte2fixed(b), byte2fixed(a)); }
int main(void) { EGLDisplay m_eglDisplay; EGLContext m_eglContext; EGLSurface m_eglSurface; EGLint attributeList[] = { EGL_RED_SIZE, 1, EGL_DEPTH_SIZE, 1, EGL_NONE }; EGLint aEGLAttributes[] = { EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_NONE }; EGLint aEGLContextAttributes[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; EGLConfig m_eglConfig[1]; EGLint nConfigs; unsigned char mIndices[] = { 0, 1, 2 }; signed short mVertices[] = { -50, -29, 0, 50, -29, 0, 0, 58, 0 }; HWND hwnd; HDC hdc; MSG sMessage; int bDone = 0; // Platform init. platform(&hwnd, 640, 480); ShowWindow(hwnd, SW_SHOW); SetForegroundWindow(hwnd); SetFocus(hwnd); // EGL init. hdc = GetDC(hwnd); m_eglDisplay = eglGetDisplay(hdc); eglInitialize(m_eglDisplay, NULL, NULL); eglChooseConfig(m_eglDisplay, aEGLAttributes, m_eglConfig, 1, &nConfigs); printf("EGLConfig = %p\n", m_eglConfig[0]); m_eglSurface = eglCreateWindowSurface(m_eglDisplay, m_eglConfig[0], (NativeWindowType)hwnd, 0); m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig[0], EGL_NO_CONTEXT, aEGLContextAttributes); printf("EGLContext = %p\n", m_eglContext); eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_SHORT, 0, mVertices); /* Set projection matrix so screen extends to (-160, -120) at bottom left * and to (160, 120) at top right, with -128..128 as Z buffer. */ glMatrixMode(GL_PROJECTION); glOrthox(-160<<16, 160<<16, -120<<16, 120<<16, -128<<16, 128<<16); glMatrixMode(GL_MODELVIEW); glClearColorx(0x10000, 0x10000, 0, 0); glColor4x(0x10000, 0, 0, 0); // Main event loop while(!bDone) { // Do Windows stuff: if(PeekMessage(&sMessage, NULL, 0, 0, PM_REMOVE)) { if(sMessage.message == WM_QUIT) { bDone = 1; } else { TranslateMessage(&sMessage); DispatchMessage(&sMessage); } } glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, mIndices); glRotatex(2<<16, 0, 0, 0x10000); eglSwapBuffers(m_eglDisplay, m_eglSurface); Sleep(30); } // Exit. eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(m_eglDisplay, m_eglContext); eglDestroySurface(m_eglDisplay, m_eglSurface); eglTerminate(m_eglDisplay); ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); return 0; }
void glColor4xLogged(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) { printf("glColor4x(%i, %i, %i, %i)\n", red, green, blue, alpha); glColor4x(red, green, blue, alpha); }
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); } } } }
void DrawLine( GLuint rgba, float ax, float ay, float bx, float by, float lineWidth ) { SetupOrtho(); //g_globalBatcher.Flush(); glDisable( GL_TEXTURE_2D ); glEnableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(GL_CULL_FACE); static GLfloat vertices[3*4]; CL_Vec2f start = CL_Vec2f(ax, ay); CL_Vec2f end = CL_Vec2f(bx, by); float dx = ax - bx; float dy = ay - by; CL_Vec2f rightSide = CL_Vec2f(dy, -dx); if (rightSide.length() > 0) { rightSide.normalize(); rightSide *= lineWidth/2; } CL_Vec2f leftSide =CL_Vec2f(-dy, dx); if (leftSide.length() > 0) { leftSide.normalize(); leftSide *= lineWidth/2; } CL_Vec2f one = leftSide + start; CL_Vec2f two = rightSide + start; CL_Vec2f three = rightSide + end; CL_Vec2f four = leftSide = end; vertices[0*3+0] = one.x; vertices[0*3+1] = one.y; vertices[1*3+0] = two.x; vertices[1*3+1] = two.y; vertices[2*3+0] = three.x; vertices[2*3+1] = three.y; vertices[3*3+0] = four.x; vertices[3*3+1] = four.y; //set the Z vertices[0*3+2] = 0; vertices[1*3+2] = 0; vertices[2*3+2] = 0; vertices[3*3+2] = 0; glVertexPointer(3, GL_FLOAT, 0, vertices); //glColor4f(1, 1, 1, 1); glEnable( GL_BLEND ); glColor4x( (rgba >>8 & 0xFF)*256, (rgba>>16& 0xFF)*256, (rgba>>24& 0xFF)*256, (rgba&0xFF)*256); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glColor4x(1 << 16, 1 << 16, 1 << 16, 1 << 16); glEnable(GL_CULL_FACE); glDisable( GL_BLEND ); glEnable( GL_TEXTURE_2D ); glEnableClientState(GL_TEXTURE_COORD_ARRAY); CHECK_GL_ERROR(); }