void OpenGLPlugin::SetPalette(ColorARGB8888* c) { //SDL_SetPalette(_publicVideo, SDL_LOGPAL | SDL_PHYSPAL, c, 0, 32); if (_publicVideo->format->palette) { Uint8* pal=(Uint8*)malloc(sizeof(Uint8)*256*3); for(int i=0;i<256;i++) { pal[3*i ] = _publicVideo->format->palette->colors[i].r; pal[3*i+1] = _publicVideo->format->palette->colors[i].g; pal[3*i+2] = _publicVideo->format->palette->colors[i].b; } eglBindTexture(GL_TEXTURE_2D,_screenTexnum); eglColorTableEXT(GL_TEXTURE_2D,GL_RGB8,256,GL_RGB,GL_UNSIGNED_BYTE,pal); free(pal); } }
/* ================= gl_texture_create ================= */ erbool gl_texture_create (image_t *image, int flags, int *gltex, int *texw, int *texh) { int max, sw, sh, mip; GLuint tex; if (NULL == image || NULL == gltex || NULL == texw || NULL == texh) { sys_printf("bad args (image=%p, flags=%i, gltex=%p, texw=%p, texh=%p)\n", image, flags, gltex, texw, texh); return false; } if (flags & GL_TEX_FL_TEX3D) { max = gl_texture3d_size_max; } else if (flags & GL_TEX_FL_CUBEMAP) { max = gl_texture_cube_map_size_max; } else { max = gl_max_texture_size; } if (GL_TEX_FL_NOPICMIP) { sw = CLAMP(image->width, 1, max); sh = CLAMP(image->height, 1, max); } else { sw = CLAMP(image->width >> gl_picmip->i, 1, max); sh = CLAMP(image->height >> gl_picmip->i, 1, max); } if (!ext_gl_arb_texture_non_power_of_two || !gl_arb_texture_non_power_of_two->i) { sw = ceil_pwrov2(sw); sh = ceil_pwrov2(sh); } sw = CLAMP(sw, GL_MIN_TEXTURE_DIMENSION, max); sh = CLAMP(sh, GL_MIN_TEXTURE_DIMENSION, max); if (flags & GL_TEX_FL_NOSCALE) { *texw = sw; *texh = sh; if (!image_resize(image, sw, sh)) return false; } else { *texw = image->width; *texh = image->height; if (!image_scale(image, sw, sh)) return false; } glGenTextures(1, &tex); GLERROR(); eglBindTexture(GL_TEXTURE_2D, tex); GLERROR(); *gltex = tex; if (NULL != image->teximage2d) { image->teximage2d(image); } else { if (ext_gl_sgis_generate_mipmap && gl_sgis_generate_mipmap->i) { #ifdef ENGINE_OS_IPHONE glGenerateMipmapOES(GL_TEXTURE_2D); #else glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); #endif GLERROR(); GL_IMAGE_DATA2D(0, image); GLERROR(); } else { GL_IMAGE_DATA2D(0, image); GLERROR(); for (mip = 1; image->width > 1 || image->height > 1 ; mip++) { int status; if (0 > (status = image_mipmap(image))) { sys_printf("mipmap failed\n"); goto error; } else if (status > 0) { break; } GL_IMAGE_DATA2D(mip, image); GLERROR(); } } } if (flags & GL_TEX_FL_NOFILTER) { glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); GLERROR(); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); GLERROR(); } else { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_trilinear->i ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR_MIPMAP_NEAREST); GLERROR(); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); GLERROR(); } if (!(flags & GL_TEX_FL_NOANISO) && ext_gl_ext_texture_filter_anisotropic && gl_ext_texture_filter_anisotropic->i) { GLfloat ani = CLAMP(gl_anisotropy_level->f, 1, gl_anisotropy_max); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, ani); GLERROR(); } if (!(flags & GL_TEX_FL_NOLOD) && ext_gl_ext_texture_lod_bias && gl_ext_texture_lod_bias->i) { GLfloat lod = CLAMP(gl_lod_bias->f, 0, gl_lod_bias_max); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS_EXT, lod); GLERROR(); } return true; error: glDeleteTextures(1, &tex); GLERROR(); return false; }
void OpenGLPlugin::Flip() { eglDisable(GL_BLEND); if (_GLScanlines!=0) { eglActiveTextureARB(GL_TEXTURE1_ARB); eglEnable(GL_TEXTURE_2D); eglBindTexture(GL_TEXTURE_2D,_modulateTexnum); eglTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); eglColor4f(1.0,1.0,1.0,1.0); eglActiveTextureARB(GL_TEXTURE0_ARB); } eglEnable(GL_TEXTURE_2D); eglBindTexture(GL_TEXTURE_2D,_screenTexnum); if (_remanency) { /* draw again using the old texture */ eglBegin(GL_QUADS); eglColor4f(1.0,1.0,1.0,1.0); eglTexCoord2f(0.f, 0.f); if (_GLScanlines!=0) eglMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.f, 0.f); eglVertex2i(0, 0); eglTexCoord2f(0.f, (float)(_publicVideo->h)/_texHeight); if (_GLScanlines!=0) eglMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.f, (float)_video->h/2); eglVertex2i(0, _video->h); eglTexCoord2f((float)(_publicVideo->w)/_texWidth, (float)(_publicVideo->h)/_texHeight); if (_GLScanlines!=0) eglMultiTexCoord2fARB(GL_TEXTURE1_ARB,(float)_video->w, (float)_video->h/2); eglVertex2i(_video->w, _video->h); eglTexCoord2f((float)(_publicVideo->w)/_texWidth, 0.f); if (_GLScanlines!=0) eglMultiTexCoord2fARB(GL_TEXTURE1_ARB,(float)_video->w, 0); eglVertex2i(_video->w, 0); eglEnd(); /* enable blending for the subsequent pass */ eglEnable(GL_BLEND); eglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } /* upload the texture */ switch(_publicVideo->format->BitsPerPixel) { case 32: eglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _publicVideo->w, _publicVideo->h, GL_BGRA,GL_UNSIGNED_BYTE, _publicVideo->pixels); break; case 24: eglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _publicVideo->w, _publicVideo->h, GL_BGR,GL_UNSIGNED_BYTE, _publicVideo->pixels); break; case 16: eglTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _publicVideo->w, _publicVideo->h, GL_RGB,GL_UNSIGNED_SHORT_5_6_5, _publicVideo->pixels); break; case 8: eglTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, _publicVideo->w,_publicVideo->h, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, _publicVideo->pixels); break; } /* draw ! */ eglBegin(GL_QUADS); eglColor4f(1.0,1.0,1.0,0.5); eglTexCoord2f(0.f, 0.f); if (_GLScanlines!=0) eglMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.f, 0.f); eglVertex2i(0, 0); eglTexCoord2f(0.f, (float)(_publicVideo->h)/_texHeight); if (_GLScanlines!=0) eglMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.f, (float)_video->h/2); eglVertex2i(0, _video->h); eglTexCoord2f((float)(_publicVideo->w)/_texWidth, (float)(_publicVideo->h)/_texHeight); if (_GLScanlines!=0) eglMultiTexCoord2fARB(GL_TEXTURE1_ARB,(float)_video->w, (float)_video->h/2); eglVertex2i(_video->w, _video->h); eglTexCoord2f((float)(_publicVideo->w)/_texWidth, 0.f); if (_GLScanlines!=0) eglMultiTexCoord2fARB(GL_TEXTURE1_ARB,(float)_video->w, 0); eglVertex2i(_video->w, 0); eglEnd(); if (_postRenderCallBack != NULL) _postRenderCallBack(); }
SDL_Surface* OpenGLPlugin::OpenGLInit(int w,int h, int bpp, bool fs, int glScanline) { _GLScanlines = glScanline; #ifdef _WIN32 const char *gl_library = "OpenGL32.DLL"; #else const char *gl_library = "libGL.so.1"; #endif int surface_bpp; SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); if (SDL_GL_LoadLibrary(gl_library)<0) { fprintf(stderr,"Unable to dynamically open GL lib : %s\n",SDL_GetError()); return NULL; } if (!fs) { w=CPCVisibleSCRWidth*2; h=CPCVisibleSCRHeight*2; } _video=SDL_SetVideoMode(w,h,0,SDL_OPENGL | (fs?SDL_FULLSCREEN:0)); if (!_video) { fprintf(stderr, "Could not set requested video mode: %s\n", SDL_GetError()); return NULL; } if (init_glfuncs()!=0) { fprintf(stderr, "Cannot init OpenGL functions: %s\n", SDL_GetError()); return NULL; } int major, minor; const char *version; version = (char *) eglGetString(GL_VERSION); if (sscanf(version, "%d.%d", &major, &minor) != 2) { fprintf(stderr, "Unable to get OpenGL version\n"); return NULL; } GLint max_texsize; eglGetIntegerv(GL_MAX_TEXTURE_SIZE,&max_texsize); if (max_texsize<512) { fprintf(stderr, "Your OpenGL implementation doesn't support 512x512 textures\n"); return NULL; } // We have to react differently to the bpp parameter than with software rendering // Here are the rules : // for 8bpp OpenGL, we need the GL_EXT_paletted_texture extension // for 16bpp OpenGL, we need OpenGL 1.2+ // for 24bpp reversed OpenGL, we need OpenGL 1.2+ surface_bpp=0; switch(bpp) { case 8: surface_bpp = (HaveOpenGLExtension("GL_EXT_paletted_texture"))?8:0; break; case 15: case 16: surface_bpp = ((major>1)||(major == 1 && minor >= 2))?16:0; break; case 24: surface_bpp = ((major>1)||(major == 1 && minor >= 2))?24:0; case 32: surface_bpp = ((major>1)||(major == 1 && minor >= 2))?32:0; default: surface_bpp = ((major>1)||(major == 1 && minor >= 2))?32:0; break; } if (surface_bpp==0) { fprintf(stderr, "Your OpenGL implementation doesn't support %dbpp textures\n",surface_bpp); return NULL; } eglDisable(GL_FOG); eglDisable(GL_LIGHTING); eglDisable(GL_CULL_FACE); eglDisable(GL_DEPTH_TEST); eglDisable(GL_BLEND); eglDisable(GL_NORMALIZE); eglDisable(GL_ALPHA_TEST); eglEnable(GL_TEXTURE_2D); eglBlendFunc (GL_SRC_ALPHA, GL_ONE); eglGenTextures(1,&_screenTexnum); eglBindTexture(GL_TEXTURE_2D,_screenTexnum); eglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _openGLFilter?GL_LINEAR:GL_NEAREST); eglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _openGLFilter?GL_LINEAR:GL_NEAREST); _texWidth=512; _texHeight=512; switch(surface_bpp) { case 32: eglTexImage2D(GL_TEXTURE_2D, 0,GL_RGBA,_texWidth,_texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); break; case 24: eglTexImage2D(GL_TEXTURE_2D, 0,GL_RGB,_texWidth,_texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); break; case 16: eglTexImage2D(GL_TEXTURE_2D, 0,GL_RGB5,_texWidth,_texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); break; case 8: eglTexImage2D(GL_TEXTURE_2D, 0,GL_COLOR_INDEX8_EXT,_texWidth,_texHeight, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, NULL); break; } if (_GLScanlines!=0) { Uint8 texmod; switch(_GLScanlines) { case 25: texmod=192; break; case 50: texmod=128; break; case 75: texmod=64; break; case 100: texmod=0; break; default: texmod=255; } eglGenTextures(1,&_modulateTexnum); eglBindTexture(GL_TEXTURE_2D,_modulateTexnum); eglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _openGLFilter?GL_LINEAR:GL_NEAREST); eglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _openGLFilter?GL_LINEAR:GL_NEAREST); Uint8 modulate_texture[]={ 255,255,255, 0,0,0}; modulate_texture[3]=texmod; modulate_texture[4]=texmod; modulate_texture[5]=texmod; eglTexImage2D(GL_TEXTURE_2D, 0,GL_RGB8,1,2, 0,GL_RGB,GL_UNSIGNED_BYTE, modulate_texture); } eglViewport(0,0,w,h); eglMatrixMode(GL_PROJECTION); eglLoadIdentity(); eglOrtho(0,w,h,0,-1.0, 1.0); eglMatrixMode(GL_MODELVIEW); eglLoadIdentity(); // _publicVideo=SDL_CreateRGBSurface(SDL_SWSURFACE,CPCVisibleSCRWidth,CPCVisibleSCRHeight,surface_bpp,0,0,0,0); return _publicVideo; }