Re #320 Added anti-aliasing detection/configuration (but seems when it is enabled, you can't disable it, unless you choose the 'compatible' vido init mode)
git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@3527 30fe4595-0a0c-4342-8851-515496e4dcbd Former-commit-id: b792afdbbe99bf549eb5466d1c9419395ad96542 Former-commit-id: 5f2ba07278ad6549d31e45360da05c0ff3e6d20e
This commit is contained in:
parent
323184f69e
commit
4d9832156f
15 changed files with 653 additions and 376 deletions
|
@ -36,21 +36,6 @@
|
|||
#define GR_ATT_SOUND_STATE_DISABLED "disabled"
|
||||
#define GR_ATT_SOUND_VOLUME "volume"
|
||||
|
||||
#define GR_SCT_GLFEATURES "OpenGL Features"
|
||||
#define GR_ATT_TEXTURECOMPRESSION "texture compression"
|
||||
#define GR_ATT_TEXTURECOMPRESSION_ENABLED "enabled"
|
||||
#define GR_ATT_TEXTURECOMPRESSION_DISABLED "disabled"
|
||||
|
||||
#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"
|
||||
#define GR_ATT_CAM_HEAD "camera head list"
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
***************************************************************************/
|
||||
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
#include "glfeatures.h"
|
||||
|
@ -66,44 +68,73 @@ GfglFeatures* GfglFeatures::_pSelf = 0;
|
|||
// Initialization.
|
||||
GfglFeatures::GfglFeatures()
|
||||
{
|
||||
checkSupport();
|
||||
}
|
||||
|
||||
// Initialization.
|
||||
GfglFeatures* GfglFeatures::self()
|
||||
GfglFeatures& GfglFeatures::self()
|
||||
{
|
||||
if (!_pSelf)
|
||||
_pSelf = new GfglFeatures;
|
||||
|
||||
return _pSelf;
|
||||
}
|
||||
|
||||
void GfglFeatures::setSelectionLoader(void (*funcLoad)())
|
||||
{
|
||||
_funcLoadSelection = funcLoad;
|
||||
}
|
||||
|
||||
void GfglFeatures::setSelectionStorer(void (*funcStore)())
|
||||
{
|
||||
_funcStoreSelection = funcStore;
|
||||
return *_pSelf;
|
||||
}
|
||||
|
||||
// Warning: Should not be called before any successfull call to SDL_SetVideoMode()
|
||||
void GfglFeatures::checkSupport()
|
||||
{
|
||||
int nValue;
|
||||
bool bValue;
|
||||
|
||||
GfLogInfo("Video hardware info :\n");
|
||||
GfLogInfo(" Vendor : %s\n", glGetString(GL_VENDOR));
|
||||
GfLogInfo(" Renderer : %s\n", glGetString(GL_RENDERER));
|
||||
GfLogInfo(" Version : %s\n", glGetString(GL_VERSION));
|
||||
|
||||
GfLogInfo("Supported OpenGL features :\n");
|
||||
|
||||
// a) Max texture size.
|
||||
// 1) Double-buffer : if it is supported, it is set, so we simply read it (see GfScrInit).
|
||||
SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &nValue);
|
||||
_mapSupportedBool[DoubleBuffer] = nValue ? true : false;
|
||||
GfLogInfo(" Double buffer : %s\n", nValue ? "Yes" : "No");
|
||||
|
||||
// Update selection if needed.
|
||||
if (!nValue)
|
||||
_mapSelectedBool[DoubleBuffer] = false;
|
||||
|
||||
// 2) Color buffer depth.
|
||||
glGetIntegerv(GL_DEPTH_BITS, &nValue);
|
||||
_mapSupportedInt[ColorDepth] = nValue;
|
||||
GfLogInfo(" Color depth : %d bits\n", nValue);
|
||||
|
||||
// Update selection if needed.
|
||||
if (getSelected(ColorDepth) > nValue)
|
||||
_mapSelectedInt[ColorDepth] = nValue;
|
||||
|
||||
// 3) Alpha channel depth.
|
||||
glGetIntegerv(GL_ALPHA_BITS, &nValue);
|
||||
_mapSupportedInt[AlphaDepth] = nValue;
|
||||
GfLogInfo(" Alpha channel : %s", nValue > 0 ? "Yes" : "No");
|
||||
if (nValue > 0)
|
||||
GfLogInfo(" (%d bits)", nValue);
|
||||
GfLogInfo("\n");
|
||||
|
||||
// Update selection if needed.
|
||||
if (getSelected(AlphaDepth) > nValue)
|
||||
_mapSelectedInt[AlphaDepth] = nValue;
|
||||
|
||||
// 4) 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
|
||||
// Update selection if needed.
|
||||
if (getSelected(TextureMaxSize) > nValue)
|
||||
_mapSelectedInt[TextureMaxSize] = nValue;
|
||||
|
||||
// 5) Texture compression.
|
||||
// Note: Check if at least one internal format is available. 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.
|
||||
|
@ -117,64 +148,226 @@ void GfglFeatures::checkSupport()
|
|||
}
|
||||
_mapSupportedBool[TextureCompression] = bValue;
|
||||
GfLogInfo(" Texture compression : %s\n", bValue ? "Yes" : "No");
|
||||
|
||||
// Update selection if needed.
|
||||
if (!bValue)
|
||||
_mapSelectedBool[TextureCompression] = false;
|
||||
|
||||
// c) Multi-texturing (automatically select all the texturing units).
|
||||
// 6) 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);
|
||||
GfLogInfo(" Multi-texturing : %s", bValue ? "Yes" : "No", nValue);
|
||||
if (bValue)
|
||||
GfLogInfo(" (%d units)", nValue);
|
||||
GfLogInfo("\n");
|
||||
|
||||
// Update selection if needed.
|
||||
if (!bValue)
|
||||
_mapSelectedBool[MultiTexturing] = false;
|
||||
_mapSelectedInt[MultiTexturingUnits] = nValue; // Auto-select.
|
||||
|
||||
// d) Rectangle textures.
|
||||
// 7) Rectangle textures.
|
||||
bValue = gfglIsOpenGLExtensionSupported("GL_ARB_texture_rectangle");
|
||||
_mapSupportedBool[TextureRectangle] = bValue;
|
||||
GfLogInfo(" Rectangle textures : %s\n", bValue ? "Yes" : "No");
|
||||
|
||||
// e) Non-power-of-2 textures.
|
||||
// Force selection.
|
||||
_mapSelectedBool[TextureRectangle] = bValue;
|
||||
|
||||
// 8) 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)
|
||||
{
|
||||
// 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");
|
||||
// Force selection.
|
||||
_mapSelectedBool[TextureNonPowerOf2] = bValue;
|
||||
|
||||
// 9) Multi-sampling = anti-aliasing
|
||||
// Warning: Detection not done here (too late) :
|
||||
// should already have been stored through setSupported calls.
|
||||
// bValue = gfglIsOpenGLExtensionSupported("GL_ARB_multisample");
|
||||
// if (bValue)
|
||||
// {
|
||||
// // Check if it is enabled.
|
||||
// glGetIntegerv(GL_SAMPLE_BUFFERS, &nValue);
|
||||
// bValue = nValue == 1;
|
||||
// bool bTryForced = false;
|
||||
// if (!bValue)
|
||||
// {
|
||||
// // Not enabled : try to enable to see if possible.
|
||||
// bTryForced = true;
|
||||
// bValue = SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1) != -1;
|
||||
// }
|
||||
// if (bValue)
|
||||
// {
|
||||
// // After forcing MULTISAMPLEBUFFERS, can't get the real SAMPLES ...
|
||||
// if (bTryForced)
|
||||
// nValue = 2; // ... so can't do better than minimum.
|
||||
// else
|
||||
// glGetIntegerv(GL_SAMPLES, &nValue);
|
||||
// if (nValue < 2)
|
||||
// bValue = false;
|
||||
// }
|
||||
|
||||
// // Disable it if was not selected and we had to try it.
|
||||
// if (bTryForced && !isSelected(MultiSampling))
|
||||
// SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||
// }
|
||||
// _mapSupportedBool[MultiSampling] = bValue;
|
||||
// _mapSupportedInt[MultiSamplingSamples] = nValue;
|
||||
bValue = _mapSupportedBool[MultiSampling];
|
||||
nValue = _mapSupportedInt[MultiSamplingSamples];
|
||||
GfLogInfo(" Multi-sampling : %s", bValue ? "Yes" : "No");
|
||||
if (bValue && nValue > 1)
|
||||
GfLogInfo(" (%d samples)", nValue);
|
||||
GfLogInfo("\n");
|
||||
|
||||
// Update selection if needed.
|
||||
if (!bValue)
|
||||
_mapSelectedBool[MultiSampling] = false;
|
||||
}
|
||||
|
||||
void GfglFeatures::loadSelection()
|
||||
// Load the selected OpenGL features from the config file.
|
||||
void GfglFeatures::loadSelection(void* hparmConfig)
|
||||
{
|
||||
if (_funcLoadSelection)
|
||||
_funcLoadSelection();
|
||||
dumpSelection();
|
||||
// Open the config file if not already done.
|
||||
void* hparm;
|
||||
if (!hparmConfig)
|
||||
{
|
||||
std::ostringstream ossParm;
|
||||
ossParm << GfLocalDir() << GFSCR_CONF_FILE;
|
||||
hparm = GfParmReadFile(ossParm.str().c_str(), GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
hparm = hparmConfig;
|
||||
}
|
||||
|
||||
// Read the OpenGL configuration from screen.xml (or hard coded values).
|
||||
// and select the OpenGL features accordingly
|
||||
// (by default, select the max possible values ; we'll see later through checkSupport
|
||||
// if we really can).
|
||||
|
||||
// 1) Double-buffer : no choice, hard-coded.
|
||||
_mapSelectedBool[DoubleBuffer] = true;
|
||||
|
||||
// 2) Color buffer depth : no choice, hard-coded.
|
||||
_mapSelectedInt[ColorDepth] = 24;
|
||||
|
||||
// 3) Alpha-channel depth : no choice, hard-coded.
|
||||
_mapSelectedInt[AlphaDepth] = 8;
|
||||
|
||||
// 4) Max texture size : load from config file.
|
||||
const int nTSize =
|
||||
(int)GfParmGetNum(hparm, GfSCR_SECT_GLFEATURES, GfSCR_ATT_MAXTEXTURESIZE,
|
||||
(char*)NULL, (tdble)1024);
|
||||
_mapSelectedInt[TextureMaxSize] = nTSize;
|
||||
|
||||
// 5) Texture compression : load from config file.
|
||||
const std::string strTexComp =
|
||||
GfParmGetStr(hparm, GfSCR_SECT_GLFEATURES, GfSCR_ATT_TEXTURECOMPRESSION,
|
||||
GfSCR_ATT_TEXTURECOMPRESSION_ENABLED);
|
||||
_mapSelectedBool[TextureCompression] = strTexComp == GfSCR_ATT_TEXTURECOMPRESSION_ENABLED;
|
||||
|
||||
// 6) Multi-texturing : load from config file.
|
||||
const std::string strMultiTex =
|
||||
GfParmGetStr(hparm, GfSCR_SECT_GLFEATURES, GfSCR_ATT_MULTITEXTURING,
|
||||
GfSCR_ATT_MULTITEXTURING_ENABLED);
|
||||
_mapSelectedBool[MultiTexturing] = strMultiTex == GfSCR_ATT_MULTITEXTURING_ENABLED;
|
||||
|
||||
// 7) Rectangle textures : no choice, selected = supported (see checkSupport).
|
||||
|
||||
// 8) Non-power-of-2 textures : no choice, selected = supported (see checkSupport).
|
||||
|
||||
// 9) Multi-sampling : load from config file (but Buffers from actually supported value).
|
||||
const std::string strMultiSamp =
|
||||
GfParmGetStr(hparm, GfSCR_SECT_GLFEATURES, GfSCR_ATT_MULTISAMPLING,
|
||||
GfSCR_ATT_MULTISAMPLING_ENABLED);
|
||||
_mapSelectedBool[MultiSampling] = strMultiSamp == GfSCR_ATT_MULTISAMPLING_ENABLED;
|
||||
const int nSamples =
|
||||
(int)GfParmGetNum(hparm, GfSCR_SECT_GLFEATURES, GfSCR_ATT_MULTISAMPLING_SAMPLES,
|
||||
(char*)NULL, (tdble)8); // Good but reasonable value.
|
||||
_mapSelectedInt[MultiSamplingSamples] = nSamples;
|
||||
|
||||
// Close params.
|
||||
if (!hparmConfig)
|
||||
GfParmReleaseHandle(hparm);
|
||||
}
|
||||
|
||||
void GfglFeatures::storeSelection() const
|
||||
|
||||
// Save settings to screen.xml
|
||||
void GfglFeatures::storeSelection(void* hparmConfig) const
|
||||
{
|
||||
// Display what we have selected.
|
||||
dumpSelection();
|
||||
if (_funcStoreSelection)
|
||||
_funcStoreSelection();
|
||||
|
||||
// Open the config file if not already done.
|
||||
void* hparm;
|
||||
if (!hparmConfig)
|
||||
{
|
||||
std::ostringstream ossParm;
|
||||
ossParm << GfLocalDir() << GFSCR_CONF_FILE;
|
||||
hparm = GfParmReadFile(ossParm.str().c_str(), GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
hparm = hparmConfig;
|
||||
}
|
||||
|
||||
// Write new values.
|
||||
GfParmSetStr(hparm, GfSCR_SECT_GLFEATURES, GfSCR_ATT_TEXTURECOMPRESSION,
|
||||
isSelected(TextureCompression)
|
||||
? GfSCR_ATT_TEXTURECOMPRESSION_ENABLED : GfSCR_ATT_TEXTURECOMPRESSION_DISABLED);
|
||||
GfParmSetNum(hparm, GfSCR_SECT_GLFEATURES, GfSCR_ATT_MAXTEXTURESIZE, (char*)NULL,
|
||||
(tdble)getSelected(TextureMaxSize));
|
||||
GfParmSetStr(hparm, GfSCR_SECT_GLFEATURES, GfSCR_ATT_MULTITEXTURING,
|
||||
isSelected(MultiTexturing)
|
||||
? GfSCR_ATT_MULTITEXTURING_ENABLED : GfSCR_ATT_MULTITEXTURING_DISABLED);
|
||||
GfParmSetStr(hparm, GfSCR_SECT_GLFEATURES, GfSCR_ATT_MULTISAMPLING,
|
||||
isSelected(MultiSampling)
|
||||
? GfSCR_ATT_MULTISAMPLING_ENABLED : GfSCR_ATT_MULTISAMPLING_DISABLED);
|
||||
GfParmSetNum(hparm, GfSCR_SECT_GLFEATURES, GfSCR_ATT_MULTISAMPLING_SAMPLES, (char*)NULL,
|
||||
(tdble)getSelected(MultiSamplingSamples));
|
||||
|
||||
// Force 'best possible' mode for video initialization when anti-aliasing selected
|
||||
// (we can only activate this at GfScrInit time, and only this mode try and activates it).
|
||||
if (isSelected(MultiSampling))
|
||||
GfParmSetStr(hparm, GFSCR_SECT_PROP, GFSCR_ATT_VINIT, GFSCR_VAL_VINIT_BEST);
|
||||
|
||||
// Write new params to disk.
|
||||
GfParmWriteFile(NULL, hparm, "Screen");
|
||||
|
||||
// Close params.
|
||||
if (!hparmConfig)
|
||||
GfParmReleaseHandle(hparm);
|
||||
}
|
||||
|
||||
void GfglFeatures::dumpSelection() const
|
||||
{
|
||||
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");
|
||||
GfLogInfo(" Double buffer : %s\n", isSelected(DoubleBuffer) ? "On" : "Off");
|
||||
GfLogInfo(" Color depth : %d bits\n", getSelected(ColorDepth));
|
||||
GfLogInfo(" Alpha channel : %s",
|
||||
getSelected(AlphaDepth) > 0 ? "On" : "Off");
|
||||
if (getSelected(AlphaDepth) > 0)
|
||||
GfLogInfo(" (%d bits)", getSelected(AlphaDepth));
|
||||
GfLogInfo("\n");
|
||||
GfLogInfo(" Max texture size : %d\n", getSelected(TextureMaxSize));
|
||||
GfLogInfo(" Texture compression : %s\n", isSelected(TextureCompression) ? "On" : "Off");
|
||||
GfLogInfo(" Multi-texturing : %s", isSelected(MultiTexturing) ? "On" : "Off");
|
||||
if (isSelected(MultiTexturing))
|
||||
GfLogInfo(" (%d units)", getSelected(MultiTexturingUnits));
|
||||
GfLogInfo("\n");
|
||||
GfLogInfo(" Rectangle textures : %s\n", isSelected(TextureRectangle) ? "On" : "Off");
|
||||
GfLogInfo(" Non power-of-2 textures : %s\n", isSelected(TextureNonPowerOf2) ? "On" : "Off");
|
||||
GfLogInfo(" Multi-sampling : %s", isSelected(MultiSampling) ? "On" : "Off");
|
||||
if (isSelected(MultiSampling))
|
||||
GfLogInfo(" (%d samples)", getSelected(MultiSamplingSamples));
|
||||
GfLogInfo("\n");
|
||||
}
|
||||
|
||||
bool GfglFeatures::isSelected(EFeatureBool eFeature) const
|
||||
|
@ -184,6 +377,13 @@ bool GfglFeatures::isSelected(EFeatureBool eFeature) const
|
|||
return itFeature == _mapSelectedBool.end() ? false : itFeature->second;
|
||||
}
|
||||
|
||||
void GfglFeatures::setSupported(EFeatureBool eFeature, bool bSupported)
|
||||
{
|
||||
_mapSupportedBool[eFeature] = bSupported;
|
||||
if (!bSupported && isSelected(eFeature))
|
||||
_mapSelectedBool[eFeature] = bSupported;
|
||||
}
|
||||
|
||||
bool GfglFeatures::isSupported(EFeatureBool eFeature) const
|
||||
{
|
||||
const std::map<EFeatureBool, bool>::const_iterator itFeature =
|
||||
|
@ -193,7 +393,7 @@ bool GfglFeatures::isSupported(EFeatureBool eFeature) const
|
|||
|
||||
void GfglFeatures::select(EFeatureBool eFeature, bool bSelected)
|
||||
{
|
||||
if (isSupported(eFeature))
|
||||
if (!bSelected || isSupported(eFeature))
|
||||
_mapSelectedBool[eFeature] = bSelected;
|
||||
// GfLogDebug("GfglFeatures::select(Bool:%d, %s) : supp=%s, new=%s\n",
|
||||
// (int)eFeature, bSelected ? "true" : "false",
|
||||
|
@ -208,6 +408,13 @@ int GfglFeatures::getSelected(EFeatureInt eFeature) const
|
|||
return itFeature == _mapSelectedInt.end() ? -1 : itFeature->second;
|
||||
}
|
||||
|
||||
void GfglFeatures::setSupported(EFeatureInt eFeature, int nSupportedValue)
|
||||
{
|
||||
_mapSupportedInt[eFeature] = nSupportedValue;
|
||||
if (nSupportedValue < getSelected(eFeature))
|
||||
_mapSelectedInt[eFeature] = nSupportedValue;
|
||||
}
|
||||
|
||||
int GfglFeatures::getSupported(EFeatureInt eFeature) const
|
||||
{
|
||||
const std::map<EFeatureInt, int>::const_iterator itFeature =
|
||||
|
@ -217,8 +424,9 @@ int GfglFeatures::getSupported(EFeatureInt eFeature) const
|
|||
|
||||
void GfglFeatures::select(EFeatureInt eFeature, int nSelectedValue)
|
||||
{
|
||||
if (getSupported(eFeature) != -1)
|
||||
_mapSelectedInt[eFeature] = nSelectedValue;
|
||||
if (nSelectedValue > getSupported(eFeature))
|
||||
nSelectedValue = getSupported(eFeature);
|
||||
_mapSelectedInt[eFeature] = nSelectedValue;
|
||||
// GfLogDebug("GfglFeatures::select(Int:%d, %d) : supp=%s, new=%d\n",
|
||||
// (int)eFeature, nSelectedValue, getSupported(eFeature) >= 0 ? "true" : "false",
|
||||
// _mapSelectedInt[eFeature]);
|
||||
|
|
|
@ -42,19 +42,19 @@
|
|||
|
||||
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),
|
||||
(through the OpenGL option menu or the screen.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.
|
||||
(Exceptions: MultiTexturingUnits = all available ones, MultiSamplingSamples = max level).
|
||||
GfglFeatures doesn't 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: GfglFeatures::self() mustn't be used before the 1st successfull call
|
||||
to SDL_SetVideoMode().
|
||||
Warning: GfglFeatures::checkSupport() mustn't be used before the 1st successfull call
|
||||
to SDL_SetVideoMode() (needs an up-and-running frame buffer).
|
||||
*/
|
||||
|
||||
class TGFCLIENT_API GfglFeatures
|
||||
|
@ -62,20 +62,17 @@ class TGFCLIENT_API GfglFeatures
|
|||
public:
|
||||
|
||||
// Access to the unique instance.
|
||||
static GfglFeatures* self();
|
||||
static GfglFeatures& self();
|
||||
|
||||
// Set the functions for "loading from" and "storing to" the feature selection XML file.
|
||||
void setSelectionLoader(void (*funcLoad)());
|
||||
void setSelectionStorer(void (*funcStore)());
|
||||
|
||||
// Check supported features (ask OpenGL).
|
||||
// Load selected features from the config file (default = GFSCR_CONF_FILE).
|
||||
void loadSelection(void* hparmConfig = 0);
|
||||
|
||||
// Check supported features (ask OpenGL), and update selection as needed.
|
||||
// Warning: Must not be called before any successfull call to SDL_SetVideoMode()
|
||||
void checkSupport();
|
||||
|
||||
// Load selected features from the feature selection XML file.
|
||||
void loadSelection();
|
||||
|
||||
// Store selected features to the feature selection XML file.
|
||||
void storeSelection() const;
|
||||
// Store selected features to the config file (default = GFSCR_CONF_FILE).
|
||||
void storeSelection(void* hparmConfig = 0) const;
|
||||
|
||||
// Dump selected features (in the current trace stream).
|
||||
void dumpSelection() const;
|
||||
|
@ -83,6 +80,7 @@ class TGFCLIENT_API GfglFeatures
|
|||
// Bool-valued features.
|
||||
enum EFeatureBool
|
||||
{
|
||||
DoubleBuffer,
|
||||
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.
|
||||
|
@ -92,16 +90,20 @@ class TGFCLIENT_API GfglFeatures
|
|||
void select(EFeatureBool eFeature, bool bSelected);
|
||||
bool isSelected(EFeatureBool eFeature) const;
|
||||
bool isSupported(EFeatureBool eFeature) const;
|
||||
void setSupported(EFeatureBool eFeature, bool bSupported);
|
||||
|
||||
// Integer-valued features (WARNING: For the moment, -1 means "not supported").
|
||||
enum EFeatureInt
|
||||
{
|
||||
ColorDepth, AlphaDepth,
|
||||
TextureMaxSize,
|
||||
MultiTexturingUnits // Number of texturing units.
|
||||
MultiTexturingUnits,
|
||||
MultiSamplingSamples
|
||||
};
|
||||
void select(EFeatureInt eFeature, int nSelectedValue);
|
||||
int getSelected(EFeatureInt eFeature) const;
|
||||
int getSupported(EFeatureInt eFeature) const;
|
||||
void setSupported(EFeatureInt eFeature, int nSupportedValue);
|
||||
|
||||
// Get the pointer to the named OpenGL extension function.
|
||||
static void* getProcAddress(const char* pszName);
|
||||
|
@ -115,10 +117,6 @@ class TGFCLIENT_API GfglFeatures
|
|||
// 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<EFeatureBool, bool> _mapSupportedBool;
|
||||
std::map<EFeatureInt, int> _mapSupportedInt;
|
||||
|
|
|
@ -96,7 +96,6 @@ static tScreenSize ADefScreenSizes[] =
|
|||
{ 928, 696 },
|
||||
{ 960, 600 },
|
||||
{ 960, 720 },
|
||||
{ 960, 1200 },
|
||||
{ 1024, 600 },
|
||||
{ 1024, 768 },
|
||||
{ 1152, 768 },
|
||||
|
@ -327,17 +326,6 @@ static void gfScrReshapeViewport(int width, int height)
|
|||
|
||||
bool GfScrInit(void)
|
||||
{
|
||||
char buf[512];
|
||||
int xw, yw;
|
||||
int winX, winY;
|
||||
void *handle;
|
||||
const char *fscr;
|
||||
const char *vinit;
|
||||
SDL_Surface *icon;
|
||||
|
||||
int maxfreq;
|
||||
int depth;
|
||||
|
||||
// Initialize SDL video subsystem (and exit if not supported).
|
||||
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
|
||||
{
|
||||
|
@ -374,25 +362,30 @@ bool GfScrInit(void)
|
|||
}
|
||||
|
||||
char pszDriverName[32];
|
||||
GfLogTrace("SDL video driver : '%s'\n", SDL_VideoDriverName(pszDriverName, 32));
|
||||
//GfLogTrace(" Hardware acceleration : %s\n", sdlVideoInfo->hw_available ? "true" : "false");
|
||||
//GfLogTrace(" Total video memory : %u Kb\n", sdlVideoInfo->video_mem);
|
||||
GfLogTrace("Maximum pixel depth : %d bits\n", sdlVideoInfo->vfmt->BitsPerPixel);
|
||||
GfLogInfo("SDL video backend info :\n");
|
||||
GfLogInfo(" Driver : %s\n", SDL_VideoDriverName(pszDriverName, 32));
|
||||
GfLogInfo(" Maximum color depth : %d bits\n", sdlVideoInfo->vfmt->BitsPerPixel);
|
||||
// These ones don't report actually real values on some configurations.
|
||||
// GfLogInfo(" Hardware acceleration : %s\n", sdlVideoInfo->hw_available ? "Yes" : "No");
|
||||
// GfLogInfo(" Total video memory : %u Kb\n", sdlVideoInfo->video_mem);
|
||||
|
||||
// Get graphical settings from config file.
|
||||
char buf[512];
|
||||
sprintf(buf, "%s%s", GfLocalDir(), GFSCR_CONF_FILE);
|
||||
handle = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
|
||||
xw = (int)GfParmGetNum(handle, GFSCR_SECT_PROP, GFSCR_ATT_X, (char*)NULL, 800);
|
||||
yw = (int)GfParmGetNum(handle, GFSCR_SECT_PROP, GFSCR_ATT_Y, (char*)NULL, 600);
|
||||
winX = (int)GfParmGetNum(handle, GFSCR_SECT_PROP, GFSCR_ATT_WIN_X, (char*)NULL, xw);
|
||||
winY = (int)GfParmGetNum(handle, GFSCR_SECT_PROP, GFSCR_ATT_WIN_Y, (char*)NULL, yw);
|
||||
depth = (int)GfParmGetNum(handle, GFSCR_SECT_PROP, GFSCR_ATT_BPP, (char*)NULL, 32);
|
||||
maxfreq = (int)GfParmGetNum(handle, GFSCR_SECT_PROP, GFSCR_ATT_MAXREFRESH, (char*)NULL, 160);
|
||||
|
||||
fscr = GfParmGetStr(handle, GFSCR_SECT_PROP, GFSCR_ATT_FSCR, GFSCR_VAL_NO);
|
||||
|
||||
vinit = GfParmGetStr(handle, GFSCR_SECT_PROP, GFSCR_ATT_VINIT, GFSCR_VAL_VINIT_COMPATIBLE);
|
||||
void* hparmScreen = GfParmReadFile(buf, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
|
||||
|
||||
int winX = (int)GfParmGetNum(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_WIN_X, (char*)NULL, 800);
|
||||
int winY = (int)GfParmGetNum(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_WIN_Y, (char*)NULL, 600);
|
||||
int depth = (int)GfParmGetNum(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_BPP, (char*)NULL, 32);
|
||||
//int maxfreq = (int)GfParmGetNum(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_MAXREFRESH, (char*)NULL, 160);
|
||||
const std::string strFullScreen =
|
||||
GfParmGetStr(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_FSCR, GFSCR_VAL_NO);
|
||||
const std::string strVideoInit =
|
||||
GfParmGetStr(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_VINIT, GFSCR_VAL_VINIT_COMPATIBLE);
|
||||
|
||||
// Load Open GL settings from config file.
|
||||
GfglFeatures::self().loadSelection();
|
||||
|
||||
// Set window/icon captions
|
||||
sprintf(buf, "Speed Dreams %s", VERSION_LONG);
|
||||
SDL_WM_SetCaption(buf, buf);
|
||||
|
@ -400,169 +393,256 @@ bool GfScrInit(void)
|
|||
// Set window icon (MUST be a 32x32 icon for Windows, and with black pixels as alpha ones,
|
||||
// as BMP doesn't support transparency).
|
||||
sprintf(buf, "%sdata/icons/icon.bmp", GfDataDir());
|
||||
if ((icon = SDL_LoadBMP(buf)))
|
||||
SDL_Surface* surfIcon = SDL_LoadBMP(buf);
|
||||
if (surfIcon)
|
||||
{
|
||||
SDL_SetColorKey(icon, SDL_SRCCOLORKEY, SDL_MapRGB(icon->format, 0, 0, 0));
|
||||
SDL_WM_SetIcon(icon, 0);
|
||||
SDL_FreeSurface(icon);
|
||||
SDL_SetColorKey(surfIcon, SDL_SRCCOLORKEY, SDL_MapRGB(surfIcon->format, 0, 0, 0));
|
||||
SDL_WM_SetIcon(surfIcon, 0);
|
||||
SDL_FreeSurface(surfIcon);
|
||||
}
|
||||
|
||||
// Set full screen mode if required.
|
||||
// Set full screen mode if selected.
|
||||
int videomode = SDL_OPENGL; // What about SDL_DOUBLEBUFFER ?
|
||||
if (!strcmp(fscr, "yes"))
|
||||
if (strFullScreen == "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)
|
||||
if (strVideoInit == GFSCR_VAL_VINIT_BEST)
|
||||
{
|
||||
// TODO: Check for better than default multi-sampling level
|
||||
// through SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, level);
|
||||
// Could not get it automatically detected till now.
|
||||
GfLogInfo("Detecting 'best possible mode' for video initialization.\n");
|
||||
|
||||
/* Set the minimum requirements for the OpenGL window */
|
||||
// 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_DOUBLEBUFFER, 1);
|
||||
|
||||
// Try to get "best" videomode with default anti-aliasing support :
|
||||
// 24 bit z-buffer with alpha channel.
|
||||
// Try to get "best" videomode with maximum anti-aliasing support :
|
||||
// 24 bit z-buffer with alpha channel
|
||||
// (even if not selected : we 1st detect what we can do at most).
|
||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
|
||||
// Detect the max supported number of samples.
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
|
||||
|
||||
// Failed : try without anti-aliasing.
|
||||
if (!ScreenSurface)
|
||||
int nSamples = 32; // Hard coded max value for the moment.
|
||||
while (!ScreenSurface && nSamples > 1)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, nSamples);
|
||||
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
|
||||
if (!ScreenSurface)
|
||||
{
|
||||
GfLogTrace("Can't get a video mode for a 24+8 bit "
|
||||
"%dx anti-aliased double-buffer\n", nSamples);
|
||||
nSamples /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Failed : try with anti-aliasing, but without alpha channel.
|
||||
// Store the detected anti-aliasing supported features.
|
||||
GfglFeatures::self().setSupported(GfglFeatures::MultiSampling, ScreenSurface != 0);
|
||||
if (ScreenSurface)
|
||||
GfglFeatures::self().setSupported(GfglFeatures::MultiSamplingSamples, nSamples);
|
||||
|
||||
if (ScreenSurface)
|
||||
SDL_FreeSurface(ScreenSurface);
|
||||
|
||||
// Then, back to the user selection (may have been updated by the detection above).
|
||||
GfLogInfo("Trying user selected 'best possible mode' for video initialization.\n");
|
||||
|
||||
if (GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
|
||||
{
|
||||
nSamples = GfglFeatures::self().getSelected(GfglFeatures::MultiSamplingSamples);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, nSamples);
|
||||
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
|
||||
if (!ScreenSurface)
|
||||
GfLogTrace("Can't get a video mode for a 24+8 bit "
|
||||
"%dx anti-aliased double-buffer\n", nSamples);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 1);
|
||||
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
|
||||
if (!ScreenSurface)
|
||||
GfLogTrace("Can't get a video mode for a 24+8 bit double-buffer\n");
|
||||
}
|
||||
|
||||
// Failed : try with anti-aliasing if selected, but without alpha channel.
|
||||
if (!ScreenSurface)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
|
||||
if (GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
|
||||
if (!ScreenSurface)
|
||||
GfLogTrace("Can't get a video mode for a 24 bit anti-aliased double-buffer\n");
|
||||
}
|
||||
|
||||
// Failed : try without anti-aliasing, and without alpha channel.
|
||||
if (!ScreenSurface)
|
||||
// Failed : try without anti-aliasing if selected, and without alpha channel.
|
||||
if (!ScreenSurface && GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
|
||||
if (!ScreenSurface)
|
||||
GfLogTrace("Can't get a video mode for a 24 bit double-buffer\n");
|
||||
}
|
||||
|
||||
// Failed : try 16 bit z-buffer and back with alpha channel and anti-aliasing.
|
||||
// Failed : try 16 bit z-buffer and back with alpha channel and anti-aliasing if selected.
|
||||
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);
|
||||
if (GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
|
||||
if (!ScreenSurface)
|
||||
GfLogTrace("Can't get a video mode for a 16+8 bit anti-aliased double-buffer\n");
|
||||
}
|
||||
|
||||
// Failed : try without anti-aliasing.
|
||||
if (!ScreenSurface)
|
||||
// Failed : try without anti-aliasing if selected.
|
||||
if (!ScreenSurface && GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
|
||||
if (!ScreenSurface)
|
||||
GfLogTrace("Can't get a video mode for a 16+8 bit double-buffer\n");
|
||||
}
|
||||
|
||||
// Failed : try with anti-aliasing, but without alpha channel.
|
||||
// Failed : try with anti-aliasing if selected, but without alpha channel.
|
||||
if (!ScreenSurface)
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
|
||||
if (GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
|
||||
if (!ScreenSurface)
|
||||
GfLogTrace("Can't get a video mode for a 16 bit anti-aliased double-buffer\n");
|
||||
}
|
||||
|
||||
// Failed : try without anti-aliasing, and without alpha channel.
|
||||
if (!ScreenSurface)
|
||||
// Failed : try without anti-aliasing if selected, and without alpha channel.
|
||||
if (!ScreenSurface && GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
|
||||
if (!ScreenSurface)
|
||||
GfLogTrace("Can't get a video mode for a 16 bit double-buffer\n");
|
||||
}
|
||||
|
||||
// Failed : Give up but say why.
|
||||
// Failed : Change display / Open GL settings and restart.
|
||||
if (!ScreenSurface)
|
||||
{
|
||||
GfLogWarning("The minimum display requirements are not fulfilled :\n");
|
||||
GfLogWarning("We need a double buffered RGB visual with a 16 bit depth buffer at least.\n");
|
||||
// Retry without anti-aliasing if selected if it was requested.
|
||||
if (GfglFeatures::self().isSelected(GfglFeatures::MultiSampling))
|
||||
{
|
||||
GfLogWarning("Failed to setup best supported video mode : "
|
||||
"retrying without anti-aliasing at all ...\n");
|
||||
GfglFeatures::self().select(GfglFeatures::MultiSampling, false);
|
||||
GfglFeatures::self().storeSelection(hparmScreen);
|
||||
}
|
||||
|
||||
// Otherwise, retry a "compatible" = "all defaults" initialization mode.
|
||||
else if (strFullScreen == "yes")
|
||||
{
|
||||
|
||||
GfLogWarning("Failed to setup full-screen best supported video mode : "
|
||||
"retrying in windowed mode ...\n");
|
||||
GfParmSetStr(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_FSCR, GFSCR_VAL_NO);
|
||||
GfParmWriteFile(NULL, hparmScreen, "Screen");
|
||||
}
|
||||
|
||||
// Otherwise, retry a "compatible" = "all defaults" initialization mode.
|
||||
else
|
||||
{
|
||||
|
||||
GfLogWarning("Failed to setup best supported video mode : "
|
||||
"falling back to a more compatible default mode ...\n");
|
||||
GfParmSetStr(hparmScreen, GFSCR_SECT_PROP, GFSCR_ATT_VINIT,
|
||||
GFSCR_VAL_VINIT_COMPATIBLE);
|
||||
GfParmWriteFile(NULL, hparmScreen, "Screen");
|
||||
}
|
||||
|
||||
GfParmReleaseHandle(hparmScreen);
|
||||
GfRestart(); // Never returns.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Store the detected anti-aliasing supported features.
|
||||
GfglFeatures::self().setSupported(GfglFeatures::MultiSampling, false);
|
||||
GfglFeatures::self().setSupported(GfglFeatures::MultiSamplingSamples, -1);
|
||||
}
|
||||
|
||||
GfParmReleaseHandle(hparmScreen);
|
||||
|
||||
// Video initialization with generic compatible settings.
|
||||
if (!ScreenSurface)
|
||||
{
|
||||
GfLogInfo("Trying generic video initialization with requested size and color depth, fallback.\n\n");
|
||||
GfLogInfo("Trying 'default compatible' mode for video initialization.\n");
|
||||
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
|
||||
if (!ScreenSurface)
|
||||
GfLogTrace("Can't get a %s%dx%dx%d compatible video mode\n",
|
||||
strFullScreen == "yes" ? "full-screen " : "", winX, winY, depth);
|
||||
}
|
||||
|
||||
// Failed : Try and remove the full-screen requirement if present ...
|
||||
if (!ScreenSurface && strFullScreen == "yes")
|
||||
{
|
||||
videomode &= ~SDL_FULLSCREEN;
|
||||
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
|
||||
if (!ScreenSurface)
|
||||
GfLogTrace("Can't get a non-full-screen %dx%dx%d compatible video mode\n",
|
||||
winX, winY, depth);
|
||||
}
|
||||
|
||||
// Failed : Try with a lower fallback size : should be supported everywhere ...
|
||||
if (!ScreenSurface)
|
||||
{
|
||||
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 size %dx%d and requested color depth.\n\n",
|
||||
winX, winY);
|
||||
ScreenSurface = SDL_SetVideoMode(winX, winY, depth, videomode);
|
||||
if (!ScreenSurface)
|
||||
GfLogTrace("Can't get a %dx%dx%d compatible video mode\n", winX, winY, depth);
|
||||
}
|
||||
|
||||
// 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);
|
||||
if (!ScreenSurface)
|
||||
GfLogTrace("Can't get a %dx%dx%d compatible video mode\n", winX, winY, depth);
|
||||
}
|
||||
|
||||
// Failed : No way ... no more ideas !
|
||||
if (!ScreenSurface)
|
||||
{
|
||||
GfLogError("Unable to get any compatible video mode"
|
||||
" (fallback resolution not supported) : giving up !\n\n");
|
||||
" (fallback resolution / color depth not supported) : giving up !\n\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
GfParmReleaseHandle(handle);
|
||||
|
||||
// If we get here, that's because we succeeded in getting a valid video mode :-)
|
||||
|
||||
// Save view geometry and screen center.
|
||||
GfViewWidth = xw;
|
||||
GfViewHeight = yw;
|
||||
GfScrCenX = xw / 2;
|
||||
GfScrCenY = yw / 2;
|
||||
GfViewWidth = winX;
|
||||
GfViewHeight = winY;
|
||||
GfScrCenX = winX / 2;
|
||||
GfScrCenY = winY / 2;
|
||||
|
||||
// Report video mode and OpenGL features finally obtained.
|
||||
GfLogInfo("Current video mode :\n");
|
||||
// Report about selected SDL video mode.
|
||||
GfLogInfo("Selected SDL 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);
|
||||
GfLogInfo(" Color depth : %d bits\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);
|
||||
// Initialize the Open GL feature management layer and report about the supported features
|
||||
// (may appear double work for anti-aliasing support - see above -
|
||||
// but we can't check such support before a successfull call to SDL_SetVideoMode()).
|
||||
GfglFeatures::self().checkSupport();
|
||||
|
||||
// TODO: Is anti-aliasing really related to video mode initialization ?
|
||||
// What about moving this to gfglCheckGLFeatures and enable it later ?
|
||||
GfLogInfo("Enabled 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");
|
||||
if (glMSamp)
|
||||
GfLogInfo(" (multi-sampling level %d)\n", glMSampLevel);
|
||||
// Report about the actually selected support, after checking support.
|
||||
GfglFeatures::self().dumpSelection();
|
||||
|
||||
#ifdef WIN32
|
||||
// Under Windows, give an initial position to the window if not full-screen mode
|
||||
|
@ -586,9 +666,6 @@ bool GfScrInit(void)
|
|||
GfuiApp().eventLoop().setReshapeCB(gfScrReshapeViewport);
|
||||
GfuiApp().eventLoop().postRedisplay();
|
||||
|
||||
// Initialize Open GL feature management layer
|
||||
//TODO:gfglCheckGLFeatures();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -671,7 +748,7 @@ int GfScrCaptureAsPNG(const char *filename)
|
|||
free(img);
|
||||
|
||||
if (!nStatus)
|
||||
GfLogDebug("Captured screen to %s (capture=%.3f s, PNG=%.3f s)\n",
|
||||
GfLogTrace("Captured screen to %s (capture=%.3f s, PNG=%.3f s)\n",
|
||||
filename, dCaptureDuration, dFileWriteDuration);
|
||||
else
|
||||
GfLogError("Failed to capture screen to %s\n", filename);
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
|
||||
#define GFSCR_SECT_PROP "Screen Properties"
|
||||
|
||||
#define GFSCR_ATT_X "x"
|
||||
#define GFSCR_ATT_Y "y"
|
||||
#define GFSCR_ATT_BPP "bpp"
|
||||
#define GFSCR_ATT_WIN_X "window width"
|
||||
#define GFSCR_ATT_WIN_Y "window height"
|
||||
|
@ -88,6 +86,23 @@
|
|||
#define GFSCR_ATTR_BLUE "blue"
|
||||
#define GFSCR_ATTR_ALPHA "alpha"
|
||||
|
||||
#define GfSCR_SECT_GLFEATURES "OpenGL Features"
|
||||
|
||||
#define GfSCR_ATT_TEXTURECOMPRESSION "texture compression"
|
||||
#define GfSCR_ATT_TEXTURECOMPRESSION_ENABLED "enabled"
|
||||
#define GfSCR_ATT_TEXTURECOMPRESSION_DISABLED "disabled"
|
||||
|
||||
#define GfSCR_ATT_MAXTEXTURESIZE "max texture size"
|
||||
|
||||
#define GfSCR_ATT_MULTITEXTURING "multi-texturing"
|
||||
#define GfSCR_ATT_MULTITEXTURING_ENABLED "enabled"
|
||||
#define GfSCR_ATT_MULTITEXTURING_DISABLED "disabled"
|
||||
|
||||
#define GfSCR_ATT_MULTISAMPLING "multi-sampling"
|
||||
#define GfSCR_ATT_MULTISAMPLING_ENABLED "enabled"
|
||||
#define GfSCR_ATT_MULTISAMPLING_DISABLED "disabled"
|
||||
|
||||
#define GfSCR_ATT_MULTISAMPLING_SAMPLES "multi-sampling samples"
|
||||
|
||||
SDL_Surface* gfScrGetScreenSurface();
|
||||
|
||||
|
|
|
@ -16,18 +16,16 @@
|
|||
<!DOCTYPE params SYSTEM "../tgf/params.dtd">
|
||||
|
||||
|
||||
<params name="Screen" version="1.1">
|
||||
<params name="Screen" version="1.2">
|
||||
|
||||
<section name="Screen Properties">
|
||||
<attnum name="x" val="800"/>
|
||||
<attnum name="y" val="600"/>
|
||||
<attnum name="window width" val="800"/>
|
||||
<attnum name="window height" val="600"/>
|
||||
<attnum name="bpp" val="24"/>
|
||||
<attstr name="fullscreen" in="yes,no" val="no"/>
|
||||
<attnum name="gamma" val="2"/>
|
||||
<attnum name="window width" val="800"/>
|
||||
<attnum name="window height" val="600"/>
|
||||
<attstr name="video mode detect" in="auto,manual" val="auto"/>
|
||||
<attstr name="video mode init" in="compatible,best" val="compatible"/>
|
||||
<attstr name="video mode init" in="compatible,best" val="best"/>
|
||||
</section>
|
||||
|
||||
<section name="Menu Font">
|
||||
|
@ -240,6 +238,13 @@
|
|||
|
||||
</section>
|
||||
|
||||
<section name="OpenGL Features">
|
||||
<attstr name="texture compression" val="enabled"/>
|
||||
<attnum name="max texture size" val="8192"/>
|
||||
<attstr name="multi-texturing" val="enabled"/>
|
||||
<attstr name="multi-sampling" val="enabled"/>
|
||||
</section>
|
||||
|
||||
</params>
|
||||
<!-- Emacs settings : Keep this comment at the end of the file
|
||||
Local variables:
|
||||
|
|
|
@ -1221,9 +1221,6 @@ ssgEntity *grssgLoadAC3D ( const char *fname, const grssgLoaderOptions* options
|
|||
static ssgEntity *myssgLoadAC ( const char *fname, const grssgLoaderOptions* options )
|
||||
{
|
||||
|
||||
if (grMaxTextureUnits==0)
|
||||
grInitMultiTex();
|
||||
|
||||
char filename [ 1024 ] ;
|
||||
current_options -> makeModelPath ( filename, fname ) ;
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "grscreen.h"
|
||||
#include "grscene.h"
|
||||
#include "grsound.h"
|
||||
#include "grloadac.h"
|
||||
#include "grutil.h"
|
||||
#include "grcarlight.h"
|
||||
#include "grboard.h"
|
||||
|
@ -73,7 +74,9 @@ int grNbArrangeScreens = 0;
|
|||
// Current screen index.
|
||||
static int nCurrentScreenIndex = 0;
|
||||
|
||||
static grssgLoaderOptions options(/*bDoMipMap*/true);
|
||||
|
||||
// TODO: Move this to glfeatures.
|
||||
#ifdef WIN32
|
||||
PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2fARB = NULL;
|
||||
PFNGLMULTITEXCOORD2FVARBPROC glMultiTexCoord2fvARB = NULL;
|
||||
|
@ -82,15 +85,21 @@ PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB = NULL;
|
|||
#endif
|
||||
|
||||
|
||||
// Set up OpenGL for multi-texturing support
|
||||
int grInitMultiTex(void)
|
||||
// Set up OpenGL features from user settings.
|
||||
static void setupOpenGLFeatures(void)
|
||||
{
|
||||
grMaxTextureUnits = 1;
|
||||
static bool bInitialized = false;
|
||||
|
||||
if (GfglFeatures::self()->isSelected(GfglFeatures::MultiTexturing))
|
||||
// Don't do it twice.
|
||||
if (bInitialized)
|
||||
return;
|
||||
|
||||
// Multi-texturing.
|
||||
grMaxTextureUnits = 1;
|
||||
if (GfglFeatures::self().isSelected(GfglFeatures::MultiTexturing))
|
||||
{
|
||||
// Use the selected number of texture units.
|
||||
grMaxTextureUnits = GfglFeatures::self()->getSelected(GfglFeatures::MultiTexturingUnits);
|
||||
grMaxTextureUnits = GfglFeatures::self().getSelected(GfglFeatures::MultiTexturingUnits);
|
||||
|
||||
#ifdef WIN32
|
||||
// Retrieve the addresses of multi-texturing functions under Windows
|
||||
|
@ -102,8 +111,9 @@ int grInitMultiTex(void)
|
|||
glMultiTexCoord2fvARB = (PFNGLMULTITEXCOORD2FVARBPROC)wglGetProcAddress("glMultiTexCoord2fvARB");
|
||||
#endif
|
||||
}
|
||||
|
||||
return grMaxTextureUnits;
|
||||
|
||||
// Done once and for all.
|
||||
bInitialized = true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -365,10 +375,6 @@ initView(int x, int y, int width, int height, int /* flag */, void *screen)
|
|||
char buf[256];
|
||||
int i;
|
||||
|
||||
// TODO: Is this needed, as already done in initTrack ?
|
||||
if (grMaxTextureUnits==0)
|
||||
grInitMultiTex();
|
||||
|
||||
grWinx = x;
|
||||
grWiny = y;
|
||||
grWinw = width;
|
||||
|
@ -630,6 +636,11 @@ initTrack(tTrack *track)
|
|||
// TODO: Find a solution to init the graphics first independent of objects.
|
||||
grContext.makeCurrent();
|
||||
|
||||
setupOpenGLFeatures();
|
||||
|
||||
grssgSetCurrentOptions(&options);
|
||||
|
||||
// Now, do the real track loading job.
|
||||
grTrackHandle = GfParmReadFile(track->filename, GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
|
||||
if (grNbActiveScreens > 0)
|
||||
grLoadScene(track);
|
||||
|
@ -641,15 +652,19 @@ initTrack(tTrack *track)
|
|||
void
|
||||
shutdownTrack(void)
|
||||
{
|
||||
// Do the real track termination job.
|
||||
grShutdownScene();
|
||||
|
||||
grShutdownState();
|
||||
|
||||
if (grTrackHandle)
|
||||
{
|
||||
GfParmReleaseHandle(grTrackHandle);
|
||||
grTrackHandle = 0;
|
||||
}
|
||||
|
||||
// And then the context termination job (should not be there, see initTrack).
|
||||
options.endLoad();
|
||||
|
||||
grShutdownState();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -41,8 +41,6 @@ extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB ;
|
|||
extern PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTextureARB ;
|
||||
#endif
|
||||
|
||||
extern int grInitMultiTex();
|
||||
|
||||
extern int grWinx, grWiny, grWinw, grWinh;
|
||||
extern int grVectFlag;
|
||||
extern int grVectDispFlag[];
|
||||
|
|
|
@ -110,8 +110,6 @@ grInitScene(void)
|
|||
}//grInitScene
|
||||
|
||||
|
||||
static grssgLoaderOptions options(/*bDoMipMap*/true);
|
||||
|
||||
int
|
||||
grLoadScene(tTrack *track)
|
||||
{
|
||||
|
@ -120,11 +118,6 @@ grLoadScene(tTrack *track)
|
|||
const char *acname;
|
||||
ssgEntity *desc;
|
||||
|
||||
if (grMaxTextureUnits == 0)
|
||||
grInitMultiTex();
|
||||
|
||||
grssgSetCurrentOptions(&options);
|
||||
|
||||
// Load graphic options if not already done.
|
||||
if(!grHandle) {
|
||||
sprintf(buf, "%s%s", GfLocalDir(), GR_PARAM_FILE);
|
||||
|
@ -215,8 +208,6 @@ grShutdownScene(void)
|
|||
TheScene = 0;
|
||||
|
||||
grShutdownBackground();
|
||||
|
||||
options.endLoad();
|
||||
}//grShutdownScene
|
||||
|
||||
|
||||
|
|
|
@ -285,7 +285,7 @@ bool grMakeMipMaps (GLubyte *image, int xsize, int ysize, int zsize, int mipmap)
|
|||
GLint ww;
|
||||
|
||||
GLint textureTargetFormat;
|
||||
if (GfglFeatures::self()->isSelected(GfglFeatures::TextureCompression)) {
|
||||
if (GfglFeatures::self().isSelected(GfglFeatures::TextureCompression)) {
|
||||
//GfTrace("COMPRESSOR: ");
|
||||
|
||||
switch (zsize) {
|
||||
|
@ -311,7 +311,7 @@ bool grMakeMipMaps (GLubyte *image, int xsize, int ysize, int zsize, int mipmap)
|
|||
//GfTrace("NON COMPRESSOR\n");
|
||||
}
|
||||
|
||||
const int tlimit = GfglFeatures::self()->getSelected(GfglFeatures::TextureMaxSize);
|
||||
const int tlimit = GfglFeatures::self().getSelected(GfglFeatures::TextureMaxSize);
|
||||
|
||||
do {
|
||||
if (xsize > tlimit || ysize > tlimit) {
|
||||
|
|
|
@ -385,7 +385,7 @@ cGrTrackMap::cGrTrackMap()
|
|||
// 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 (GfglFeatures::self()->isSelected(GfglFeatures::TextureCompression)) {
|
||||
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);
|
||||
|
|
|
@ -115,6 +115,8 @@ void DisplayMenu::onAccept(void *pDisplayMenu)
|
|||
// Save display settings.
|
||||
pMenu->storeSettings();
|
||||
|
||||
// TODO: Simply call GfuiApp().restart() (when it is implemented ;-).
|
||||
|
||||
// Shutdown the user interface.
|
||||
LegacyMenu::self().shutdown();
|
||||
|
||||
|
@ -185,8 +187,8 @@ void DisplayMenu::loadSettings()
|
|||
_eDisplayMode = strcmp(pszFullScreen, GFSCR_VAL_YES) ? eWindowed : eFullScreen;
|
||||
|
||||
// Screen / window size.
|
||||
_nScreenWidth = (int)GfParmGetNum(hScrConfParams, GFSCR_SECT_PROP, GFSCR_ATT_X, NULL, 800);
|
||||
_nScreenHeight = (int)GfParmGetNum(hScrConfParams, GFSCR_SECT_PROP, GFSCR_ATT_Y, NULL, 600);
|
||||
_nScreenWidth = (int)GfParmGetNum(hScrConfParams, GFSCR_SECT_PROP, GFSCR_ATT_WIN_X, NULL, 800);
|
||||
_nScreenHeight = (int)GfParmGetNum(hScrConfParams, GFSCR_SECT_PROP, GFSCR_ATT_WIN_Y, NULL, 600);
|
||||
|
||||
// Video initialization mode : Compatible or Best.
|
||||
const char *pszVideoInitMode =
|
||||
|
@ -214,8 +216,6 @@ void DisplayMenu::storeSettings() const
|
|||
GfParmReadFile(ossConfFile.str().c_str(), GFPARM_RMODE_STD | GFPARM_RMODE_CREAT);
|
||||
|
||||
// Write new settings.
|
||||
GfParmSetNum(hScrConfParams, GFSCR_SECT_PROP, GFSCR_ATT_X, (char*)NULL, _nScreenWidth);
|
||||
GfParmSetNum(hScrConfParams, GFSCR_SECT_PROP, GFSCR_ATT_Y, (char*)NULL, _nScreenHeight);
|
||||
GfParmSetNum(hScrConfParams, GFSCR_SECT_PROP, GFSCR_ATT_WIN_X, (char*)NULL, _nScreenWidth);
|
||||
GfParmSetNum(hScrConfParams, GFSCR_SECT_PROP, GFSCR_ATT_WIN_Y, (char*)NULL, _nScreenHeight);
|
||||
GfParmSetNum(hScrConfParams, GFSCR_SECT_PROP, GFSCR_ATT_BPP, (char*)NULL, _nColorDepth);
|
||||
|
@ -234,6 +234,12 @@ void DisplayMenu::storeSettings() const
|
|||
const char* pszDisplMode =
|
||||
(_eDisplayMode == eFullScreen) ? GFSCR_VAL_YES : GFSCR_VAL_NO;
|
||||
GfParmSetStr(hScrConfParams, GFSCR_SECT_PROP, GFSCR_ATT_FSCR, pszDisplMode);
|
||||
|
||||
// Deselect anti-aliasing from the Open GL settings if 'compatible' mode
|
||||
// selected for the video initialization (anti-aliasing not supported in this mode).
|
||||
if (_eVideoInitMode == eCompatible)
|
||||
GfParmSetStr(hScrConfParams, GfSCR_SECT_GLFEATURES, GfSCR_ATT_MULTISAMPLING,
|
||||
GfSCR_ATT_MULTISAMPLING_DISABLED);
|
||||
|
||||
// Write and release screen config params file.
|
||||
GfParmWriteFile(NULL, hScrConfParams, "Screen");
|
||||
|
|
|
@ -18,25 +18,28 @@
|
|||
***************************************************************************/
|
||||
|
||||
/** @file
|
||||
|
||||
Open GL options menu
|
||||
@version $Id$
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
|
||||
#include <graphic.h>
|
||||
#include <portability.h>
|
||||
#include <tgfclient.h>
|
||||
#include <glfeatures.h>
|
||||
|
||||
#include "legacymenu.h"
|
||||
#include "openglconfig.h"
|
||||
|
||||
|
||||
// Texture compression.
|
||||
static const char *ATextureCompTexts[] =
|
||||
{GR_ATT_TEXTURECOMPRESSION_DISABLED, GR_ATT_TEXTURECOMPRESSION_ENABLED};
|
||||
{GfSCR_ATT_TEXTURECOMPRESSION_DISABLED, GfSCR_ATT_TEXTURECOMPRESSION_ENABLED};
|
||||
static const int NTextureComps =
|
||||
sizeof(ATextureCompTexts) / sizeof(ATextureCompTexts[0]);
|
||||
static int NCurTextureCompIndex = 0;
|
||||
|
@ -50,11 +53,11 @@ static int NMaxTextureSizes = sizeof(AMaxTextureSizeTexts) / sizeof(AMaxTextureS
|
|||
static int NCurMaxTextureSizeIndex = 0;
|
||||
static int MaxTextureSizeLabelId;
|
||||
|
||||
static const int NDefaultTextSize = 64; // In case everything goes wrong.
|
||||
static const int NDefaultTextureSize = 64; // In case everything goes wrong.
|
||||
|
||||
// Multi-texturing.
|
||||
static const char *AMultiTextureTexts[] =
|
||||
{GR_ATT_MULTITEXTURING_DISABLED, GR_ATT_MULTITEXTURING_ENABLED};
|
||||
{GfSCR_ATT_MULTITEXTURING_DISABLED, GfSCR_ATT_MULTITEXTURING_ENABLED};
|
||||
static const int NMultiTextures =
|
||||
sizeof(AMultiTextureTexts) / sizeof(AMultiTextureTexts[0]);
|
||||
static int NCurMultiTextureIndex = 0;
|
||||
|
@ -63,11 +66,9 @@ 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]);
|
||||
// Multi-sampling (initialized in OpenGLMenuInit).
|
||||
static std::vector<std::string> VecMultiSampleTexts;
|
||||
static int NMultiSamples = 0;
|
||||
static int NCurMultiSampleIndex = 0;
|
||||
|
||||
static int MultiSampleLabelId;
|
||||
|
@ -78,100 +79,49 @@ static int MultiSampleRightButtonId;
|
|||
static void *ScrHandle = NULL;
|
||||
static void *PrevHandle = NULL;
|
||||
|
||||
|
||||
// TODO: Why not moving this to tgfclient ? or the graphics engine ? or tgfdata ?
|
||||
// Load the selected OpenGL features from the graphic parameter file.
|
||||
void OpenGLLoadSelectedFeatures()
|
||||
{
|
||||
char buf[512];
|
||||
|
||||
// Read OpenGL configuration from graph.xml, and select relevant OpenGL features
|
||||
// (by default, select the max possible values for supported features).
|
||||
snprintf(buf, sizeof(buf), "%s%s", GfLocalDir(), 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_ENABLED);
|
||||
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_ENABLED);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// TODO: Why not moving this to tgfclient ? or the graphics engine ? or tgfdata ?
|
||||
// Save the selected OpenGL features to the graphic parameter file.
|
||||
void OpenGLStoreSelectedFeatures()
|
||||
{
|
||||
// Save settings to graph.xml
|
||||
char buf[512];
|
||||
snprintf(buf, sizeof(buf), "%s%s", GfLocalDir(), GR_PARAM_FILE);
|
||||
void *paramHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD | GFPARM_RMODE_CREAT);
|
||||
|
||||
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 bool BMultiSamplingWasSelected = false;
|
||||
static int BPrevMultiSamplingSamples = 0;
|
||||
|
||||
static void onAccept(void *)
|
||||
{
|
||||
// Store current state of settings to the GL features layer.
|
||||
GfglFeatures::self()->select(GfglFeatures::TextureCompression,
|
||||
GfglFeatures::self().select(GfglFeatures::TextureCompression,
|
||||
strcmp(ATextureCompTexts[NCurTextureCompIndex],
|
||||
GR_ATT_TEXTURECOMPRESSION_ENABLED) ? false : true);
|
||||
GfglFeatures::self()->select(GfglFeatures::TextureMaxSize,
|
||||
GfSCR_ATT_TEXTURECOMPRESSION_ENABLED) ? false : true);
|
||||
GfglFeatures::self().select(GfglFeatures::TextureMaxSize,
|
||||
AMaxTextureSizeTexts[NCurMaxTextureSizeIndex]);
|
||||
GfglFeatures::self()->select(GfglFeatures::MultiTexturing,
|
||||
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);
|
||||
GfSCR_ATT_MULTITEXTURING_ENABLED) ? false : true);
|
||||
GfglFeatures::self().select(GfglFeatures::MultiSampling,
|
||||
VecMultiSampleTexts[NCurMultiSampleIndex]
|
||||
!= GfSCR_ATT_MULTISAMPLING_DISABLED);
|
||||
if (VecMultiSampleTexts[NCurMultiSampleIndex] != GfSCR_ATT_MULTISAMPLING_DISABLED)
|
||||
GfglFeatures::self().select(GfglFeatures::MultiSamplingSamples,
|
||||
(int)pow(2, NCurMultiSampleIndex));
|
||||
|
||||
// Store settings from the GL features layer to the graph.xml file.
|
||||
GfglFeatures::self()->storeSelection();
|
||||
GfglFeatures::self().storeSelection();
|
||||
|
||||
// Return to previous screen.
|
||||
GfuiScreenActivate(PrevHandle);
|
||||
|
||||
// But actually restart the game if the multi-sampling feature settings changed
|
||||
// (we can't change this without re-initializing the video mode).
|
||||
if (GfglFeatures::self().isSelected(GfglFeatures::MultiSampling) != BMultiSamplingWasSelected
|
||||
|| GfglFeatures::self().getSelected(GfglFeatures::MultiSamplingSamples) != BPrevMultiSamplingSamples)
|
||||
{
|
||||
// TODO: Simply call GfuiApp().restart() (when it is implemented ;-).
|
||||
|
||||
// Shutdown the user interface.
|
||||
LegacyMenu::self().shutdown();
|
||||
|
||||
// Restart the game.
|
||||
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) ?
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle texture compression state enabled/disabled.
|
||||
|
@ -192,7 +142,8 @@ static void changeMultiTextureState(void *vp)
|
|||
static void changeMultiSampleState(void *vp)
|
||||
{
|
||||
NCurMultiSampleIndex = (NCurMultiSampleIndex + (int)(long)vp + NMultiSamples) % NMultiSamples;
|
||||
GfuiLabelSetText(ScrHandle, MultiSampleLabelId, AMultiSampleTexts[NCurMultiSampleIndex]);
|
||||
GfuiLabelSetText(ScrHandle, MultiSampleLabelId,
|
||||
VecMultiSampleTexts[NCurMultiSampleIndex].c_str());
|
||||
}
|
||||
|
||||
|
||||
|
@ -203,9 +154,11 @@ static void changeMaxTextureSizeState(void *vp)
|
|||
|
||||
long delta = (long)vp;
|
||||
NCurMaxTextureSizeIndex += delta;
|
||||
if (NCurMaxTextureSizeIndex < 0) {
|
||||
if (NCurMaxTextureSizeIndex < 0)
|
||||
{
|
||||
NCurMaxTextureSizeIndex = NMaxTextureSizes - 1;
|
||||
} else if (NCurMaxTextureSizeIndex >= NMaxTextureSizes) {
|
||||
} else if (NCurMaxTextureSizeIndex >= NMaxTextureSizes)
|
||||
{
|
||||
NCurMaxTextureSizeIndex= 0;
|
||||
}
|
||||
|
||||
|
@ -221,13 +174,15 @@ static void onActivate(void * /* dummy */)
|
|||
|
||||
// Initialize current state and GUI from the GL features layer.
|
||||
// 1) Texture compression.
|
||||
if (GfglFeatures::self()->isSupported(GfglFeatures::TextureCompression))
|
||||
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])) {
|
||||
GfglFeatures::self().isSelected(GfglFeatures::TextureCompression)
|
||||
? GfSCR_ATT_TEXTURECOMPRESSION_ENABLED : GfSCR_ATT_TEXTURECOMPRESSION_DISABLED;
|
||||
for (i = 0; i < NTextureComps; i++)
|
||||
{
|
||||
if (!strcmp(pszTexComp, ATextureCompTexts[i]))
|
||||
{
|
||||
NCurTextureCompIndex = i;
|
||||
break;
|
||||
}
|
||||
|
@ -245,13 +200,15 @@ static void onActivate(void * /* dummy */)
|
|||
|
||||
// 2) Max texture size.
|
||||
int sizelimit =
|
||||
GfglFeatures::self()->getSupported(GfglFeatures::TextureMaxSize);
|
||||
GfglFeatures::self().getSupported(GfglFeatures::TextureMaxSize);
|
||||
int tsize =
|
||||
GfglFeatures::self()->getSelected(GfglFeatures::TextureMaxSize);
|
||||
GfglFeatures::self().getSelected(GfglFeatures::TextureMaxSize);
|
||||
|
||||
int maxsizenb = 0;
|
||||
for (i = 0; i < NMaxTextureSizes; i++) {
|
||||
if (AMaxTextureSizeTexts[i] <= sizelimit) {
|
||||
for (i = 0; i < NMaxTextureSizes; i++)
|
||||
{
|
||||
if (AMaxTextureSizeTexts[i] <= sizelimit)
|
||||
{
|
||||
maxsizenb = i;
|
||||
} else {
|
||||
break;
|
||||
|
@ -262,19 +219,24 @@ static void onActivate(void * /* dummy */)
|
|||
NMaxTextureSizes = maxsizenb + 1;
|
||||
|
||||
bool found = false;
|
||||
for (i = 0; i < NMaxTextureSizes; i++) {
|
||||
if (AMaxTextureSizeTexts[i] == tsize) {
|
||||
for (i = 0; i < NMaxTextureSizes; i++)
|
||||
{
|
||||
if (AMaxTextureSizeTexts[i] == tsize)
|
||||
{
|
||||
NCurMaxTextureSizeIndex = i;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (!found)
|
||||
{
|
||||
// Should never come here if there is no bug in OpenGL.
|
||||
tsize = NDefaultTextSize;
|
||||
for (i = 0; i < NMaxTextureSizes; i++) {
|
||||
if (AMaxTextureSizeTexts[i] == tsize) {
|
||||
tsize = NDefaultTextureSize;
|
||||
for (i = 0; i < NMaxTextureSizes; i++)
|
||||
{
|
||||
if (AMaxTextureSizeTexts[i] == tsize)
|
||||
{
|
||||
NCurMaxTextureSizeIndex = i;
|
||||
break;
|
||||
}
|
||||
|
@ -285,13 +247,15 @@ static void onActivate(void * /* dummy */)
|
|||
GfuiLabelSetText(ScrHandle, MaxTextureSizeLabelId, valuebuf);
|
||||
|
||||
// 3) Multi-texturing.
|
||||
if (GfglFeatures::self()->isSupported(GfglFeatures::MultiTexturing))
|
||||
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])) {
|
||||
GfglFeatures::self().isSelected(GfglFeatures::MultiTexturing)
|
||||
? GfSCR_ATT_MULTITEXTURING_ENABLED : GfSCR_ATT_MULTITEXTURING_DISABLED;
|
||||
for (i = 0; i < NMultiTextures; i++)
|
||||
{
|
||||
if (!strcmp(pszMultiTex, AMultiTextureTexts[i]))
|
||||
{
|
||||
NCurMultiTextureIndex = i;
|
||||
break;
|
||||
}
|
||||
|
@ -307,21 +271,29 @@ static void onActivate(void * /* dummy */)
|
|||
GfuiLabelSetText(ScrHandle, MultiTextureLabelId, "Not supported");
|
||||
}
|
||||
|
||||
// 4) Multi-sampling.
|
||||
if (GfglFeatures::self()->isSupported(GfglFeatures::MultiSampling))
|
||||
// 4) Multi-sampling (anti-aliasing).
|
||||
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;
|
||||
BMultiSamplingWasSelected =
|
||||
GfglFeatures::self().isSelected(GfglFeatures::MultiSampling);
|
||||
BPrevMultiSamplingSamples =
|
||||
GfglFeatures::self().getSelected(GfglFeatures::MultiSamplingSamples);
|
||||
|
||||
if (!BMultiSamplingWasSelected)
|
||||
NCurMultiSampleIndex = 0;
|
||||
else
|
||||
{
|
||||
NCurMultiSampleIndex = 0;
|
||||
int nSamples = 1;
|
||||
while (nSamples < BPrevMultiSamplingSamples)
|
||||
{
|
||||
NCurMultiSampleIndex++;
|
||||
nSamples *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
GfuiLabelSetText(ScrHandle, MultiSampleLabelId,
|
||||
AMultiSampleTexts[NCurMultiSampleIndex]);
|
||||
VecMultiSampleTexts[NCurMultiSampleIndex].c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -336,54 +308,53 @@ static void onActivate(void * /* dummy */)
|
|||
void* OpenGLMenuInit(void *prevMenu)
|
||||
{
|
||||
// Has screen already been created?
|
||||
if (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);
|
||||
void *hparmMenu = LoadMenuXML("opengloptionsmenu.xml");
|
||||
CreateStaticControls(hparmMenu,ScrHandle);
|
||||
|
||||
// Texture compression.
|
||||
TextureCompLeftButtonId =
|
||||
CreateButtonControl(ScrHandle, param, "TextureCompressionLeftArrowButton", (void*)-1,
|
||||
CreateButtonControl(ScrHandle, hparmMenu, "TextureCompressionLeftArrowButton", (void*)-1,
|
||||
changeTextureCompressionState);
|
||||
TextureCompRightButtonId =
|
||||
CreateButtonControl(ScrHandle, param, "TextureCompressionRightArrowButton", (void*)+1,
|
||||
CreateButtonControl(ScrHandle, hparmMenu, "TextureCompressionRightArrowButton", (void*)+1,
|
||||
changeTextureCompressionState);
|
||||
TextureCompLabelId = CreateLabelControl(ScrHandle,param,"TextureCompressionLabel");
|
||||
TextureCompLabelId = CreateLabelControl(ScrHandle,hparmMenu,"TextureCompressionLabel");
|
||||
|
||||
// Texture sizing.
|
||||
CreateButtonControl(ScrHandle,param,"MaxTextureSizeLeftArrowButton", (void*)-1,
|
||||
CreateButtonControl(ScrHandle,hparmMenu,"MaxTextureSizeLeftArrowButton", (void*)-1,
|
||||
changeMaxTextureSizeState);
|
||||
CreateButtonControl(ScrHandle,param,"MaxTextureSizeRightArrowButton", (void*)+1,
|
||||
CreateButtonControl(ScrHandle,hparmMenu,"MaxTextureSizeRightArrowButton", (void*)+1,
|
||||
changeMaxTextureSizeState);
|
||||
MaxTextureSizeLabelId = CreateLabelControl(ScrHandle,param,"MaxTextureSizeLabel");
|
||||
MaxTextureSizeLabelId = CreateLabelControl(ScrHandle,hparmMenu,"MaxTextureSizeLabel");
|
||||
|
||||
// Multi-texturing.
|
||||
MultiTextureLeftButtonId =
|
||||
CreateButtonControl(ScrHandle, param, "MultiTextureLeftArrowButton", (void*)-1,
|
||||
CreateButtonControl(ScrHandle, hparmMenu, "MultiTextureLeftArrowButton", (void*)-1,
|
||||
changeMultiTextureState);
|
||||
MultiTextureRightButtonId =
|
||||
CreateButtonControl(ScrHandle, param, "MultiTextureRightArrowButton", (void*)+1,
|
||||
CreateButtonControl(ScrHandle, hparmMenu, "MultiTextureRightArrowButton", (void*)+1,
|
||||
changeMultiTextureState);
|
||||
MultiTextureLabelId = CreateLabelControl(ScrHandle,param,"MultiTextureLabel");
|
||||
MultiTextureLabelId = CreateLabelControl(ScrHandle,hparmMenu,"MultiTextureLabel");
|
||||
|
||||
// Multi-sampling.
|
||||
MultiSampleLeftButtonId =
|
||||
CreateButtonControl(ScrHandle, param, "MultiSampleLeftArrowButton", (void*)-1,
|
||||
CreateButtonControl(ScrHandle, hparmMenu, "MultiSampleLeftArrowButton", (void*)-1,
|
||||
changeMultiSampleState);
|
||||
MultiSampleRightButtonId =
|
||||
CreateButtonControl(ScrHandle, param, "MultiSampleRightArrowButton", (void*)+1,
|
||||
CreateButtonControl(ScrHandle, hparmMenu, "MultiSampleRightArrowButton", (void*)+1,
|
||||
changeMultiSampleState);
|
||||
MultiSampleLabelId = CreateLabelControl(ScrHandle,param,"MultiSampleLabel");
|
||||
MultiSampleLabelId = CreateLabelControl(ScrHandle,hparmMenu,"MultiSampleLabel");
|
||||
|
||||
CreateButtonControl(ScrHandle,param,"AcceptButton",NULL, onAccept);
|
||||
CreateButtonControl(ScrHandle,param,"CancelButton",prevMenu, GfuiScreenActivate);
|
||||
CreateButtonControl(ScrHandle,hparmMenu,"AcceptButton",NULL, onAccept);
|
||||
CreateButtonControl(ScrHandle,hparmMenu,"CancelButton",prevMenu, GfuiScreenActivate);
|
||||
|
||||
GfParmReleaseHandle(param);
|
||||
GfParmReleaseHandle(hparmMenu);
|
||||
|
||||
GfuiAddKey(ScrHandle, GFUIK_RETURN, "Save", NULL, onAccept, NULL);
|
||||
GfuiAddKey(ScrHandle, GFUIK_ESCAPE, "Cancel Selection", prevMenu, GfuiScreenActivate, NULL);
|
||||
|
@ -393,5 +364,24 @@ void* OpenGLMenuInit(void *prevMenu)
|
|||
GfuiAddKey(ScrHandle, GFUIK_RIGHT, "Increase Texture Size Limit", (void*)1, changeMaxTextureSizeState, NULL);
|
||||
GfuiAddKey(ScrHandle, ' ', "Toggle Texture Compression", (void*)1, changeTextureCompressionState, NULL);
|
||||
|
||||
// Initialize multi-sampling levels.
|
||||
NMultiSamples = 1;
|
||||
VecMultiSampleTexts.push_back(GfSCR_ATT_MULTISAMPLING_DISABLED);
|
||||
if (GfglFeatures::self().isSupported(GfglFeatures::MultiSampling)
|
||||
&& GfglFeatures::self().getSupported(GfglFeatures::MultiSamplingSamples) > 1)
|
||||
{
|
||||
const int nMaxSamples =
|
||||
GfglFeatures::self().getSupported(GfglFeatures::MultiSamplingSamples);
|
||||
NMultiSamples += (int)(log(nMaxSamples) / log(2));
|
||||
std::ostringstream ossVal;
|
||||
for (int nVal = 2; nVal <= nMaxSamples; nVal *= 2)
|
||||
{
|
||||
ossVal.str("");
|
||||
ossVal << nVal << "x";
|
||||
VecMultiSampleTexts.push_back(ossVal.str());
|
||||
}
|
||||
GfLogDebug("OpenGLMenuInit: nMaxSamples=%d, NMultiSamples=%d, VecMultiSampleTexts.size=%u\n", nMaxSamples, NMultiSamples, VecMultiSampleTexts.size());
|
||||
}
|
||||
|
||||
return ScrHandle;
|
||||
}
|
||||
|
|
|
@ -17,10 +17,7 @@
|
|||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include <glfeatures.h>
|
||||
|
||||
#include "client.h"
|
||||
#include "openglconfig.h"
|
||||
#include "splash.h"
|
||||
|
||||
/*
|
||||
|
@ -42,11 +39,6 @@
|
|||
bool
|
||||
MenuEntry(void)
|
||||
{
|
||||
// Initialize gaming framework UI.
|
||||
GfglFeatures::self()->setSelectionLoader(OpenGLLoadSelectedFeatures);
|
||||
GfglFeatures::self()->setSelectionStorer(OpenGLStoreSelectedFeatures);
|
||||
GfglFeatures::self()->loadSelection();
|
||||
|
||||
// Open the splash screen, load menus in "background" and finally open the main menu.
|
||||
return SplashScreen();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue