void RfxState::SetTextureEnvironment(GLint target) { switch (state) { case GL_TextureWrapS: glTexParameteri(target, GL_TEXTURE_WRAP_S, GLWrapMode()); break; case GL_TextureWrapT: glTexParameteri(target, GL_TEXTURE_WRAP_T, GLWrapMode()); break; case GL_TextureWrapR: glTexParameteri(target, GL_TEXTURE_WRAP_R, GLWrapMode()); break; case GL_TextureMinify: glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GLFilterMode()); break; case GL_TextureMagnify: glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GLFilterMode()); break; case GL_TextureBorderColor: glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, DecodeColor(value)); break; case GL_TextureMaxAnisotropyEXT: glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, value); break; case GL_TextureLODBias: glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, value); break; default: // do nothing, unsupported state break; } }
/*** * conversion functions from enum to strings for gui use */ QString RfxState::GetTextureValue() { switch (state) { case GL_TextureWrapS: case GL_TextureWrapT: case GL_TextureWrapR: return TextureWrapStrings[value - 1]; case GL_TextureMinify: case GL_TextureMagnify: return TextureFilterStrings[value]; case GL_TextureBorderColor: { return ColorToString(DecodeColor(value)); } case GL_TextureMaxAnisotropyEXT: case GL_TextureLODBias: return QString().setNum(value); default: return ""; } }
QString RfxState::GetRenderValue() { switch (state) { case GL_CurrentColor: case GL_SecondaryColor: case GL_ClearColor: case GL_FogColor: case GL_BlendColor: return ColorToString(DecodeColor(value)); case GL_ClearDepth: case GL_DepthNear: case GL_DepthFar: case GL_FogDensity: case GL_FogStart: case GL_FogEnd: case GL_PointSize: case GL_PointMin: case GL_PointMax: case GL_LineWidth: case GL_PolyOffsetFactor: case GL_PolyOffsetUnits: case GL_AlphaReference: case GL_StencilValueMask: case GL_StencilReference: case GL_ClearStencil: case GL_WriteMaskStencil: return QString().setNum(value); case GL_EdgeFlag: case GL_PointSmooth: case GL_LineSmooth: case GL_PolySmooth: case GL_PolyOffsetPoint: case GL_PolyOffsetLine: case GL_PolyOffsetFill: case GL_AlphaEnable: case GL_DepthEnable: case GL_BlendEnable: case GL_WriteMaskDepth: case GL_VertexProgramTwoSideARB: case GL_StencilEnable: return (value == 1)? "TRUE" : "FALSE"; case GL_ShadeModel: return (value == 1)? "FLAT_SHADE" : "SMOOTH_SHADE"; case GL_FrontFace: return (value == 1)? "CCW" : "CW"; case GL_CullMode: switch (value) { case 1: return "NONE"; case 2: return "FRONT"; case 3: return "BACK"; case 4: return "FRONT_AND_BACK"; default: return ""; } case GL_FogMode: switch (value) { case 1: return "NONE"; case 2: return "LINEAR"; case 3: return "EXP"; case 4: return "EXP2"; default: return ""; } case GL_PolyFrontMode: case GL_PolyBackMode: return (value == 1)? "POINTS" : ((value == 2)? "LINES" : "FILL"); case GL_AlphaFunction: case GL_DepthFunction: case GL_StencilFunction: return RenderFunctionStrings[value - 1]; case GL_BlendSourceRGB: case GL_BlendDestRGB: case GL_BlendSourceAlpha: case GL_BlendDestAlpha: return RenderColorStrings[value - 1]; case GL_BlendEquation: switch (value) { case 1: return "ADD"; case 2: return "SUBTRACT"; case 3: return "REV_SUBTRACT"; case 4: return "MIN"; case 5: return "MAX"; default: return ""; } case GL_StencilFail: case GL_StencilPassDepthFail: case GL_StencilPassDepthPass: switch (value) { case GL_ZERO: return "ZERO"; case GL_KEEP: return "KEEP"; case GL_REPLACE: return "REPLACE"; case GL_INCR: return "INCR"; case GL_DECR: return "DECR"; case GL_INVERT: return "INVERT"; case GL_INCR_WRAP: return "INCR_WRAP"; case GL_DECR_WRAP: return "DECR_WRAP"; default: return ""; } case GL_WriteMaskColor: { GLint val = (GLint)value; QString retCol; if (val > 8) { retCol.append("ALPHA "); val -= 8; } if (val > 4) { retCol.append("BLUE "); val -= 4; } if (val > 2) { retCol.append("GREEN "); val -= 2; } if (val > 1) { retCol.append("RED"); val -= 1; } return retCol; } default: return ""; } }
void RfxState::SetGLEnvironment() { switch (state) { case GL_CurrentColor: { GLfloat *res = DecodeColor(value); glColor3f(res[0], res[1], res[2]); delete res; } case GL_SecondaryColor: { GLfloat *res = DecodeColor(value); glSecondaryColor3f(res[0], res[1], res[2]); delete res; break; } case GL_ClearColor: { GLfloat *res = DecodeColor(value); glClearColor(res[0], res[1], res[2], res[3]); delete res; break; } case GL_ClearDepth: glClearDepth(value); break; case GL_ShadeModel: glShadeModel((value == 1)? GL_FLAT : GL_SMOOTH); break; case GL_FrontFace: glFrontFace((value == 1)? GL_CCW : GL_CW); break; case GL_CullMode: if (value == 1) { glDisable(GL_CULL_FACE); } else { glEnable(GL_CULL_FACE); glCullFace((value == 2)? GL_FRONT : ((value == 3)? GL_BACK : GL_FRONT_AND_BACK)); } break; case GL_EdgeFlag: glEdgeFlag(value); break; case GL_DepthNear: case GL_DepthFar: { GLfloat range[2]; glGetFloatv(GL_DEPTH_RANGE, range); if (state == GL_DepthNear) glDepthRange(value, range[1]); else glDepthRange(range[0], value); break; } case GL_FogColor: { glFogfv(GL_FOG_COLOR, DecodeColor(value)); break; } case GL_FogDensity: glFogi(GL_FOG_DENSITY, value); break; case GL_FogStart: glFogi(GL_FOG_START, value); break; case GL_FogEnd: glFogi(GL_FOG_END, value); break; case GL_FogMode: glEnable(GL_FOG); switch ((GLint)value) { case 1: // NONE glDisable(GL_FOG); break; case 2: // LINEAR glFogi(GL_FOG_MODE, GL_LINEAR); break; case 3: // EXP glFogi(GL_FOG_MODE, GL_EXP); break; case 4: // EXP2 glFogi(GL_FOG_MODE, GL_EXP2); break; default: // UNKNOWN break; } break; case GL_PointSize: glPointSize(value); break; case GL_PointMin: glPointParameterf(GL_POINT_SIZE_MIN, value); break; case GL_PointMax: glPointParameterf(GL_POINT_SIZE_MAX_ARB, value); break; case GL_PointSmooth: GLEnableDisable(GL_POINT_SMOOTH); break; case GL_LineWidth: glLineWidth(value); break; case GL_LineSmooth: GLEnableDisable(GL_LINE_SMOOTH); break; case GL_PolyFrontMode: glPolygonMode(GL_FRONT, (value == 1)? GL_POINT : ((value == 2)? GL_LINE : GL_FILL)); break; case GL_PolyBackMode: glPolygonMode(GL_BACK, (value == 1)? GL_POINT : ((value == 2)? GL_LINE : GL_FILL)); break; case GL_PolySmooth: GLEnableDisable(GL_POLYGON_SMOOTH); break; case GL_PolyOffsetFactor: { GLfloat units; glGetFloatv(GL_POLYGON_OFFSET_UNITS, &units); glPolygonOffset(value, units); break; } case GL_PolyOffsetUnits: { GLfloat factor; glGetFloatv(GL_POLYGON_OFFSET_FACTOR, &factor); glPolygonOffset(factor, value); break; } case GL_PolyOffsetPoint: GLEnableDisable(GL_POLYGON_OFFSET_POINT); break; case GL_PolyOffsetLine: GLEnableDisable(GL_POLYGON_OFFSET_LINE); break; case GL_PolyOffsetFill: GLEnableDisable(GL_POLYGON_OFFSET_FILL); break; case GL_AlphaEnable: GLEnableDisable(GL_ALPHA_TEST); break; case GL_AlphaFunction: { GLfloat ref; glGetFloatv(GL_ALPHA_TEST_REF, &ref); glAlphaFunc(GLFunctionMode(), ref); break; } case GL_AlphaReference: { GLint func; glGetIntegerv(GL_ALPHA_TEST_FUNC, &func); glAlphaFunc(func, value); break; } case GL_DepthEnable: GLEnableDisable(GL_DEPTH_TEST); break; case GL_DepthFunction: glDepthFunc(GLFunctionMode()); break; case GL_BlendEnable: GLEnableDisable(GL_BLEND); break; case GL_BlendColor: { GLfloat *res = DecodeColor(value); glBlendColor(res[0], res[1], res[2], res[3]); delete res; break; } case GL_BlendSourceRGB: case GL_BlendDestRGB: case GL_BlendSourceAlpha: case GL_BlendDestAlpha: { GLint srcdst[4]; glGetIntegerv(GL_BLEND_SRC_RGB, &srcdst[0]); glGetIntegerv(GL_BLEND_DST_RGB, &srcdst[1]); glGetIntegerv(GL_BLEND_SRC_ALPHA, &srcdst[2]); glGetIntegerv(GL_BLEND_DST_ALPHA, &srcdst[3]); glBlendFuncSeparate( ((state == GL_BlendSourceRGB)? GLColorMode() : srcdst[0]), ((state == GL_BlendDestRGB)? GLColorMode() : srcdst[1]), ((state == GL_BlendSourceAlpha)? GLColorMode() : srcdst[2]), ((state == GL_BlendDestAlpha)? GLColorMode() : srcdst[3])); break; } case GL_BlendEquation: switch ((GLint)value) { case 1: // ADD glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); break; case 2: // SUBTRACT glBlendEquationSeparate(GL_FUNC_SUBTRACT, GL_FUNC_SUBTRACT); break; case 3: // REV_SUBTRACT glBlendEquationSeparate(GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT); break; case 4: // MIN glBlendEquationSeparate(GL_MIN, GL_MIN); break; case 5: // MAX glBlendEquationSeparate(GL_MAX, GL_MAX); break; } break; case GL_WriteMaskColor: { GLint val = (GLint)value; GLboolean par[4]; par[3] = (val > 8)? GL_TRUE : GL_FALSE; par[2] = (val -= (8 * par[3]) > 4)? GL_TRUE : GL_FALSE; par[1] = (val -= (4 * par[2]) > 2)? GL_TRUE : GL_FALSE; par[0] = (val -= (2 * par[1]) > 1)? GL_TRUE : GL_FALSE; glColorMask(par[0], par[1], par[2], par[3]); break; } case GL_WriteMaskDepth: glDepthMask(value); break; case GL_VertexProgramTwoSideARB: GLEnableDisable(GL_VERTEX_PROGRAM_TWO_SIDE_ARB); break; case GL_StencilEnable: GLEnableDisable(GL_STENCIL_TEST); break; case GL_StencilFunction: case GL_StencilValueMask: case GL_StencilReference: { GLint StFun[3]; glGetIntegerv(GL_STENCIL_FUNC, &StFun[0]); glGetIntegerv(GL_STENCIL_VALUE_MASK, &StFun[1]); glGetIntegerv(GL_STENCIL_REF, &StFun[2]); glStencilFunc( (state == GL_StencilFunction)? GLFunctionMode() : StFun[0], (state == GL_StencilValueMask)? value : StFun[1], (state == GL_StencilReference)? value : StFun[2]); break; } case GL_StencilFail: case GL_StencilPassDepthFail: case GL_StencilPassDepthPass: { GLint StOp[3]; glGetIntegerv(GL_STENCIL_FAIL, &StOp[0]); glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &StOp[1]); glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &StOp[2]); // thanks god at least these values are equivalent to OpenGL ones, // no mapping needed. glStencilOp( (state == GL_StencilFail)? value : StOp[0], (state == GL_StencilPassDepthFail)? value : StOp[1], (state == GL_StencilPassDepthPass)? value : StOp[2]); break; } case GL_WriteMaskStencil: glStencilMask(value); break; case GL_ClearStencil: glClearStencil(value); break; default: // do nothing, unsupported state break; } }
// When we're converting, only convert the w*h area(AKA leave the last part of the line, pitch32 - w, alone), // for places where we store auxillary information there(graphics viewer in the debugger), and it'll be faster // to boot. void MDFN_Surface::SetFormat(const MDFN_PixelFormat &nf, bool convert) { assert(format.bpp == 16 || format.bpp == 32); assert(nf.bpp == 16 || nf.bpp == 32); if(nf.bpp == 16) { } else { assert((nf.Rshift + nf.Gshift + nf.Bshift + nf.Ashift) == 48); assert(!((nf.Rshift | nf.Gshift | nf.Bshift | nf.Ashift) & 0x7)); } #ifdef CONFIG_SUPPORT_32BPP if(nf.bpp != format.bpp) { void *rpix = calloc(1, pitchinpix * h * (nf.bpp / 8)); void *oldpix; if(nf.bpp == 16) // 32bpp to 16bpp { pixels16 = (uint16 *)rpix; if(convert) { MDFN_printf("32bpp to 16bpp convert"); for(int y = 0; y < h; y++) { uint32 *srow = &pixels[y * pitchinpix]; uint16 *drow = &pixels16[y * pitchinpix]; for(int x = 0; x < w; x++) { uint32 c = srow[x]; int r, g, b, a; DecodeColor(c, r, g, b, a); drow[x] = nf.MakeColor(r, g, b, a); } } } oldpix = pixels; pixels = NULL; } else // 16bpp to 32bpp { pixels = (uint32 *)rpix; if(convert) { MDFN_printf("16bpp to 32bpp convert"); for(int y = 0; y < h; y++) { uint16 *srow = &pixels16[y * pitchinpix]; uint32 *drow = &pixels[y * pitchinpix]; for(int x = 0; x < w; x++) { uint32 c = srow[x]; int r, g, b, a; DecodeColor(c, r, g, b, a); drow[x] = nf.MakeColor(r, g, b, a); } } } oldpix = pixels16; pixels16 = NULL; } if(oldpix && !pixels_is_external) free(oldpix); pixels_is_external = false; // We already handled surface conversion above. convert = false; } #endif if(convert) { if(format.bpp == 16) { // We should assert that surface->pixels is non-NULL even if we don't need to convert the surface, to catch more insidious bugs. assert(pixels16); if(memcmp(&format, &nf, sizeof(MDFN_PixelFormat))) { //puts("Converting"); for(int y = 0; y < h; y++) { uint16 *row = &pixels16[y * pitchinpix]; for(int x = 0; x < w; x++) { uint32 c = row[x]; int r, g, b, a; DecodeColor(c, r, g, b, a); row[x] = nf.MakeColor(r, g, b, a); } } } } #ifdef CONFIG_SUPPORT_32BPP else { // We should assert that surface->pixels is non-NULL even if we don't need to convert the surface, to catch more insidious bugs. assert(pixels); if(memcmp(&format, &nf, sizeof(MDFN_PixelFormat))) { //puts("Converting"); for(int y = 0; y < h; y++) { uint32 *row = &pixels[y * pitchinpix]; for(int x = 0; x < w; x++) { uint32 c = row[x]; int r, g, b, a; DecodeColor(c, r, g, b, a); row[x] = nf.MakeColor(r, g, b, a); } } } } #endif } format = nf; }