diff --git a/src/interfaces/graphic.h b/src/interfaces/graphic.h index ac0a893f8..b9e55e8c7 100755 --- a/src/interfaces/graphic.h +++ b/src/interfaces/graphic.h @@ -37,11 +37,19 @@ #define GR_ATT_SOUND_VOLUME "volume" #define GR_SCT_GLFEATURES "OpenGL Features" -#define GR_ATT_TEXTURECOMPRESSION "texture compression ARB" +#define GR_ATT_TEXTURECOMPRESSION "texture compression" #define GR_ATT_TEXTURECOMPRESSION_ENABLED "enabled" #define GR_ATT_TEXTURECOMPRESSION_DISABLED "disabled" -#define GR_ATT_TEXTURESIZE "user texture sizelimit" +#define GR_ATT_MAXTEXTURESIZE "max texture size" + +#define GR_ATT_MULTISAMPLING "multi-sampling" +#define GR_ATT_MULTISAMPLING_ENABLED "enabled" +#define GR_ATT_MULTISAMPLING_DISABLED "disabled" + +#define GR_ATT_MULTITEXTURING "multi-texturing" +#define GR_ATT_MULTITEXTURING_ENABLED "enabled" +#define GR_ATT_MULTITEXTURING_DISABLED "disabled" #define GR_SCT_DISPMODE "Display Mode" #define GR_ATT_CAM "camera" diff --git a/src/libs/client/entry.cpp b/src/libs/client/entry.cpp index 282532b1b..854e19d5e 100644 --- a/src/libs/client/entry.cpp +++ b/src/libs/client/entry.cpp @@ -21,6 +21,7 @@ #include #include "client.h" +#include "openglconfig.h" #include "splash.h" /* @@ -42,8 +43,11 @@ bool MenuEntry(void) { - // Initialize gaming framework. + // Initialize gaming framework UI. GfInitClient(); + GfglFeatures::self()->setSelectionLoader(OpenGLLoadSelectedFeatures); + GfglFeatures::self()->setSelectionStorer(OpenGLStoreSelectedFeatures); + GfglFeatures::self()->loadSelection(); // Open the splash screen, load menus in "backgroud" and finally open the main menu. return SplashScreen(); diff --git a/src/libs/confscreens/displayconfig.cpp b/src/libs/confscreens/displayconfig.cpp index d15a52759..5e6da4fe4 100755 --- a/src/libs/confscreens/displayconfig.cpp +++ b/src/libs/confscreens/displayconfig.cpp @@ -118,7 +118,7 @@ void DisplayMenu::onAccept(void *pDisplayMenu) GfScrShutdown(); // Restart the game. - GfRestart(GfuiMouseIsHWPresent(), GfglIsMultiTexturingEnabled()); + GfRestart(GfuiMouseIsHWPresent()); // TODO: A nice system to get back to previous display settings if the chosen ones // keep the game from really restarting (ex: unsupported full screen size) ? diff --git a/src/libs/confscreens/openglconfig.cpp b/src/libs/confscreens/openglconfig.cpp index 10e0da6a7..9f16a9f09 100644 --- a/src/libs/confscreens/openglconfig.cpp +++ b/src/libs/confscreens/openglconfig.cpp @@ -22,64 +22,232 @@ @version $Id$ */ -#include -#include +#include +#include #include -#include #include -#include +#include +#include + #include "openglconfig.h" -#include "gui.h" + // Texture compression. -static const char *textureCompressOptionList[] = {GR_ATT_TEXTURECOMPRESSION_DISABLED, GR_ATT_TEXTURECOMPRESSION_ENABLED}; -static const int nbOptionsTextComp = sizeof(textureCompressOptionList) / sizeof(textureCompressOptionList[0]); -static int curOptionTextComp = 0; -static int TextureCompressOptionId; +static const char *ATextureCompTexts[] = + {GR_ATT_TEXTURECOMPRESSION_DISABLED, GR_ATT_TEXTURECOMPRESSION_ENABLED}; +static const int NTextureComps = + sizeof(ATextureCompTexts) / sizeof(ATextureCompTexts[0]); +static int NCurTextureCompIndex = 0; +static int TextureCompLabelId; +static int TextureCompLeftButtonId; +static int TextureCompRightButtonId; -// Texture sizing, order of list is important, do not change. -static int textureSizeOptionList[] = {8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384}; -static int nbOptionsTextSize = sizeof(textureSizeOptionList) / sizeof(textureSizeOptionList[0]); -static int curOptionTextSize = 0; -static int TextureSizeOptionId; -static const int defaultTextSize = 64; // In case everything goes wrong. -static char valuebuf[10]; +// Max texture size (WARNING: the order in the list is important, do not change). +static int AMaxTextureSizeTexts[] = {8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384}; +static int NMaxTextureSizes = sizeof(AMaxTextureSizeTexts) / sizeof(AMaxTextureSizeTexts[0]); +static int NCurMaxTextureSizeIndex = 0; +static int MaxTextureSizeLabelId; -// gui screen handles. -static void *scrHandle = NULL; -static void *prevHandle = NULL; +static const int NDefaultTextSize = 64; // In case everything goes wrong. + +// Multi-texturing. +static const char *AMultiTextureTexts[] = + {GR_ATT_MULTITEXTURING_DISABLED, GR_ATT_MULTITEXTURING_ENABLED}; +static const int NMultiTextures = + sizeof(AMultiTextureTexts) / sizeof(AMultiTextureTexts[0]); +static int NCurMultiTextureIndex = 0; + +static int MultiTextureLabelId; +static int MultiTextureLeftButtonId; +static int MultiTextureRightButtonId; + +// Multi-sampling. +static const char *AMultiSampleTexts[] = + {GR_ATT_MULTISAMPLING_DISABLED, GR_ATT_MULTISAMPLING_ENABLED}; +static const int NMultiSamples = + sizeof(AMultiSampleTexts) / sizeof(AMultiSampleTexts[0]); +static int NCurMultiSampleIndex = 0; + +static int MultiSampleLabelId; +static int MultiSampleLeftButtonId; +static int MultiSampleRightButtonId; + +// GUI screen handles. +static void *ScrHandle = NULL; +static void *PrevHandle = NULL; -// Read OpenGL configuration. -static void readOpenGLCfg(void) +void OpenGLLoadSelectedFeatures() { int i; - char buf[1024]; + char buf[512]; - sprintf(buf, "%s%s", GetLocalDir(), GR_PARAM_FILE); + // Read OpenGL configuration from graph.xml, and select relevant OpenGL features. + snprintf(buf, sizeof(buf), "%s%s", GetLocalDir(), GR_PARAM_FILE); + void* paramHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT); + + // 1) Texture compression. + const char* pszTexComp = + GfParmGetStr(paramHandle, GR_SCT_GLFEATURES, GR_ATT_TEXTURECOMPRESSION, + GR_ATT_TEXTURECOMPRESSION_DISABLED); + GfglFeatures::self()->select(GfglFeatures::TextureCompression, + strcmp(pszTexComp, GR_ATT_TEXTURECOMPRESSION_ENABLED) ? false : true); + + // 2) Max texture size. + const int sizelimit = + GfglFeatures::self()->getSupported(GfglFeatures::TextureMaxSize); + int tsize = + (int)GfParmGetNum(paramHandle, GR_SCT_GLFEATURES, GR_ATT_MAXTEXTURESIZE, + (char*)NULL, (tdble)sizelimit); + if (tsize > sizelimit) + tsize = sizelimit; + + GfglFeatures::self()->select(GfglFeatures::TextureMaxSize, tsize); + + // 3) Multi-texturing. + const char* pszMultiTex = + GfParmGetStr(paramHandle, GR_SCT_GLFEATURES, GR_ATT_MULTITEXTURING, + GR_ATT_MULTITEXTURING_DISABLED); + GfglFeatures::self()->select(GfglFeatures::MultiTexturing, + strcmp(pszMultiTex, GR_ATT_MULTITEXTURING_ENABLED) ? false : true); + + // 4) Multi-sampling. + const char* pszMultiSamp = + GfParmGetStr(paramHandle, GR_SCT_GLFEATURES, GR_ATT_MULTISAMPLING, + GR_ATT_MULTISAMPLING_DISABLED); + GfglFeatures::self()->select(GfglFeatures::MultiSampling, + strcmp(pszMultiSamp, GR_ATT_MULTISAMPLING_ENABLED) ? false : true); + + // Close graphic params. + GfParmReleaseHandle(paramHandle); +} + + +// Save the choosen values in the corresponding parameter file. +void OpenGLStoreSelectedFeatures() +{ + // Save settings to graph.xml + char buf[512]; + snprintf(buf, sizeof(buf), "%s%s", GetLocalDir(), GR_PARAM_FILE); void *paramHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT); - // Read texture compression parameters. - const char *optionName = GfParmGetStr(paramHandle, GR_SCT_GLFEATURES, GR_ATT_TEXTURECOMPRESSION, textureCompressOptionList[0]); - for (i = 0; i < nbOptionsTextComp; i++) { - if (strcmp(optionName, textureCompressOptionList[i]) == 0) { - curOptionTextComp = i; - break; + GfParmSetStr(paramHandle, GR_SCT_GLFEATURES, GR_ATT_TEXTURECOMPRESSION, + GfglFeatures::self()->isSelected(GfglFeatures::TextureCompression) + ? GR_ATT_TEXTURECOMPRESSION_ENABLED : GR_ATT_TEXTURECOMPRESSION_DISABLED); + GfParmSetNum(paramHandle, GR_SCT_GLFEATURES, GR_ATT_MAXTEXTURESIZE, (char*)NULL, + (tdble)GfglFeatures::self()->getSelected(GfglFeatures::TextureMaxSize)); + GfParmSetStr(paramHandle, GR_SCT_GLFEATURES, GR_ATT_MULTITEXTURING, + GfglFeatures::self()->isSelected(GfglFeatures::MultiTexturing) + ? GR_ATT_MULTITEXTURING_ENABLED : GR_ATT_MULTITEXTURING_DISABLED); + GfParmSetStr(paramHandle, GR_SCT_GLFEATURES, GR_ATT_MULTISAMPLING, + GfglFeatures::self()->isSelected(GfglFeatures::MultiSampling) + ? GR_ATT_MULTISAMPLING_ENABLED : GR_ATT_MULTISAMPLING_DISABLED); + + GfParmWriteFile(NULL, paramHandle, "graph"); + GfParmReleaseHandle(paramHandle); +} + +static void onAccept(void *) +{ + // Store current state of settings to the GL features layer. + GfglFeatures::self()->select(GfglFeatures::TextureCompression, + strcmp(ATextureCompTexts[NCurTextureCompIndex], + GR_ATT_TEXTURECOMPRESSION_ENABLED) ? false : true); + GfglFeatures::self()->select(GfglFeatures::TextureMaxSize, + AMaxTextureSizeTexts[NCurMaxTextureSizeIndex]); + GfglFeatures::self()->select(GfglFeatures::MultiTexturing, + strcmp(AMultiTextureTexts[NCurMultiTextureIndex], + GR_ATT_MULTITEXTURING_ENABLED) ? false : true); + GfglFeatures::self()->select(GfglFeatures::MultiSampling, + strcmp(AMultiSampleTexts[NCurMultiSampleIndex], + GR_ATT_MULTISAMPLING_ENABLED) ? false : true); + + // Store settings from the GL features layer to the graph.xml file. + GfglFeatures::self()->storeSelection(); + + // Return to previous screen. + GfuiScreenActivate(PrevHandle); +} + +// Toggle texture compression state enabled/disabled. +static void changeTextureCompressionState(void *vp) +{ + NCurTextureCompIndex = (NCurTextureCompIndex + (int)(long)vp + NTextureComps) % NTextureComps; + GfuiLabelSetText(ScrHandle, TextureCompLabelId, ATextureCompTexts[NCurTextureCompIndex]); +} + +// Toggle multi-texturing state enabled/disabled. +static void changeMultiTextureState(void *vp) +{ + NCurMultiTextureIndex = (NCurMultiTextureIndex + (int)(long)vp + NMultiTextures) % NMultiTextures; + GfuiLabelSetText(ScrHandle, MultiTextureLabelId, AMultiTextureTexts[NCurMultiTextureIndex]); +} + +// Toggle multi-sampling state enabled/disabled. +static void changeMultiSampleState(void *vp) +{ + NCurMultiSampleIndex = (NCurMultiSampleIndex + (int)(long)vp + NMultiSamples) % NMultiSamples; + GfuiLabelSetText(ScrHandle, MultiSampleLabelId, AMultiSampleTexts[NCurMultiSampleIndex]); +} + + +// Scroll through texture sizes smaller or equal the system limit. +static void changeMaxTextureSizeState(void *vp) +{ + char valuebuf[10]; + + long delta = (long)vp; + NCurMaxTextureSizeIndex += delta; + if (NCurMaxTextureSizeIndex < 0) { + NCurMaxTextureSizeIndex = NMaxTextureSizes - 1; + } else if (NCurMaxTextureSizeIndex >= NMaxTextureSizes) { + NCurMaxTextureSizeIndex= 0; + } + + snprintf(valuebuf, sizeof(valuebuf), "%d", AMaxTextureSizeTexts[NCurMaxTextureSizeIndex]); + GfuiLabelSetText(ScrHandle, MaxTextureSizeLabelId, valuebuf); +} + + +static void onActivate(void * /* dummy */) +{ + int i; + char valuebuf[10]; + + // Initialize current state and GUI from the GL features layer. + // 1) Texture compression. + if (GfglFeatures::self()->isSupported(GfglFeatures::TextureCompression)) + { + const char *pszTexComp = + GfglFeatures::self()->isSelected(GfglFeatures::TextureCompression) + ? GR_ATT_TEXTURECOMPRESSION_ENABLED : GR_ATT_TEXTURECOMPRESSION_DISABLED; + for (i = 0; i < NTextureComps; i++) { + if (!strcmp(pszTexComp, ATextureCompTexts[i])) { + NCurTextureCompIndex = i; + break; + } } + + GfuiLabelSetText(ScrHandle, TextureCompLabelId, + ATextureCompTexts[NCurTextureCompIndex]); } - if (GfglIsCompressARBAvailable()) { - GfuiLabelSetText(scrHandle, TextureCompressOptionId, textureCompressOptionList[curOptionTextComp]); + else + { + GfuiEnable(ScrHandle, TextureCompLeftButtonId, GFUI_DISABLE); + GfuiEnable(ScrHandle, TextureCompRightButtonId, GFUI_DISABLE); + GfuiLabelSetText(ScrHandle, TextureCompLabelId, "Not supported"); } - // Read texture sizing parameters. + // 2) Max texture size. + int sizelimit = + GfglFeatures::self()->getSupported(GfglFeatures::TextureMaxSize); + int tsize = + GfglFeatures::self()->getSelected(GfglFeatures::TextureMaxSize); + int maxsizenb = 0; - int sizelimit = GfglGetGLTextureMaxSize(); - int tsize = (int) GfParmGetNum(paramHandle, GR_SCT_GLFEATURES, GR_ATT_TEXTURESIZE, (char*)NULL, (tdble) sizelimit); - bool found = false; - - for (i = 0; i < nbOptionsTextSize; i++) { - if (textureSizeOptionList[i] <= sizelimit) { + for (i = 0; i < NMaxTextureSizes; i++) { + if (AMaxTextureSizeTexts[i] <= sizelimit) { maxsizenb = i; } else { break; @@ -87,11 +255,12 @@ static void readOpenGLCfg(void) } // Limit to available sizes. - nbOptionsTextSize = maxsizenb+1; + NMaxTextureSizes = maxsizenb + 1; - for (i = 0; i < nbOptionsTextSize; i++) { - if (textureSizeOptionList[i] == tsize) { - curOptionTextSize = i; + bool found = false; + for (i = 0; i < NMaxTextureSizes; i++) { + if (AMaxTextureSizeTexts[i] == tsize) { + NCurMaxTextureSizeIndex = i; found = true; break; } @@ -99,126 +268,126 @@ static void readOpenGLCfg(void) if (!found) { // Should never come here if there is no bug in OpenGL. - tsize = defaultTextSize; - for (i = 0; i < nbOptionsTextSize; i++) { - if (textureSizeOptionList[i] == tsize) { - curOptionTextSize = i; + tsize = NDefaultTextSize; + for (i = 0; i < NMaxTextureSizes; i++) { + if (AMaxTextureSizeTexts[i] == tsize) { + NCurMaxTextureSizeIndex = i; break; } } } - sprintf(valuebuf, "%d", textureSizeOptionList[curOptionTextSize]); - GfuiLabelSetText(scrHandle, TextureSizeOptionId, valuebuf); - - GfParmReleaseHandle(paramHandle); -} - - -// Save the choosen values in the corresponding parameter file. -static void saveOpenGLOption(void *) -{ - char buf[1024]; - sprintf(buf, "%s%s", GetLocalDir(), GR_PARAM_FILE); - void *paramHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT); - - // Texture compression. - GfParmSetStr(paramHandle, GR_SCT_GLFEATURES, GR_ATT_TEXTURECOMPRESSION, textureCompressOptionList[curOptionTextComp]); - // Texture sizing. - GfParmSetNum(paramHandle, GR_SCT_GLFEATURES, GR_ATT_TEXTURESIZE, (char*)NULL, (tdble) textureSizeOptionList[curOptionTextSize]); - - GfParmWriteFile(NULL, paramHandle, "graph"); - GfParmReleaseHandle(paramHandle); - - // Return to previous screen. - GfuiScreenActivate(prevHandle); - GfglUpdateCompressARBEnabled(); - GfglUpdateUserTextureMaxSize(); - return; -} - - -// Toggle texture compression state enabled/disabled. -static void changeTextureCompressState(void *vp) -{ - if (vp == 0) { - curOptionTextComp--; - if (curOptionTextComp < 0) { - curOptionTextComp = nbOptionsTextComp - 1; + + snprintf(valuebuf, sizeof(valuebuf), "%d", AMaxTextureSizeTexts[NCurMaxTextureSizeIndex]); + GfuiLabelSetText(ScrHandle, MaxTextureSizeLabelId, valuebuf); + + // 3) Multi-texturing. + if (GfglFeatures::self()->isSupported(GfglFeatures::MultiTexturing)) + { + const char *pszMultiTex = + GfglFeatures::self()->isSelected(GfglFeatures::MultiTexturing) + ? GR_ATT_MULTITEXTURING_ENABLED : GR_ATT_MULTITEXTURING_DISABLED; + for (i = 0; i < NMultiTextures; i++) { + if (!strcmp(pszMultiTex, AMultiTextureTexts[i])) { + NCurMultiTextureIndex = i; + break; + } } - } else { - curOptionTextComp++; - if (curOptionTextComp == nbOptionsTextComp) { - curOptionTextComp = 0; + + GfuiLabelSetText(ScrHandle, MultiTextureLabelId, + AMultiTextureTexts[NCurMultiTextureIndex]); + } + else + { + GfuiEnable(ScrHandle, MultiTextureLeftButtonId, GFUI_DISABLE); + GfuiEnable(ScrHandle, MultiTextureRightButtonId, GFUI_DISABLE); + GfuiLabelSetText(ScrHandle, MultiTextureLabelId, "Not supported"); + } + + // 4) Multi-sampling. + if (GfglFeatures::self()->isSupported(GfglFeatures::MultiSampling)) + { + const char *pszMultiSamp = + GfglFeatures::self()->isSelected(GfglFeatures::MultiSampling) + ? GR_ATT_MULTISAMPLING_ENABLED : GR_ATT_MULTISAMPLING_DISABLED; + for (i = 0; i < NMultiSamples; i++) { + if (!strcmp(pszMultiSamp, AMultiSampleTexts[i])) { + NCurMultiSampleIndex = i; + break; + } } + + GfuiLabelSetText(ScrHandle, MultiSampleLabelId, + AMultiSampleTexts[NCurMultiSampleIndex]); } - GfuiLabelSetText(scrHandle, TextureCompressOptionId, textureCompressOptionList[curOptionTextComp]); -} - - -// Scroll through texture sizes smaller or equal the system limit. -static void changeTextureSizeState(void *vp) -{ - long delta = (long)vp; - curOptionTextSize += delta; - if (curOptionTextSize < 0) { - curOptionTextSize = nbOptionsTextSize - 1; - } else if (curOptionTextSize >= nbOptionsTextSize) { - curOptionTextSize= 0; + else + { + GfuiEnable(ScrHandle, MultiSampleLeftButtonId, GFUI_DISABLE); + GfuiEnable(ScrHandle, MultiSampleRightButtonId, GFUI_DISABLE); + GfuiLabelSetText(ScrHandle, MultiSampleLabelId, "Not supported"); } - - sprintf(valuebuf, "%d", textureSizeOptionList[curOptionTextSize]); - GfuiLabelSetText(scrHandle, TextureSizeOptionId, valuebuf); -} - - -static void onActivate(void * /* dummy */) -{ - readOpenGLCfg(); } // OpenGL menu -void * OpenGLMenuInit(void *prevMenu) +void* OpenGLMenuInit(void *prevMenu) { // Has screen already been created? - if (scrHandle) { - return scrHandle; + if (ScrHandle) { + return ScrHandle; } - prevHandle = prevMenu; - - scrHandle = GfuiScreenCreateEx((float*)NULL, NULL, onActivate, NULL, (tfuiCallback)NULL, 1); - void *param = LoadMenuXML("opengloptionsmenu.xml"); - CreateStaticControls(param,scrHandle); + PrevHandle = prevMenu; + ScrHandle = GfuiScreenCreateEx((float*)NULL, NULL, onActivate, NULL, (tfuiCallback)NULL, 1); + void *param = LoadMenuXML("opengloptionsmenu.xml"); + CreateStaticControls(param,ScrHandle); // Texture compression. - if (GfglIsCompressARBAvailable()) { - CreateButtonControl(scrHandle,param,"compressleftarrow",(void*)-1, changeTextureCompressState); - CreateButtonControl(scrHandle,param,"compressrightarrow",(void*)1, changeTextureCompressState); - TextureCompressOptionId = CreateLabelControl(scrHandle,param,"compressiontext"); - } else { - CreateLabelControl(scrHandle,param,"na"); - } - + TextureCompLeftButtonId = + CreateButtonControl(ScrHandle, param, "TextureCompressionLeftArrowButton", (void*)-1, + changeTextureCompressionState); + TextureCompRightButtonId = + CreateButtonControl(ScrHandle, param, "TextureCompressionRightArrowButton", (void*)+1, + changeTextureCompressionState); + TextureCompLabelId = CreateLabelControl(ScrHandle,param,"TextureCompressionLabel"); // Texture sizing. - CreateButtonControl(scrHandle,param,"textureleftarrow",(void*)-1, changeTextureSizeState); - CreateButtonControl(scrHandle,param,"texturerightarrow",(void*)1, changeTextureSizeState); - TextureSizeOptionId = CreateLabelControl(scrHandle,param,"texturetext"); + CreateButtonControl(ScrHandle,param,"MaxTextureSizeLeftArrowButton", (void*)-1, + changeMaxTextureSizeState); + CreateButtonControl(ScrHandle,param,"MaxTextureSizeRightArrowButton", (void*)+1, + changeMaxTextureSizeState); + MaxTextureSizeLabelId = CreateLabelControl(ScrHandle,param,"MaxTextureSizeLabel"); - CreateButtonControl(scrHandle,param,"accept",NULL, saveOpenGLOption); - CreateButtonControl(scrHandle,param,"cancel",prevMenu, GfuiScreenActivate); + // Multi-texturing. + MultiTextureLeftButtonId = + CreateButtonControl(ScrHandle, param, "MultiTextureLeftArrowButton", (void*)-1, + changeMultiTextureState); + MultiTextureRightButtonId = + CreateButtonControl(ScrHandle, param, "MultiTextureRightArrowButton", (void*)+1, + changeMultiTextureState); + MultiTextureLabelId = CreateLabelControl(ScrHandle,param,"MultiTextureLabel"); + + // Multi-sampling. + MultiSampleLeftButtonId = + CreateButtonControl(ScrHandle, param, "MultiSampleLeftArrowButton", (void*)-1, + changeMultiSampleState); + MultiSampleRightButtonId = + CreateButtonControl(ScrHandle, param, "MultiSampleRightArrowButton", (void*)+1, + changeMultiSampleState); + MultiSampleLabelId = CreateLabelControl(ScrHandle,param,"MultiSampleLabel"); + + CreateButtonControl(ScrHandle,param,"AcceptButton",NULL, onAccept); + CreateButtonControl(ScrHandle,param,"CancelButton",prevMenu, GfuiScreenActivate); GfParmReleaseHandle(param); - GfuiAddKey(scrHandle, GFUIK_RETURN, "Save", NULL, saveOpenGLOption, NULL); - GfuiAddKey(scrHandle, GFUIK_ESCAPE, "Cancel Selection", prevMenu, GfuiScreenActivate, NULL); - GfuiAddKey(scrHandle, GFUIK_F1, "Help", scrHandle, GfuiHelpScreen, NULL); - GfuiAddKey(scrHandle, GFUIK_F12, "Screen-Shot", NULL, GfuiScreenShot, NULL); - GfuiAddKey(scrHandle, GFUIK_LEFT, "Decrease Texture Size Limit", (void*)-1, changeTextureSizeState, NULL); - GfuiAddKey(scrHandle, GFUIK_RIGHT, "Increase Texture Size Limit", (void*)1, changeTextureSizeState, NULL); - GfuiAddKey(scrHandle, ' ', "Toggle Texture Compression", (void*)1, changeTextureCompressState, NULL); + GfuiAddKey(ScrHandle, GFUIK_RETURN, "Save", NULL, onAccept, NULL); + GfuiAddKey(ScrHandle, GFUIK_ESCAPE, "Cancel Selection", prevMenu, GfuiScreenActivate, NULL); + GfuiAddKey(ScrHandle, GFUIK_F1, "Help", ScrHandle, GfuiHelpScreen, NULL); + GfuiAddKey(ScrHandle, GFUIK_F12, "Screen-Shot", NULL, GfuiScreenShot, NULL); + GfuiAddKey(ScrHandle, GFUIK_LEFT, "Decrease Texture Size Limit", (void*)-1, changeMaxTextureSizeState, NULL); + GfuiAddKey(ScrHandle, GFUIK_RIGHT, "Increase Texture Size Limit", (void*)1, changeMaxTextureSizeState, NULL); + GfuiAddKey(ScrHandle, ' ', "Toggle Texture Compression", (void*)1, changeTextureCompressionState, NULL); - return scrHandle; + return ScrHandle; } diff --git a/src/libs/confscreens/openglconfig.h b/src/libs/confscreens/openglconfig.h index 6c6d413f3..6ffa793aa 100644 --- a/src/libs/confscreens/openglconfig.h +++ b/src/libs/confscreens/openglconfig.h @@ -30,5 +30,7 @@ CONFSCREENS_API void *OpenGLMenuInit(void *prevMenu); +CONFSCREENS_API void OpenGLLoadSelectedFeatures(); +CONFSCREENS_API void OpenGLStoreSelectedFeatures(); #endif // _OPENGLCONFIG_H_ diff --git a/src/libs/tgf/tgf.cpp b/src/libs/tgf/tgf.cpp index b5197d438..083bb1a9a 100644 --- a/src/libs/tgf/tgf.cpp +++ b/src/libs/tgf/tgf.cpp @@ -453,12 +453,11 @@ void GfInit(void) /** Restart the gaming framework (restart the current process). @ingroup tgf - @param sec Time to convert - @param plus String to display as the positive sign (+) for positive values of time. + @param bHardwareMouse If true, use hardware mouse cursor @return None - @warning Never returns (retart the process). + @warning Never returns (restart the process). */ -void GfRestart(bool bHardwareMouse, bool bMultiTexturing) +void GfRestart(bool bHardwareMouse) { int retcode = 0; static const int CMDSIZE = 1024; @@ -480,8 +479,6 @@ void GfRestart(bool bHardwareMouse, bool bMultiTexturing) if (bHardwareMouse) nArgs += 1; - if (!bMultiTexturing) - nArgs += 1; if (GetLocalDir() && strlen(GetLocalDir())) nArgs += 2; if (GetBinDir() && strlen(GetBinDir())) @@ -504,9 +501,6 @@ void GfRestart(bool bHardwareMouse, bool bMultiTexturing) if (bHardwareMouse) args[argInd++] = strdup("-m"); - if (!bMultiTexturing) - args[argInd++] = strdup("-s"); - if (GetLocalDir() && strlen(GetLocalDir())) { args[argInd++] = strdup("-l"); diff --git a/src/libs/tgf/tgf.h b/src/libs/tgf/tgf.h index 163b5fba5..31ec46e03 100644 --- a/src/libs/tgf/tgf.h +++ b/src/libs/tgf/tgf.h @@ -168,7 +168,7 @@ typedef struct * Gaming framework managment * ******************************/ TGF_API void GfInit(void); -TGF_API void GfRestart(bool bHardwareMouse = false, bool bSingleTexturing = false); +TGF_API void GfRestart(bool bHardwareMouse = false); /************************************************************************ diff --git a/src/libs/tgfclient/glfeatures.cpp b/src/libs/tgfclient/glfeatures.cpp index 9848815b9..f486d4438 100644 --- a/src/libs/tgfclient/glfeatures.cpp +++ b/src/libs/tgfclient/glfeatures.cpp @@ -17,28 +17,19 @@ ***************************************************************************/ -/* - Functions to check if features seems to be available and requested by the - user. The isAvailable functions should return if a feature is working on - the system, the isEnabled feature should check if the user wants to enable - it as well. - It should NOT check if the features are really working, that is subject - to another part eventually. -*/ - #include #include "glfeatures.h" -/** Report if a given OpenGL extension is supported (1) or not (0) +/** Report if a given OpenGL extension is supported Warning: Should not be called before any successfull call to SDL_SetVideoMode() Note: Copied from freeGLUT 2.4.0 */ -int GfglIsOpenGLExtensionSupported(const char* extension) +static bool gfglIsOpenGLExtensionSupported(const char* extension) { const char *extensions, *start; const int len = strlen(extension); @@ -46,12 +37,12 @@ int GfglIsOpenGLExtensionSupported(const char* extension) /* TODO: Make sure there is a current window, and thus a current context available */ if (strchr(extension, ' ')) - return 0; + return false; start = extensions = (const char *)glGetString(GL_EXTENSIONS); if (!extensions) - return 0; + return false; while (1) { @@ -60,194 +51,180 @@ int GfglIsOpenGLExtensionSupported(const char* extension) return 0; /* not found */ /* check that the match isn't a super string */ if ((p == start || p[-1] == ' ') && (p[len] == ' ' || p[len] == 0)) - return 1; + return true; /* skip the false match and continue */ extensions = p + len; } - return 0; + return false; } -/* - ----------------------- Texture Compression -*/ +// GfglFeatures singleton -------------------------------------------------------- +GfglFeatures* GfglFeatures::_pSelf = 0; -static bool bCompressARBAvailable; -static bool bCompressARBEnabled; - -// Feature checks, GL_ARB_texture_compression. -void checkCompressARBAvailable(bool &result) +// Initialization. +GfglFeatures::GfglFeatures() { - // Query if the extension is available at the runtime system (true, if > 0). - int compressARB = GfglIsOpenGLExtensionSupported("GL_ARB_texture_compression"); + checkSupport(); +} + +// Initialization. +GfglFeatures* GfglFeatures::self() +{ + if (!_pSelf) + _pSelf = new GfglFeatures; + + return _pSelf; +} + +void GfglFeatures::setSelectionLoader(void (*funcLoad)()) +{ + _funcLoadSelection = funcLoad; +} + +void GfglFeatures::setSelectionStorer(void (*funcStore)()) +{ + _funcStoreSelection = funcStore; +} + +void GfglFeatures::checkSupport() +{ + int nValue; + bool bValue; - // Check if at least one internal format is vailable. This is a workaround for - // driver problems and not a bugfix. According to the specification OpenGL should - // choose an uncompressed alternate format if it can't provide the requested - // compressed one... but it does not on all cards/drivers. - if (compressARB) + GfLogInfo("Supported OpenGL features :\n"); + + // a) Max texture size. + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &nValue); + if (nValue > 16384) // Max in-game supported value (must be consistent with openglconfig.cpp) + nValue = 16384; + _mapSupportedInt[TextureMaxSize] = nValue; + GfLogInfo(" Max texture size : %d\n", nValue); + + // b) Texture compression. + // Note: Check if at least one internal format is vailable. This is a workaround for + // driver problems and not a bugfix. According to the specification OpenGL should + // choose an uncompressed alternate format if it can't provide the requested + // compressed one... but it does not on all cards/drivers. + bValue = gfglIsOpenGLExtensionSupported("GL_ARB_texture_compression"); + if (bValue) { - int numformats; - glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, &numformats); - if (numformats == 0) - { - compressARB = 0; - } + int nFormats; + glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, &nFormats); + if (nFormats == 0) + bValue = false; } + _mapSupportedBool[TextureCompression] = bValue; + GfLogInfo(" Texture compression : %s\n", bValue ? "Yes" : "No"); + + // c) Multi-texturing (automatically select all the texturing units). + bValue = gfglIsOpenGLExtensionSupported("GL_ARB_multitexture"); + glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &nValue); + if (nValue < 2) + bValue = false; + _mapSupportedBool[MultiTexturing] = bValue; + GfLogInfo(" Multi-texturing : %s\n", bValue ? "Yes" : "No"); + _mapSupportedInt[MultiTexturingUnits] = nValue; + GfLogInfo(" Multi-texturing units : %d\n", nValue); - result = compressARB != 0; -} + _mapSelectedInt[MultiTexturingUnits] = nValue; // Auto-select. + + // d) Rectangle textures. + bValue = gfglIsOpenGLExtensionSupported("GL_ARB_texture_rectangle"); + _mapSupportedBool[TextureRectangle] = bValue; + GfLogInfo(" Rectangle textures : %s\n", bValue ? "Yes" : "No"); - -void checkCompressARBEnabled(bool &result) -{ - if (!GfglIsCompressARBAvailable()) + // e) Non-power-of-2 textures. + bValue = gfglIsOpenGLExtensionSupported("GL_ARB_texture_non_power_of_two"); + _mapSupportedBool[TextureNonPowerOf2] = bValue; + GfLogInfo(" Non power-of-2 textures : %s\n", bValue ? "Yes" : "No"); + + // f) Multi-sampling (anti-aliasing). + bValue = gfglIsOpenGLExtensionSupported("GL_ARB_multisample"); + if (bValue) { - // Feature not available, do not use it. - result = false; - } - else - { - // Feature available, check if the user wants to use it. - // TODO: put this enabled/disable stuff in one function (it is used in grsound.cpp as well). - const char *tcEnabledStr = GR_ATT_TEXTURECOMPRESSION_ENABLED; - char fnbuf[1024]; - sprintf(fnbuf, "%s%s", GetLocalDir(), GR_PARAM_FILE); - void *paramHandle = GfParmReadFile(fnbuf, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT); - const char *optionName = GfParmGetStr(paramHandle, GR_SCT_GLFEATURES, GR_ATT_TEXTURECOMPRESSION, GR_ATT_TEXTURECOMPRESSION_DISABLED); - - result = strcmp(optionName, tcEnabledStr) == 0; - GfParmReleaseHandle(paramHandle); + // Work-in-progress. + // TODO: More checks needed : number of samples + bValue = false; } + _mapSupportedBool[MultiSampling] = bValue; + GfLogInfo(" Multi-sampling : %s (not yet implemented)\n", bValue ? "Yes" : "No"); + } - -void GfglUpdateCompressARBEnabled(void) +void GfglFeatures::loadSelection() { - checkCompressARBEnabled(bCompressARBEnabled); + if (_funcLoadSelection) + _funcLoadSelection(); + dumpSelection(); } - -// GL_ARB_texture_compression -bool GfglIsCompressARBAvailable(void) +void GfglFeatures::storeSelection() const { - return bCompressARBAvailable; + dumpSelection(); + if (_funcStoreSelection) + _funcStoreSelection(); } - -bool GfglIsCompressARBEnabled(void) +void GfglFeatures::dumpSelection() const { - return bCompressARBEnabled; + GfLogInfo("Selected OpenGL features :\n"); + GfLogInfo(" Max texture size : %d\n", getSelected(TextureMaxSize)); + GfLogInfo(" Texture compression : %s\n", isSelected(TextureCompression) ? "On" : "Off"); + GfLogInfo(" Multi-texturing : %s\n", isSelected(MultiTexturing) ? "On" : "Off"); + GfLogInfo(" Multi-texturing units : %d\n", getSelected(MultiTexturingUnits)); + GfLogInfo(" Multi-sampling : %s\n", isSelected(MultiSampling) ? "Yes" : "No"); } - -/* - ----------------------- Texture downsizing. -*/ -static int nGLTextureMaxSize; -static int nUserTextureMaxSize; - - -void GfglGetGLTextureMaxSize(int &result) +bool GfglFeatures::isSelected(EFeatureBool eFeature) const { - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &result); - if (result > 16384) - { - result = 16384; - } + const std::map::const_iterator itFeature = + _mapSelectedBool.find(eFeature); + return itFeature == _mapSelectedBool.end() ? false : itFeature->second; } - -void GfglGetUserTextureMaxSize(int &result) +bool GfglFeatures::isSupported(EFeatureBool eFeature) const { - char fnbuf[1024]; - sprintf(fnbuf, "%s%s", GetLocalDir(), GR_PARAM_FILE); - void *paramHandle = GfParmReadFile(fnbuf, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT); - result = (int) GfParmGetNum(paramHandle, GR_SCT_GLFEATURES, GR_ATT_TEXTURESIZE, (char*)NULL, (tdble) nGLTextureMaxSize); - if (result > nGLTextureMaxSize) - { - result = nGLTextureMaxSize; - } - GfParmReleaseHandle(paramHandle); + const std::map::const_iterator itFeature = + _mapSupportedBool.find(eFeature); + return itFeature == _mapSupportedBool.end() ? false : itFeature->second; } - -void GfglUpdateUserTextureMaxSize(void) +void GfglFeatures::select(EFeatureBool eFeature, bool bSelected) { - GfglGetUserTextureMaxSize(nUserTextureMaxSize); + if (isSupported(eFeature)) + _mapSelectedBool[eFeature] = bSelected; +// GfLogDebug("GfglFeatures::select(Bool:%d, %s) : supp=%s, new=%s\n", +// (int)eFeature, bSelected ? "true" : "false", +// isSupported(eFeature) ? "true" : "false", +// _mapSelectedBool[eFeature] ? "true" : "false"); } -int GfglGetGLTextureMaxSize(void) +int GfglFeatures::getSelected(EFeatureInt eFeature) const { - return nGLTextureMaxSize; + const std::map::const_iterator itFeature = + _mapSelectedInt.find(eFeature); + return itFeature == _mapSelectedInt.end() ? -1 : itFeature->second; } - -int GfglGetUserTextureMaxSize(void) +int GfglFeatures::getSupported(EFeatureInt eFeature) const { - return nUserTextureMaxSize; + const std::map::const_iterator itFeature = + _mapSupportedInt.find(eFeature); + return itFeature == _mapSupportedInt.end() ? -1 : itFeature->second; } - -/* - ----------------------- Multi-texturing (anti-aliasing) support. -*/ -static bool bMultiTexturingEnabled = true; - - -bool GfglIsMultiTexturingEnabled() +void GfglFeatures::select(EFeatureInt eFeature, int nSelectedValue) { - return bMultiTexturingEnabled; + if (getSupported(eFeature) != -1) + _mapSelectedInt[eFeature] = nSelectedValue; +// GfLogDebug("GfglFeatures::select(Int:%d, %d) : supp=%s, new=%d\n", +// (int)eFeature, nSelectedValue, getSupported(eFeature) >= 0 ? "true" : "false", +// _mapSelectedInt[eFeature]); } - -void GfglEnableMultiTexturing(bool bEnable) +void* GfglFeatures::getProcAddress(const char* pszName) { - bMultiTexturingEnabled = bEnable; -} - - -/* - ----------------------- Non-power of 2 size texture support. -*/ -static bool bTextureRectangleARBAvailable; -static bool bTextureNonPowerOf2ARBAvailable; - -// Feature checks, GL_ARB_texture_rectangle. -void checkTextureRectangleARBAvailable(bool &result) -{ - // Query if the extension is available at the runtime system (true, if not 0). - result = GfglIsOpenGLExtensionSupported("GL_ARB_texture_rectangle") != 0; -} - -// Feature checks, GL_ARB_texture_rectangle. -void checkTextureNonPowerOf2ARBAvailable(bool &result) -{ - // Query if the extension is available at the runtime system (true if not 0). - result = GfglIsOpenGLExtensionSupported("GL_ARB_texture_non_power_of_two") != 0; -} - -bool GfglIsTextureRectangleARBAvailable(void) -{ - return bTextureRectangleARBAvailable; -} - -bool GfglIsTextureNonPowerOf2ARBAvailable(void) -{ - return bTextureNonPowerOf2ARBAvailable; -} - -/* - ----------------------- Initialization. -*/ - -void gfglCheckGLFeatures(void) -{ - checkCompressARBAvailable(bCompressARBAvailable); - checkCompressARBEnabled(bCompressARBEnabled); - GfglGetGLTextureMaxSize(nGLTextureMaxSize); - GfglGetUserTextureMaxSize(nUserTextureMaxSize); - checkTextureRectangleARBAvailable(bTextureRectangleARBAvailable); - checkTextureNonPowerOf2ARBAvailable(bTextureNonPowerOf2ARBAvailable); + return SDL_GL_GetProcAddress(pszName); } diff --git a/src/libs/tgfclient/glfeatures.h b/src/libs/tgfclient/glfeatures.h index d47e39853..c27ad5a7e 100644 --- a/src/libs/tgfclient/glfeatures.h +++ b/src/libs/tgfclient/glfeatures.h @@ -16,15 +16,6 @@ * * ***************************************************************************/ -/* -Functions to check if features seems to be available and requested by the -user. The isAvailable functions should return if a feature is working on -the system, the isEnabled feature should check if the user wants to enable -it as well. -It should NOT check if the features are really working, that is subject -to another part eventually. -*/ - #ifndef _GLFEATURES_H_ #define _GLFEATURES_H_ @@ -46,9 +37,5 @@ to another part eventually. #include "tgfclient.h" - -// Initialize -extern void gfglCheckGLFeatures(void); - #endif // _GLFEATURES_H_ diff --git a/src/libs/tgfclient/guiscreen.cpp b/src/libs/tgfclient/guiscreen.cpp index f4677c133..296dede6a 100644 --- a/src/libs/tgfclient/guiscreen.cpp +++ b/src/libs/tgfclient/guiscreen.cpp @@ -405,11 +405,13 @@ void GfScrInit(int argc, char *argv[]) } // Set full screen mode if required. - int videomode = SDL_OPENGL; + int videomode = SDL_OPENGL; // What about SDL_DOUBLEBUFFER ? if (!strcmp(fscr, "yes")) videomode |= SDL_FULLSCREEN; // Video initialization with best possible settings. + // TODO: Shouldn't we use only SDL_SetVideoMode here, and move SDL_GL_SetAttribute + // into the graphics engine ? Do we need multi-sampling in menus ? ScreenSurface = 0; if (strcmp(vinit, GFSCR_VAL_VINIT_BEST) == 0) { @@ -418,69 +420,69 @@ void GfScrInit(int argc, char *argv[]) // Could not get it automatically detected till now. /* Set the minimum requirements for the OpenGL window */ - SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8 ); - SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8 ); - SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8 ); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); // Try to get "best" videomode with default anti-aliasing support : // 24 bit z-buffer with alpha channel. - SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 ); - SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 ); - SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); - SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 ); - ScreenSurface = SDL_SetVideoMode( winX, winY, depth, videomode); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode); // Failed : try without anti-aliasing. if (!ScreenSurface) { - SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 0 ); - ScreenSurface = SDL_SetVideoMode( winX, winY, depth, videomode); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); + ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode); } // Failed : try with anti-aliasing, but without alpha channel. if (!ScreenSurface) { - SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 ); - SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 0 ); - ScreenSurface = SDL_SetVideoMode( winX, winY, depth, videomode); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); + ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode); } // Failed : try without anti-aliasing, and without alpha channel. if (!ScreenSurface) { - SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 0 ); - ScreenSurface = SDL_SetVideoMode( winX, winY, depth, videomode); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); + ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode); } // Failed : try 16 bit z-buffer and back with alpha channel and anti-aliasing. if (!ScreenSurface) { - SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 ); - SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 ); - SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 ); - ScreenSurface = SDL_SetVideoMode( winX, winY, depth, videomode); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode); } // Failed : try without anti-aliasing. if (!ScreenSurface) { - SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 0 ); - ScreenSurface = SDL_SetVideoMode( winX, winY, depth, videomode); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); + ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode); } // Failed : try with anti-aliasing, but without alpha channel. if (!ScreenSurface) { - SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 ); - SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 0 ); - ScreenSurface = SDL_SetVideoMode( winX, winY, depth, videomode); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); + ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode); } // Failed : try without anti-aliasing, and without alpha channel. if (!ScreenSurface) { - SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 0 ); - ScreenSurface = SDL_SetVideoMode( winX, winY, depth, videomode); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0); + ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode); } // Failed : Give up but say why. @@ -494,19 +496,29 @@ void GfScrInit(int argc, char *argv[]) // Video initialization with generic compatible settings. if (!ScreenSurface) { - GfLogInfo("Trying generic video initialization with requested resolution, fallback.\n\n"); - ScreenSurface = SDL_SetVideoMode( winX, winY, depth, videomode); + GfLogInfo("Trying generic video initialization with requested size and color depth, fallback.\n\n"); + ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode); } - // Failed : Try with a lower fallback resolution that should be supported everywhere ... + // Failed : Try with a lower fallback size : should be supported everywhere ... if (!ScreenSurface) { - GfLogError("Unable to get compatible video mode with requested resolution\n\n"); + GfLogError("Unable to get compatible video mode with requested size and color depth\n\n"); winX = ADefScreenSizes[0].width; winY = ADefScreenSizes[0].height; - GfLogInfo("Trying generic video initialization with fallback resolution %dx%d.\n\n", + GfLogInfo("Trying generic video initialization with fallback size %dx%d and requested color depth.\n\n", winX, winY); - ScreenSurface = SDL_SetVideoMode( winX, winY, depth, videomode); + ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode); + } + + // Failed : Try with a lower fallback color depth : should be supported everywhere ... + if (!ScreenSurface) + { + GfLogError("Unable to get compatible video mode with fallback size and requested color depth\n\n"); + depth = ADefScreenColorDepths[0]; + GfLogInfo("Trying generic video initialization with fallback size %dx%d and color depth %d.\n\n", + winX, winY, depth); + ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode); } // Failed : No way ... no more ideas ! @@ -525,24 +537,29 @@ void GfScrInit(int argc, char *argv[]) GfScrCenX = xw / 2; GfScrCenY = yw / 2; - // Report video mode finally obtained. + // Report video mode and OpenGL features finally obtained. + GfLogInfo("Current video mode :\n"); + GfLogInfo(" Full screen : %s\n", (videomode & SDL_FULLSCREEN) ? "Yes" : "No"); + GfLogInfo(" Size : %dx%d\n", winX, winY); + GfLogInfo(" Color depth : %d\n", depth); + int glAlpha, glDepth, glDblBuff, glMSamp, glMSampLevel; - SDL_GL_GetAttribute( SDL_GL_ALPHA_SIZE, &glAlpha ); - SDL_GL_GetAttribute( SDL_GL_DEPTH_SIZE, &glDepth ); - SDL_GL_GetAttribute( SDL_GL_DOUBLEBUFFER, &glDblBuff ); - SDL_GL_GetAttribute( SDL_GL_MULTISAMPLEBUFFERS, &glMSamp ); - SDL_GL_GetAttribute( SDL_GL_MULTISAMPLESAMPLES, &glMSampLevel ); + SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &glAlpha); + SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &glDepth); + SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &glDblBuff); + SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &glMSamp); + SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &glMSampLevel); - GfLogInfo("Visual Properties Report\n"); - GfLogInfo("------------------------\n"); - GfLogInfo("Resolution : %dx%dx%d\n", winX, winY, depth); - GfLogInfo("Double-buffer : %s", glDblBuff ? "Yes" : "No\n"); + // TODO: Is this really related to video mode initialization ? + // What about moving this to gfglCheckGLFeatures ? + GfLogInfo("Supported OpenGL features :\n"); + GfLogInfo(" Double-buffer : %s", glDblBuff ? "Yes" : "No\n"); if (glDblBuff) GfLogInfo(" (%d bits)\n", glDepth); - GfLogInfo("Alpha-channel : %s\n", glAlpha ? "Yes" : "No"); - GfLogInfo("Anti-aliasing : %s", glMSamp ? "Yes" : "No\n"); + GfLogInfo(" Alpha-channel : %s\n", glAlpha ? "Yes" : "No"); + GfLogInfo(" Anti-aliasing : %s", glMSamp ? "Yes" : "No\n"); if (glMSamp) - GfLogInfo(" (multi-sampling level %d)\n", glMSampLevel); + GfLogInfo(" (multi-sampling level %d)\n", glMSampLevel); #ifdef WIN32 // Under Windows, give an initial position to the window if not full-screen mode @@ -567,7 +584,7 @@ void GfScrInit(int argc, char *argv[]) GfelSetReshapeCB(gfScrReshapeViewport); // Initialize Open GL feature management layer - gfglCheckGLFeatures(); + //TODO:gfglCheckGLFeatures(); } /** Shutdown the screen diff --git a/src/libs/tgfclient/tgfclient.h b/src/libs/tgfclient/tgfclient.h index 2483ec5b1..2619da671 100644 --- a/src/libs/tgfclient/tgfclient.h +++ b/src/libs/tgfclient/tgfclient.h @@ -27,6 +27,7 @@ #include #include +#include #ifdef WIN32 # include @@ -599,30 +600,93 @@ TGFCLIENT_API void GfelForceRedisplay(); // The event loop itself (never returns) TGFCLIENT_API void GfelMainLoop(void); + /******************************* - * Graphics features interface * + * OpenGL features interface * *******************************/ +/* Makes the difference between selected, supported and enabled features : + - "selected" means that the user choosed to use the feature + (through the OpenGL option menu or the graph.xml file), + - "supported" means that the underlying hardware/driver actually supports the feature, + - "enabled" means that the feature is actually enabled in the underlying hardware/driver. + GfglFeatures generally doesn't automatically select features : call select() for this + (Exceptions: MultiTexturingUnits = all available ones). + GfglFeatures doesn't automatically enables features : not done here. + A feature that is not supported can not be selected (or enabled). + A feature that is selected is not necessarily enabled (not done here). + Warning: Should not be used before the 1st successfull call to SDL_SetVideoMode(). +*/ -TGFCLIENT_API int GfglIsOpenGLExtensionSupported(const char* extension); +class TGFCLIENT_API GfglFeatures +{ + public: + + // Access to the unique instance. + static GfglFeatures* self(); -// GL_ARB_texture_compression -TGFCLIENT_API bool GfglIsCompressARBAvailable(void); -TGFCLIENT_API bool GfglIsCompressARBEnabled(void); -TGFCLIENT_API void GfglUpdateCompressARBEnabled(void); + // Set the functions for "loading from" and "storing to" the feature selection XML file. + void setSelectionLoader(void (*funcLoad)()); + void setSelectionStorer(void (*funcStore)()); -// Texture max size -TGFCLIENT_API int GfglGetUserTextureMaxSize(void); -TGFCLIENT_API int GfglGetGLTextureMaxSize(void); -TGFCLIENT_API void GfglUpdateUserTextureMaxSize(void); + // Check supported features (ask OpenGL). + void checkSupport(); -// Texture non-power-of-2 support -TGFCLIENT_API bool GfglIsTextureRectangleARBAvailable(void); // In case mipmapping NOT needed. -TGFCLIENT_API bool GfglIsTextureNonPowerOf2ARBAvailable(void); // In case mipmapping needed. + // Load selected features from the feature selection XML file. + void loadSelection(); + + // Store selected features to the feature selection XML file. + void storeSelection() const; + + // Dump selected features (in the current trace stream). + void dumpSelection() const; + + // Bool-valued features. + enum EFeatureBool + { + TextureCompression, // GL_ARB_texture_compression + TextureRectangle, // GL_ARB_texture_rectangle, in case mipmapping NOT needed. + TextureNonPowerOf2, // GL_ARB_texture_non_power_of_two, in case mipmapping needed. + MultiTexturing, // GL_ARB_multitexture + MultiSampling // GL_ARB_multisample + }; + void select(EFeatureBool eFeature, bool bSelected); + bool isSelected(EFeatureBool eFeature) const; + bool isSupported(EFeatureBool eFeature) const; -// Multi-texturing support -TGFCLIENT_API bool GfglIsMultiTexturingEnabled(); -TGFCLIENT_API void GfglEnableMultiTexturing(bool bEnable = true); + // Integer-valued features (WARNING: For the moment, -1 means "not supported"). + enum EFeatureInt + { + TextureMaxSize, + MultiTexturingUnits // Number of texturing units. + }; + void select(EFeatureInt eFeature, int nSelectedValue); + int getSelected(EFeatureInt eFeature) const; + int getSupported(EFeatureInt eFeature) const; + // Get the pointer to the named OpenGL extension function. + static void* getProcAddress(const char* pszName); + + private: + + GfglFeatures(); // Singleton pattern => private constructor. + + private: + + // The unique instance. + static GfglFeatures* _pSelf; + + // Functions for "loading from" and "storing to" the feature selection XML file. + void (*_funcLoadSelection)(); + void (*_funcStoreSelection)(); + + // Maps of supported features (bool and int-valued). + std::map _mapSupportedBool; + std::map _mapSupportedInt; + + // Maps of selected features (bool and int-valued). + std::map _mapSelectedBool; + std::map _mapSelectedInt; +}; #endif /* __TGFCLIENT__H__ */ diff --git a/src/linux/main.cpp b/src/linux/main.cpp index c650d1d61..1f3dfd26f 100644 --- a/src/linux/main.cpp +++ b/src/linux/main.cpp @@ -67,11 +67,6 @@ init_args(int argc, char **argv) if (++i < argc) bindir = SetBinDir(argv[i]); } - // -s option : Single texture mode (= disable multi-texturing) - else if (!strncmp(argv[i], "-s", 2)) - { - GfglEnableMultiTexturing(false); - } // -m option : Allow the hardware mouse cursor else if (!strncmp(argv[i], "-m", 2)) { diff --git a/src/modules/graphic/ssggraph/graph.xml b/src/modules/graphic/ssggraph/graph.xml index 7cca7a0de..d4d2246bb 100644 --- a/src/modules/graphic/ssggraph/graph.xml +++ b/src/modules/graphic/ssggraph/graph.xml @@ -14,7 +14,7 @@ - +
diff --git a/src/modules/graphic/ssggraph/grmain.cpp b/src/modules/graphic/ssggraph/grmain.cpp index 0a76e0461..c45917161 100644 --- a/src/modules/graphic/ssggraph/grmain.cpp +++ b/src/modules/graphic/ssggraph/grmain.cpp @@ -24,7 +24,7 @@ #endif #include -#include +#include // GfglFeatures #include //ROB_SECT_ARBITRARY #include "grmain.h" @@ -83,37 +83,28 @@ PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = NULL; #endif -// Set up OpenGL for multitexturing support -bool grInitMultiTex(void) +// Set up OpenGL for multi-texturing support +int grInitMultiTex(void) { - if (!GfglIsMultiTexturingEnabled()) + grMaxTextureUnits = 1; + + if (GfglFeatures::self()->isSelected(GfglFeatures::MultiTexturing)) { - grMaxTextureUnits = 1; - return true; - } + // Use the selected number of texture units. + grMaxTextureUnits = GfglFeatures::self()->getSelected(GfglFeatures::MultiTexturingUnits); - // TODO: Move most of the following code to tgfclient/glfeatures.cpp ? - - // list of available extensions - char *extensionStr = (char*)glGetString(GL_EXTENSIONS); - if (!extensionStr) - return false; - - if (strstr(extensionStr, "GL_ARB_multitexture")) - { - // retrieve the maximum number of texture units allowed - glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &grMaxTextureUnits); #ifdef WIN32 - // retrieve addresses of multitexturing functions - glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress("glMultiTexCoord2fARB"); - glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB"); - glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC) wglGetProcAddress("glClientActiveTextureARB"); - glMultiTexCoord2fvARB = (PFNGLMULTITEXCOORD2FVARBPROC) wglGetProcAddress("glMultiTexCoord2fvARB"); + // Retrieve the addresses of multi-texturing functions under Windows + // They are not declared in gl.h or any other header ; + // you can only get them through a call to wglGetProcAddress at run-time. + glMultiTexCoord2fARB = (PFNGLMULTITEXCOORD2FARBPROC)wglGetProcAddress("glMultiTexCoord2fARB"); + glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB"); + glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)wglGetProcAddress("glClientActiveTextureARB"); + glMultiTexCoord2fvARB = (PFNGLMULTITEXCOORD2FVARBPROC)wglGetProcAddress("glMultiTexCoord2fvARB"); #endif - return true; } - return false; + return grMaxTextureUnits; } diff --git a/src/modules/graphic/ssggraph/grmain.h b/src/modules/graphic/ssggraph/grmain.h index 2ab11ac58..ec9fd19b3 100644 --- a/src/modules/graphic/ssggraph/grmain.h +++ b/src/modules/graphic/ssggraph/grmain.h @@ -31,14 +31,15 @@ #ifdef WIN32 -////// Multitexturing Info +// Multi-texturing functions : Under Windows, not present in gl.h or any other ; +// you can only get them through a call to wglGetProcAddress at run-time. extern PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB ; extern PFNGLMULTITEXCOORD2FVARBPROC glMultiTexCoord2fvARB; extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB ; extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB ; #endif -extern bool grInitMultiTex(); +extern int grInitMultiTex(); extern int grWinx, grWiny, grWinw, grWinh; extern int grVectFlag; diff --git a/src/modules/graphic/ssggraph/grscene.cpp b/src/modules/graphic/ssggraph/grscene.cpp index db74e508a..9e798b322 100644 --- a/src/modules/graphic/ssggraph/grscene.cpp +++ b/src/modules/graphic/ssggraph/grscene.cpp @@ -27,7 +27,7 @@ #include #include -#include //gluXXX +#include #include //RtXXX() #include // snprintf diff --git a/src/modules/graphic/ssggraph/grtexture.cpp b/src/modules/graphic/ssggraph/grtexture.cpp index fc19e0a23..5a617e824 100644 --- a/src/modules/graphic/ssggraph/grtexture.cpp +++ b/src/modules/graphic/ssggraph/grtexture.cpp @@ -22,10 +22,11 @@ they should obsolete parts of grutil.cpp. */ -#include +#include // GfglFeatures #include "grutil.h" + int doMipMap(const char *tfname, int mipmap) { char *buf = strdup(tfname); @@ -283,7 +284,7 @@ bool grMakeMipMaps (GLubyte *image, int xsize, int ysize, int zsize, int mipmap) GLint ww; GLint textureTargetFormat; - if (GfglIsCompressARBEnabled()) { + if (GfglFeatures::self()->isSelected(GfglFeatures::TextureCompression)) { //GfTrace("COMPRESSOR: "); switch (zsize) { @@ -309,7 +310,7 @@ bool grMakeMipMaps (GLubyte *image, int xsize, int ysize, int zsize, int mipmap) //GfTrace("NON COMPRESSOR\n"); } - int tlimit = GfglGetUserTextureMaxSize(); + const int tlimit = GfglFeatures::self()->getSelected(GfglFeatures::TextureMaxSize); do { if (xsize > tlimit || ysize > tlimit) { diff --git a/src/modules/graphic/ssggraph/grtrackmap.cpp b/src/modules/graphic/ssggraph/grtrackmap.cpp index 41c9eacd7..166874024 100644 --- a/src/modules/graphic/ssggraph/grtrackmap.cpp +++ b/src/modules/graphic/ssggraph/grtrackmap.cpp @@ -24,13 +24,14 @@ game just the texture needs to be redrawn. */ #include -#include +#include // GfglFeatures #include //tSituation #include "grtrackmap.h" #include "grmain.h" //grWinXXX + // The resolution in [m] to analyse turns. const float cGrTrackMap::RESOLUTION = 5.0; @@ -367,10 +368,10 @@ cGrTrackMap::cGrTrackMap() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - // If GL_ARB_texture_compression is available at runtime, (try to) compress the + // If GL_ARB_texture_compression is available at runtime and selected, (try to) compress the // texture. This is done with the specification of the internal format to // GL_COMPRESSED_RGBA_ARB. - if (GfglIsCompressARBAvailable()) { + if (GfglFeatures::self()->isSelected(GfglFeatures::TextureCompression)) { // This texture contains mostly the clear color value and should therefore // compress well even with high quality. glHint(GL_TEXTURE_COMPRESSION_HINT_ARB, GL_NICEST); @@ -385,7 +386,7 @@ cGrTrackMap::cGrTrackMap() printf("compression ratio: %d to %d\n", csize, texturesize*texturesize*sizeof(GLuint)); }*/ } else { - // GL_ARB_texture_compression not available at runtime, fallback. + // GL_ARB_texture_compression not available at runtime or not selected, fallback. gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, texturesize, texturesize, GL_RGBA, GL_BYTE, trackImage); } diff --git a/src/tools/menuview/main.cpp b/src/tools/menuview/main.cpp index cfbc1191d..130db3212 100644 --- a/src/tools/menuview/main.cpp +++ b/src/tools/menuview/main.cpp @@ -39,8 +39,10 @@ #include "splash.h" #include "previewmenu.h" + std::string g_strMenuFile; + static void init_args(int argc, char **argv) { @@ -80,11 +82,6 @@ init_args(int argc, char **argv) if (++i < argc) bindir = SetBinDir(argv[i]); } - // -s option : Single texture mode (= disable multi-texturing) - else if (!strncmp(argv[i], "-s", 2)) - { - GfglEnableMultiTexturing(false); - } // -m option : Allow the hardware mouse cursor else if (!strncmp(argv[i], "-m", 2)) { diff --git a/src/windows/main.cpp b/src/windows/main.cpp index 3bd78f969..b8a0fd9bd 100644 --- a/src/windows/main.cpp +++ b/src/windows/main.cpp @@ -67,11 +67,6 @@ init_args(int argc, char **argv) if (++i < argc) datadir = SetDataDir(argv[i]); } - // -s or /s option : Single texture mode (= disable multi-texturing) - else if (!strncmp(argv[i], "-s", 2) || !strncmp(argv[i], "/s", 2)) - { - GfglEnableMultiTexturing(false); - } // -m or /m option : Allow the hardware mouse cursor else if (!strncmp(argv[i], "-m", 2) || !strncmp(argv[i], "/m", 2)) {