Beispiel #1
0
/** Adds GL limits to the json data structure.
 *  (C) 2014-2015 Wildfire Games (0 A.D.), ported by Joerg Henrichs
 */
void getGLLimits(HardwareStats::Json *json)
{
    // Various macros to make the data assembly shorter.
#define INTEGER(id)                               \
    do {                                          \
        GLint i = -1;                             \
        glGetIntegerv(GL_##id, &i);               \
        if (glGetError()==GL_NO_ERROR)            \
            json->add("GL_"#id, i);               \
    } while (false)
#define INTEGER2(id)                              \
    do {                                          \
        GLint i[2] = { -1, -1 };                  \
        glGetIntegerv(GL_##id, i);                \
        if (glGetError()==GL_NO_ERROR) {          \
            json->add("GL_"#id"[0]", i[0]);       \
            json->add("GL_"#id"[1]", i[1]);       \
        }                                         \
    } while (false)
#define FLOAT(id)                                 \
    do {                                          \
        GLfloat f = -1.0f;                        \
        glGetFloatv(GL_##id, &f);                 \
        if (glGetError()==GL_NO_ERROR)            \
            json->add("GL_"#id, f);               \
    } while (false)
#define FLOAT2(id)                                \
    do {                                          \
        GLfloat f[2] = {-1.0f, -1.0f};            \
        glGetFloatv(GL_##id,  f);                 \
        if (glGetError()==GL_NO_ERROR)  {         \
            json->add("GL_"#id"[0]", f[0]);       \
            json->add("GL_"#id"[1]", f[1]);       \
        }                                         \
    } while (false)
#define STRING(id)                                         \
    do {                                                   \
        const char* c = (const char*)glGetString(GL_##id); \
        if(!c) c="";                                       \
        json->add("GL_"#id, c);                            \
    } while (false)


    STRING(VERSION);
    STRING(VENDOR);
    STRING(RENDERER);
    INTEGER(SUBPIXEL_BITS);
    INTEGER(MAX_TEXTURE_SIZE);
    INTEGER(MAX_CUBE_MAP_TEXTURE_SIZE);
    INTEGER2(MAX_VIEWPORT_DIMS);
    FLOAT2(ALIASED_POINT_SIZE_RANGE);
    FLOAT2(ALIASED_LINE_WIDTH_RANGE);
    INTEGER(SAMPLE_BUFFERS);
    INTEGER(SAMPLES);
    // TODO: compressed texture formats
    INTEGER(RED_BITS);
    INTEGER(GREEN_BITS);
    INTEGER(BLUE_BITS);
    INTEGER(ALPHA_BITS);
    INTEGER(DEPTH_BITS);
    INTEGER(STENCIL_BITS);

    return;

#ifdef NOT_DONE_YET
#define QUERY(target, pname) do { \
    GLint i = -1; \
    pglGetQueryivARB(GL_##target, GL_##pname, &i); \
    if (ogl_SquelchError(GL_INVALID_ENUM)) \
    scriptInterface.SetProperty(settings, "GL_" #target ".GL_" #pname, errstr); \
else \
    scriptInterface.SetProperty(settings, "GL_" #target ".GL_" #pname, i); \
        } while (false)
#define VERTEXPROGRAM(id) do { \
    GLint i = -1; \
    pglGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_##id, &i); \
    if (ogl_SquelchError(GL_INVALID_ENUM)) \
    scriptInterface.SetProperty(settings, "GL_VERTEX_PROGRAM_ARB.GL_" #id, errstr); \
else \
    scriptInterface.SetProperty(settings, "GL_VERTEX_PROGRAM_ARB.GL_" #id, i); \
        } while (false)
#define FRAGMENTPROGRAM(id) do { \
    GLint i = -1; \
    pglGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_##id, &i); \
    if (ogl_SquelchError(GL_INVALID_ENUM)) \
    scriptInterface.SetProperty(settings, "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, errstr); \
else \
    scriptInterface.SetProperty(settings, "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, i); \
        } while (false)
#define BOOL(id) INTEGER(id)


#if !CONFIG2_GLES
        INTEGER(MAX_LIGHTS);
        INTEGER(MAX_CLIP_PLANES);
        // Skip MAX_COLOR_MATRIX_STACK_DEPTH (only in imaging subset)
        INTEGER(MAX_MODELVIEW_STACK_DEPTH);
        INTEGER(MAX_PROJECTION_STACK_DEPTH);
        INTEGER(MAX_TEXTURE_STACK_DEPTH);
#endif
#if !CONFIG2_GLES
        INTEGER(MAX_3D_TEXTURE_SIZE);
#endif
#if !CONFIG2_GLES
        INTEGER(MAX_PIXEL_MAP_TABLE);
        INTEGER(MAX_NAME_STACK_DEPTH);
        INTEGER(MAX_LIST_NESTING);
        INTEGER(MAX_EVAL_ORDER);
#endif
#if !CONFIG2_GLES
        INTEGER(MAX_ATTRIB_STACK_DEPTH);
        INTEGER(MAX_CLIENT_ATTRIB_STACK_DEPTH);
        INTEGER(AUX_BUFFERS);
        BOOL(RGBA_MODE);
        BOOL(INDEX_MODE);
        BOOL(DOUBLEBUFFER);
        BOOL(STEREO);
#endif
#if !CONFIG2_GLES
        FLOAT2(SMOOTH_POINT_SIZE_RANGE);
        FLOAT(SMOOTH_POINT_SIZE_GRANULARITY);
#endif
#if !CONFIG2_GLES
        FLOAT2(SMOOTH_LINE_WIDTH_RANGE);
        FLOAT(SMOOTH_LINE_WIDTH_GRANULARITY);
        // Skip MAX_CONVOLUTION_WIDTH, MAX_CONVOLUTION_HEIGHT (only in imaging subset)
        INTEGER(MAX_ELEMENTS_INDICES);
        INTEGER(MAX_ELEMENTS_VERTICES);
        INTEGER(MAX_TEXTURE_UNITS);
#endif
#if !CONFIG2_GLES
        INTEGER(INDEX_BITS);
#endif
#if !CONFIG2_GLES
        INTEGER(ACCUM_RED_BITS);
        INTEGER(ACCUM_GREEN_BITS);
        INTEGER(ACCUM_BLUE_BITS);
        INTEGER(ACCUM_ALPHA_BITS);
#endif
#if !CONFIG2_GLES
        // Core OpenGL 2.0 (treated as extensions):
        if (ogl_HaveExtension("GL_EXT_texture_lod_bias"))
        {
            FLOAT(MAX_TEXTURE_LOD_BIAS_EXT);
        }
        if (ogl_HaveExtension("GL_ARB_occlusion_query"))
        {
            QUERY(SAMPLES_PASSED, QUERY_COUNTER_BITS);
        }
        if (ogl_HaveExtension("GL_ARB_shading_language_100"))
        {
            STRING(SHADING_LANGUAGE_VERSION_ARB);
        }
        if (ogl_HaveExtension("GL_ARB_vertex_shader"))
        {
            INTEGER(MAX_VERTEX_ATTRIBS_ARB);
            INTEGER(MAX_VERTEX_UNIFORM_COMPONENTS_ARB);
            INTEGER(MAX_VARYING_FLOATS_ARB);
            INTEGER(MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB);
            INTEGER(MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB);
        }
        if (ogl_HaveExtension("GL_ARB_fragment_shader"))
        {
            INTEGER(MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB);
        }
        if (ogl_HaveExtension("GL_ARB_vertex_shader") || ogl_HaveExtension("GL_ARB_fragment_shader") ||
            ogl_HaveExtension("GL_ARB_vertex_program") || ogl_HaveExtension("GL_ARB_fragment_program"))
        {
            INTEGER(MAX_TEXTURE_IMAGE_UNITS_ARB);
            INTEGER(MAX_TEXTURE_COORDS_ARB);
        }
        if (ogl_HaveExtension("GL_ARB_draw_buffers"))
        {
            INTEGER(MAX_DRAW_BUFFERS_ARB);
        }
        // Core OpenGL 3.0:
        if (ogl_HaveExtension("GL_EXT_gpu_shader4"))
        {
            INTEGER(MIN_PROGRAM_TEXEL_OFFSET); // no _EXT version of these in glext.h
            INTEGER(MAX_PROGRAM_TEXEL_OFFSET);
        }
        if (ogl_HaveExtension("GL_EXT_framebuffer_object"))
        {
            INTEGER(MAX_COLOR_ATTACHMENTS_EXT);
            INTEGER(MAX_RENDERBUFFER_SIZE_EXT);
        }
        if (ogl_HaveExtension("GL_EXT_framebuffer_multisample"))
        {
            INTEGER(MAX_SAMPLES_EXT);
        }
        if (ogl_HaveExtension("GL_EXT_texture_array"))
        {
            INTEGER(MAX_ARRAY_TEXTURE_LAYERS_EXT);
        }
        if (ogl_HaveExtension("GL_EXT_transform_feedback"))
        {
            INTEGER(MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT);
            INTEGER(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT);
            INTEGER(MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT);
        }
        // Other interesting extensions:
        if (ogl_HaveExtension("GL_EXT_timer_query") || ogl_HaveExtension("GL_ARB_timer_query"))
        {
            QUERY(TIME_ELAPSED, QUERY_COUNTER_BITS);
        }
        if (ogl_HaveExtension("GL_ARB_timer_query"))
        {
            QUERY(TIMESTAMP, QUERY_COUNTER_BITS);
        }
        if (ogl_HaveExtension("GL_EXT_texture_filter_anisotropic"))
        {
            FLOAT(MAX_TEXTURE_MAX_ANISOTROPY_EXT);
        }
        if (ogl_HaveExtension("GL_ARB_texture_rectangle"))
        {
            INTEGER(MAX_RECTANGLE_TEXTURE_SIZE_ARB);
        }
        if (ogl_HaveExtension("GL_ARB_vertex_program") || ogl_HaveExtension("GL_ARB_fragment_program"))
        {
            INTEGER(MAX_PROGRAM_MATRICES_ARB);
            INTEGER(MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB);
        }
        if (ogl_HaveExtension("GL_ARB_vertex_program"))
        {
            VERTEXPROGRAM(MAX_PROGRAM_ENV_PARAMETERS_ARB);
            VERTEXPROGRAM(MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
            VERTEXPROGRAM(MAX_PROGRAM_INSTRUCTIONS_ARB);
            VERTEXPROGRAM(MAX_PROGRAM_TEMPORARIES_ARB);
            VERTEXPROGRAM(MAX_PROGRAM_PARAMETERS_ARB);
            VERTEXPROGRAM(MAX_PROGRAM_ATTRIBS_ARB);
            VERTEXPROGRAM(MAX_PROGRAM_ADDRESS_REGISTERS_ARB);
            VERTEXPROGRAM(MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB);
            VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEMPORARIES_ARB);
            VERTEXPROGRAM(MAX_PROGRAM_NATIVE_PARAMETERS_ARB);
            VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ATTRIBS_ARB);
            VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB);
            if (ogl_HaveExtension("GL_ARB_fragment_program"))
            {
                // The spec seems to say these should be supported, but
                // Mesa complains about them so let's not bother
                /*
                VERTEXPROGRAM(MAX_PROGRAM_ALU_INSTRUCTIONS_ARB);
                VERTEXPROGRAM(MAX_PROGRAM_TEX_INSTRUCTIONS_ARB);
                VERTEXPROGRAM(MAX_PROGRAM_TEX_INDIRECTIONS_ARB);
                VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB);
                VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB);
                VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB);
                */
            }
        }
        if (ogl_HaveExtension("GL_ARB_fragment_program"))
        {
            FRAGMENTPROGRAM(MAX_PROGRAM_ENV_PARAMETERS_ARB);
            FRAGMENTPROGRAM(MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
            FRAGMENTPROGRAM(MAX_PROGRAM_INSTRUCTIONS_ARB);
            FRAGMENTPROGRAM(MAX_PROGRAM_ALU_INSTRUCTIONS_ARB);
            FRAGMENTPROGRAM(MAX_PROGRAM_TEX_INSTRUCTIONS_ARB);
            FRAGMENTPROGRAM(MAX_PROGRAM_TEX_INDIRECTIONS_ARB);
            FRAGMENTPROGRAM(MAX_PROGRAM_TEMPORARIES_ARB);
            FRAGMENTPROGRAM(MAX_PROGRAM_PARAMETERS_ARB);
            FRAGMENTPROGRAM(MAX_PROGRAM_ATTRIBS_ARB);
            FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB);
            FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB);
            FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB);
            FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB);
            FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEMPORARIES_ARB);
            FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_PARAMETERS_ARB);
            FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ATTRIBS_ARB);
            if (ogl_HaveExtension("GL_ARB_vertex_program"))
            {
                // The spec seems to say these should be supported, but
                // Intel drivers on Windows complain about them so let's not bother
                /*
                FRAGMENTPROGRAM(MAX_PROGRAM_ADDRESS_REGISTERS_ARB);
                FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB);
                */
            }
        }
        if (ogl_HaveExtension("GL_ARB_geometry_shader4"))
        {
            INTEGER(MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB);
            INTEGER(MAX_GEOMETRY_OUTPUT_VERTICES_ARB);
            INTEGER(MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB);
            INTEGER(MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB);
            INTEGER(MAX_GEOMETRY_VARYING_COMPONENTS_ARB);
            INTEGER(MAX_VERTEX_VARYING_COMPONENTS_ARB);
        }
#else // CONFIG2_GLES
        // Core OpenGL ES 2.0:
        STRING(SHADING_LANGUAGE_VERSION);
        INTEGER(MAX_VERTEX_ATTRIBS);
        INTEGER(MAX_VERTEX_UNIFORM_VECTORS);
        INTEGER(MAX_VARYING_VECTORS);
        INTEGER(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
        INTEGER(MAX_VERTEX_TEXTURE_IMAGE_UNITS);
        INTEGER(MAX_FRAGMENT_UNIFORM_VECTORS);
        INTEGER(MAX_TEXTURE_IMAGE_UNITS);
        INTEGER(MAX_RENDERBUFFER_SIZE);
#endif // CONFIG2_GLES
#ifdef SDL_VIDEO_DRIVER_X11
#define GLXQCR_INTEGER(id) do { \
    unsigned int i = UINT_MAX; \
    if (pglXQueryCurrentRendererIntegerMESA(id, &i)) \
    scriptInterface.SetProperty(settings, #id, i); \
        } while (false)
#define GLXQCR_INTEGER2(id) do { \
    unsigned int i[2] = { UINT_MAX, UINT_MAX }; \
    if (pglXQueryCurrentRendererIntegerMESA(id, i)) { \
    scriptInterface.SetProperty(settings, #id "[0]", i[0]); \
    scriptInterface.SetProperty(settings, #id "[1]", i[1]); \
    } \
        } while (false)
#define GLXQCR_INTEGER3(id) do { \
    unsigned int i[3] = { UINT_MAX, UINT_MAX, UINT_MAX }; \
    if (pglXQueryCurrentRendererIntegerMESA(id, i)) { \
    scriptInterface.SetProperty(settings, #id "[0]", i[0]); \
    scriptInterface.SetProperty(settings, #id "[1]", i[1]); \
    scriptInterface.SetProperty(settings, #id "[2]", i[2]); \
    } \
        } while (false)
#define GLXQCR_STRING(id) do { \
    const char* str = pglXQueryCurrentRendererStringMESA(id); \
    if (str) \
    scriptInterface.SetProperty(settings, #id ".string", str); \
        } while (false)
        SDL_SysWMinfo wminfo;
        SDL_VERSION(&wminfo.version);
        if (SDL_GetWMInfo(&wminfo) && wminfo.subsystem == SDL_SYSWM_X11)
        {
            Display* dpy = wminfo.info.x11.gfxdisplay;
            int scrnum = DefaultScreen(dpy);
            const char* glxexts = glXQueryExtensionsString(dpy, scrnum);
            scriptInterface.SetProperty(settings, "glx_extensions", glxexts);
            if (strstr(glxexts, "GLX_MESA_query_renderer") && pglXQueryCurrentRendererIntegerMESA && pglXQueryCurrentRendererStringMESA)
            {
                GLXQCR_INTEGER(GLX_RENDERER_VENDOR_ID_MESA);
                GLXQCR_INTEGER(GLX_RENDERER_DEVICE_ID_MESA);
                GLXQCR_INTEGER3(GLX_RENDERER_VERSION_MESA);
                GLXQCR_INTEGER(GLX_RENDERER_ACCELERATED_MESA);
                GLXQCR_INTEGER(GLX_RENDERER_VIDEO_MEMORY_MESA);
                GLXQCR_INTEGER(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA);
                GLXQCR_INTEGER(GLX_RENDERER_PREFERRED_PROFILE_MESA);
                GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA);
                GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA);
                GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA);
                GLXQCR_INTEGER2(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA);
                GLXQCR_STRING(GLX_RENDERER_VENDOR_ID_MESA);
                GLXQCR_STRING(GLX_RENDERER_DEVICE_ID_MESA);
            }
        }
#endif // SDL_VIDEO_DRIVER_X11

#endif  // ifdef XX
}   // getGLLimits
Beispiel #2
0
void InitGraphics(const CmdLineArgs& args, int flags)
{
	const bool setup_vmode = (flags & INIT_HAVE_VMODE) == 0;

	if(setup_vmode)
	{
		InitSDL();

		if (!g_VideoMode.InitSDL())
			throw PSERROR_System_VmodeFailed(); // abort startup

#if !SDL_VERSION_ATLEAST(2, 0, 0)
		SDL_WM_SetCaption("0 A.D.", "0 A.D.");
#endif
	}

	RunHardwareDetection();

	const int quality = SANE_TEX_QUALITY_DEFAULT;	// TODO: set value from config file
	SetTextureQuality(quality);

	ogl_WarnIfError();

	// Optionally start profiler GPU timings automatically
	// (By default it's only enabled by a hotkey, for performance/compatibility)
	bool profilerGPUEnable = false;
	CFG_GET_VAL("profiler2.autoenable", profilerGPUEnable);
	if (profilerGPUEnable)
		g_Profiler2.EnableGPU();

	if(!g_Quickstart)
	{
		WriteSystemInfo();
		// note: no longer vfs_display here. it's dog-slow due to unbuffered
		// file output and very rarely needed.
	}

	if(g_DisableAudio)
		ISoundManager::SetEnabled(false);

	g_GUI = new CGUIManager();

	// (must come after SetVideoMode, since it calls ogl_Init)
	if (ogl_HaveExtensions(0, "GL_ARB_vertex_program", "GL_ARB_fragment_program", NULL) != 0 // ARB
		&& ogl_HaveExtensions(0, "GL_ARB_vertex_shader", "GL_ARB_fragment_shader", NULL) != 0) // GLSL
	{
		DEBUG_DISPLAY_ERROR(
			L"Your graphics card doesn't appear to be fully compatible with OpenGL shaders."
			L" In the future, the game will not support pre-shader graphics cards."
			L" You are advised to try installing newer drivers and/or upgrade your graphics card."
			L" For more information, please see http://www.wildfiregames.com/forum/index.php?showtopic=16734"
		);
		// TODO: actually quit once fixed function support is dropped
	}

	const char* missing = ogl_HaveExtensions(0,
		"GL_ARB_multitexture",
		"GL_EXT_draw_range_elements",
		"GL_ARB_texture_env_combine",
		"GL_ARB_texture_env_dot3",
		NULL);
	if(missing)
	{
		wchar_t buf[500];
		swprintf_s(buf, ARRAY_SIZE(buf),
			L"The %hs extension doesn't appear to be available on your computer."
			L" The game may still work, though - you are welcome to try at your own risk."
			L" If not or it doesn't look right, upgrade your graphics card.",
			missing
		);
		DEBUG_DISPLAY_ERROR(buf);
		// TODO: i18n
	}

	if (!ogl_HaveExtension("GL_ARB_texture_env_crossbar"))
	{
		DEBUG_DISPLAY_ERROR(
			L"The GL_ARB_texture_env_crossbar extension doesn't appear to be available on your computer."
			L" Shadows are not available and overall graphics quality might suffer."
			L" You are advised to try installing newer drivers and/or upgrade your graphics card.");
		g_Shadows = false;
	}

	ogl_WarnIfError();
	InitRenderer();

	InitInput();

	ogl_WarnIfError();

	try
	{
		if (!Autostart(args))
		{
			const bool setup_gui = ((flags & INIT_NO_GUI) == 0);
			// We only want to display the splash screen at startup
			shared_ptr<ScriptInterface> scriptInterface = g_GUI->GetScriptInterface();
			JSContext* cx = scriptInterface->GetContext();
			JSAutoRequest rq(cx);
			JS::RootedValue data(cx);
			if (g_GUI)
			{
				scriptInterface->Eval("({})", &data);
				scriptInterface->SetProperty(data, "isStartup", true);
			}
			InitPs(setup_gui, L"page_pregame.xml", g_GUI->GetScriptInterface().get(), data);
		}
	}
	catch (PSERROR_Game_World_MapLoadFailed& e)
	{
		// Map Loading failed

		// Start the engine so we have a GUI
		InitPs(true, L"page_pregame.xml", NULL, JS::UndefinedHandleValue);

		// Call script function to do the actual work
		//	(delete game data, switch GUI page, show error, etc.)
		CancelLoad(CStr(e.what()).FromUTF8());
	}
}
Beispiel #3
0
void InitGraphics(const CmdLineArgs& args, int flags)
{
	const bool setup_vmode = (flags & INIT_HAVE_VMODE) == 0;

	if(setup_vmode)
	{
		InitSDL();

		if (!g_VideoMode.InitSDL())
			throw PSERROR_System_VmodeFailed(); // abort startup

#if !SDL_VERSION_ATLEAST(2, 0, 0)
		SDL_WM_SetCaption("0 A.D.", "0 A.D.");
#endif
	}

	RunHardwareDetection();

	tex_codec_register_all();

	const int quality = SANE_TEX_QUALITY_DEFAULT;	// TODO: set value from config file
	SetTextureQuality(quality);

	ogl_WarnIfError();

	// Optionally start profiler GPU timings automatically
	// (By default it's only enabled by a hotkey, for performance/compatibility)
	bool profilerGPUEnable = false;
	CFG_GET_VAL("profiler2.gpu.autoenable", Bool, profilerGPUEnable);
	if (profilerGPUEnable)
		g_Profiler2.EnableGPU();

	if(!g_Quickstart)
	{
		WriteSystemInfo();
		// note: no longer vfs_display here. it's dog-slow due to unbuffered
		// file output and very rarely needed.
	}

	if(g_DisableAudio)
	{
		// speed up startup by disabling all sound
		// (OpenAL init will be skipped).
		// must be called before first snd_open.
#if CONFIG2_AUDIO
		CSoundManager::SetEnabled(false);
#endif
	}

	g_GUI = new CGUIManager(g_ScriptingHost.GetScriptInterface());

	// (must come after SetVideoMode, since it calls ogl_Init)
	const char* missing = ogl_HaveExtensions(0,
		"GL_ARB_multitexture",
		"GL_EXT_draw_range_elements",
		"GL_ARB_texture_env_combine",
		"GL_ARB_texture_env_dot3",
		NULL);
	if(missing)
	{
		wchar_t buf[500];
		swprintf_s(buf, ARRAY_SIZE(buf),
			L"The %hs extension doesn't appear to be available on your computer."
			L" The game may still work, though - you are welcome to try at your own risk."
			L" If not or it doesn't look right, upgrade your graphics card.",
			missing
		);
		DEBUG_DISPLAY_ERROR(buf);
		// TODO: i18n
	}

	if (!ogl_HaveExtension("GL_ARB_texture_env_crossbar"))
	{
		DEBUG_DISPLAY_ERROR(
			L"The GL_ARB_texture_env_crossbar extension doesn't appear to be available on your computer."
			L" Shadows are not available and overall graphics quality might suffer."
			L" You are advised to try installing newer drivers and/or upgrade your graphics card.");
		g_Shadows = false;
	}

	ogl_WarnIfError();
	InitRenderer();

	InitInput();

	ogl_WarnIfError();

	try
	{
		if (!Autostart(args))
		{
			const bool setup_gui = ((flags & INIT_NO_GUI) == 0);
			// We only want to display the splash screen at startup
			CScriptValRooted data;
			if (g_GUI)
			{
				ScriptInterface& scriptInterface = g_GUI->GetScriptInterface();
				scriptInterface.Eval("({})", data);
				scriptInterface.SetProperty(data.get(), "isStartup", true);
			}
			InitPs(setup_gui, L"page_pregame.xml", data.get());
		}
	}
	catch (PSERROR_Game_World_MapLoadFailed e)
	{
		// Map Loading failed

		// Start the engine so we have a GUI
		InitPs(true, L"page_pregame.xml", JSVAL_VOID);

		// Call script function to do the actual work
		//	(delete game data, switch GUI page, show error, etc.)
		CancelLoad(CStr(e.what()).FromUTF8());
	}
}
Beispiel #4
0
static void ReportGLLimits(ScriptInterface& scriptInterface, CScriptValRooted settings)
{
	const char* errstr = "(error)";

#define INTEGER(id) do { \
	GLint i = -1; \
	glGetIntegerv(GL_##id, &i); \
	if (ogl_SquelchError(GL_INVALID_ENUM)) \
		scriptInterface.SetProperty(settings.get(), "GL_" #id, errstr); \
	else \
		scriptInterface.SetProperty(settings.get(), "GL_" #id, i); \
	} while (false)

#define INTEGER2(id) do { \
	GLint i[2] = { -1, -1 }; \
	glGetIntegerv(GL_##id, i); \
	if (ogl_SquelchError(GL_INVALID_ENUM)) { \
		scriptInterface.SetProperty(settings.get(), "GL_" #id "[0]", errstr); \
		scriptInterface.SetProperty(settings.get(), "GL_" #id "[1]", errstr); \
	} else { \
		scriptInterface.SetProperty(settings.get(), "GL_" #id "[0]", i[0]); \
		scriptInterface.SetProperty(settings.get(), "GL_" #id "[1]", i[1]); \
	} \
	} while (false)

#define FLOAT(id) do { \
	GLfloat f = std::numeric_limits<GLfloat>::quiet_NaN(); \
	glGetFloatv(GL_##id, &f); \
	if (ogl_SquelchError(GL_INVALID_ENUM)) \
		scriptInterface.SetProperty(settings.get(), "GL_" #id, errstr); \
	else \
		scriptInterface.SetProperty(settings.get(), "GL_" #id, f); \
	} while (false)

#define FLOAT2(id) do { \
	GLfloat f[2] = { std::numeric_limits<GLfloat>::quiet_NaN(), std::numeric_limits<GLfloat>::quiet_NaN() }; \
	glGetFloatv(GL_##id, f); \
	if (ogl_SquelchError(GL_INVALID_ENUM)) { \
		scriptInterface.SetProperty(settings.get(), "GL_" #id "[0]", errstr); \
		scriptInterface.SetProperty(settings.get(), "GL_" #id "[1]", errstr); \
	} else { \
		scriptInterface.SetProperty(settings.get(), "GL_" #id "[0]", f[0]); \
		scriptInterface.SetProperty(settings.get(), "GL_" #id "[1]", f[1]); \
	} \
	} while (false)

#define STRING(id) do { \
	const char* c = (const char*)glGetString(GL_##id); \
	if (!c) c = ""; \
	if (ogl_SquelchError(GL_INVALID_ENUM)) c = errstr; \
	scriptInterface.SetProperty(settings.get(), "GL_" #id, std::string(c)); \
	}  while (false)

#define QUERY(target, pname) do { \
	GLint i = -1; \
	pglGetQueryivARB(GL_##target, GL_##pname, &i); \
	if (ogl_SquelchError(GL_INVALID_ENUM)) \
		scriptInterface.SetProperty(settings.get(), "GL_" #target ".GL_" #pname, errstr); \
	else \
		scriptInterface.SetProperty(settings.get(), "GL_" #target ".GL_" #pname, i); \
	} while (false)

#define VERTEXPROGRAM(id) do { \
	GLint i = -1; \
	pglGetProgramivARB(GL_VERTEX_PROGRAM_ARB, GL_##id, &i); \
	if (ogl_SquelchError(GL_INVALID_ENUM)) \
		scriptInterface.SetProperty(settings.get(), "GL_VERTEX_PROGRAM_ARB.GL_" #id, errstr); \
	else \
		scriptInterface.SetProperty(settings.get(), "GL_VERTEX_PROGRAM_ARB.GL_" #id, i); \
	} while (false)

#define FRAGMENTPROGRAM(id) do { \
	GLint i = -1; \
	pglGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, GL_##id, &i); \
	if (ogl_SquelchError(GL_INVALID_ENUM)) \
		scriptInterface.SetProperty(settings.get(), "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, errstr); \
	else \
		scriptInterface.SetProperty(settings.get(), "GL_FRAGMENT_PROGRAM_ARB.GL_" #id, i); \
	} while (false)

#define BOOL(id) INTEGER(id)

	ogl_WarnIfError();

	// Core OpenGL 1.3:
	// (We don't bother checking extension strings for anything older than 1.3;
	// it'll just produce harmless warnings)
	STRING(VERSION);
	STRING(VENDOR);
	STRING(RENDERER);
	STRING(EXTENSIONS);
#if !CONFIG2_GLES
	INTEGER(MAX_LIGHTS);
	INTEGER(MAX_CLIP_PLANES);
	// Skip MAX_COLOR_MATRIX_STACK_DEPTH (only in imaging subset)
	INTEGER(MAX_MODELVIEW_STACK_DEPTH);
	INTEGER(MAX_PROJECTION_STACK_DEPTH);
	INTEGER(MAX_TEXTURE_STACK_DEPTH);
#endif
	INTEGER(SUBPIXEL_BITS);
#if !CONFIG2_GLES
	INTEGER(MAX_3D_TEXTURE_SIZE);
#endif
	INTEGER(MAX_TEXTURE_SIZE);
	INTEGER(MAX_CUBE_MAP_TEXTURE_SIZE);
#if !CONFIG2_GLES
	INTEGER(MAX_PIXEL_MAP_TABLE);
	INTEGER(MAX_NAME_STACK_DEPTH);
	INTEGER(MAX_LIST_NESTING);
	INTEGER(MAX_EVAL_ORDER);
#endif
	INTEGER2(MAX_VIEWPORT_DIMS);
#if !CONFIG2_GLES
	INTEGER(MAX_ATTRIB_STACK_DEPTH);
	INTEGER(MAX_CLIENT_ATTRIB_STACK_DEPTH);
	INTEGER(AUX_BUFFERS);
	BOOL(RGBA_MODE);
	BOOL(INDEX_MODE);
	BOOL(DOUBLEBUFFER);
	BOOL(STEREO);
#endif
	FLOAT2(ALIASED_POINT_SIZE_RANGE);
#if !CONFIG2_GLES
	FLOAT2(SMOOTH_POINT_SIZE_RANGE);
	FLOAT(SMOOTH_POINT_SIZE_GRANULARITY);
#endif
	FLOAT2(ALIASED_LINE_WIDTH_RANGE);
#if !CONFIG2_GLES
	FLOAT2(SMOOTH_LINE_WIDTH_RANGE);
	FLOAT(SMOOTH_LINE_WIDTH_GRANULARITY);
	// Skip MAX_CONVOLUTION_WIDTH, MAX_CONVOLUTION_HEIGHT (only in imaging subset)
	INTEGER(MAX_ELEMENTS_INDICES);
	INTEGER(MAX_ELEMENTS_VERTICES);
	INTEGER(MAX_TEXTURE_UNITS);
#endif
	INTEGER(SAMPLE_BUFFERS);
	INTEGER(SAMPLES);
	// TODO: compressed texture formats
	INTEGER(RED_BITS);
	INTEGER(GREEN_BITS);
	INTEGER(BLUE_BITS);
	INTEGER(ALPHA_BITS);
#if !CONFIG2_GLES
	INTEGER(INDEX_BITS);
#endif
	INTEGER(DEPTH_BITS);
	INTEGER(STENCIL_BITS);
#if !CONFIG2_GLES
	INTEGER(ACCUM_RED_BITS);
	INTEGER(ACCUM_GREEN_BITS);
	INTEGER(ACCUM_BLUE_BITS);
	INTEGER(ACCUM_ALPHA_BITS);
#endif

#if !CONFIG2_GLES

	// Core OpenGL 2.0 (treated as extensions):

	if (ogl_HaveExtension("GL_EXT_texture_lod_bias"))
	{
		FLOAT(MAX_TEXTURE_LOD_BIAS_EXT);
	}

	if (ogl_HaveExtension("GL_ARB_occlusion_query"))
	{
		QUERY(SAMPLES_PASSED, QUERY_COUNTER_BITS);
	}

	if (ogl_HaveExtension("GL_ARB_shading_language_100"))
	{
		STRING(SHADING_LANGUAGE_VERSION_ARB);
	}

	if (ogl_HaveExtension("GL_ARB_vertex_shader"))
	{
		INTEGER(MAX_VERTEX_ATTRIBS_ARB);
		INTEGER(MAX_VERTEX_UNIFORM_COMPONENTS_ARB);
		INTEGER(MAX_VARYING_FLOATS_ARB);
		INTEGER(MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB);
		INTEGER(MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB);
	}

	if (ogl_HaveExtension("GL_ARB_fragment_shader"))
	{
		INTEGER(MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB);
	}

	if (ogl_HaveExtension("GL_ARB_vertex_shader") || ogl_HaveExtension("GL_ARB_fragment_shader") ||
		ogl_HaveExtension("GL_ARB_vertex_program") || ogl_HaveExtension("GL_ARB_fragment_program"))
	{
		INTEGER(MAX_TEXTURE_IMAGE_UNITS_ARB);
		INTEGER(MAX_TEXTURE_COORDS_ARB);
	}

	if (ogl_HaveExtension("GL_ARB_draw_buffers"))
	{
		INTEGER(MAX_DRAW_BUFFERS_ARB);
	}

	// Core OpenGL 3.0:

	if (ogl_HaveExtension("GL_EXT_gpu_shader4"))
	{
		INTEGER(MIN_PROGRAM_TEXEL_OFFSET); // no _EXT version of these in glext.h
		INTEGER(MAX_PROGRAM_TEXEL_OFFSET);
	}

	if (ogl_HaveExtension("GL_EXT_framebuffer_object"))
	{
		INTEGER(MAX_COLOR_ATTACHMENTS_EXT);
		INTEGER(MAX_RENDERBUFFER_SIZE_EXT);
	}

	if (ogl_HaveExtension("GL_EXT_framebuffer_multisample"))
	{
		INTEGER(MAX_SAMPLES_EXT);
	}

	if (ogl_HaveExtension("GL_EXT_texture_array"))
	{
		INTEGER(MAX_ARRAY_TEXTURE_LAYERS_EXT);
	}

	if (ogl_HaveExtension("GL_EXT_transform_feedback"))
	{
		INTEGER(MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT);
		INTEGER(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT);
		INTEGER(MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT);
	}


	// Other interesting extensions:

	if (ogl_HaveExtension("GL_EXT_timer_query") || ogl_HaveExtension("GL_ARB_timer_query"))
	{
		QUERY(TIME_ELAPSED, QUERY_COUNTER_BITS);
	}

	if (ogl_HaveExtension("GL_ARB_timer_query"))
	{
		QUERY(TIMESTAMP, QUERY_COUNTER_BITS);
	}

	if (ogl_HaveExtension("GL_EXT_texture_filter_anisotropic"))
	{
		FLOAT(MAX_TEXTURE_MAX_ANISOTROPY_EXT);
	}

	if (ogl_HaveExtension("GL_ARB_texture_rectangle"))
	{
		INTEGER(MAX_RECTANGLE_TEXTURE_SIZE_ARB);
	}

	if (ogl_HaveExtension("GL_ARB_vertex_program") || ogl_HaveExtension("GL_ARB_fragment_program"))
	{
		INTEGER(MAX_PROGRAM_MATRICES_ARB);
		INTEGER(MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB);
	}

	if (ogl_HaveExtension("GL_ARB_vertex_program"))
	{
		VERTEXPROGRAM(MAX_PROGRAM_ENV_PARAMETERS_ARB);
		VERTEXPROGRAM(MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
		VERTEXPROGRAM(MAX_PROGRAM_INSTRUCTIONS_ARB);
		VERTEXPROGRAM(MAX_PROGRAM_TEMPORARIES_ARB);
		VERTEXPROGRAM(MAX_PROGRAM_PARAMETERS_ARB);
		VERTEXPROGRAM(MAX_PROGRAM_ATTRIBS_ARB);
		VERTEXPROGRAM(MAX_PROGRAM_ADDRESS_REGISTERS_ARB);
		VERTEXPROGRAM(MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB);
		VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEMPORARIES_ARB);
		VERTEXPROGRAM(MAX_PROGRAM_NATIVE_PARAMETERS_ARB);
		VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ATTRIBS_ARB);
		VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB);

		if (ogl_HaveExtension("GL_ARB_fragment_program"))
		{
			// The spec seems to say these should be supported, but
			// Mesa complains about them so let's not bother
			/*
			VERTEXPROGRAM(MAX_PROGRAM_ALU_INSTRUCTIONS_ARB);
			VERTEXPROGRAM(MAX_PROGRAM_TEX_INSTRUCTIONS_ARB);
			VERTEXPROGRAM(MAX_PROGRAM_TEX_INDIRECTIONS_ARB);
			VERTEXPROGRAM(MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB);
			VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB);
			VERTEXPROGRAM(MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB);
			*/
		}
	}

	if (ogl_HaveExtension("GL_ARB_fragment_program"))
	{
		FRAGMENTPROGRAM(MAX_PROGRAM_ENV_PARAMETERS_ARB);
		FRAGMENTPROGRAM(MAX_PROGRAM_LOCAL_PARAMETERS_ARB);
		FRAGMENTPROGRAM(MAX_PROGRAM_INSTRUCTIONS_ARB);
		FRAGMENTPROGRAM(MAX_PROGRAM_ALU_INSTRUCTIONS_ARB);
		FRAGMENTPROGRAM(MAX_PROGRAM_TEX_INSTRUCTIONS_ARB);
		FRAGMENTPROGRAM(MAX_PROGRAM_TEX_INDIRECTIONS_ARB);
		FRAGMENTPROGRAM(MAX_PROGRAM_TEMPORARIES_ARB);
		FRAGMENTPROGRAM(MAX_PROGRAM_PARAMETERS_ARB);
		FRAGMENTPROGRAM(MAX_PROGRAM_ATTRIBS_ARB);
		FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB);
		FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB);
		FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB);
		FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB);
		FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_TEMPORARIES_ARB);
		FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_PARAMETERS_ARB);
		FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ATTRIBS_ARB);

		if (ogl_HaveExtension("GL_ARB_vertex_program"))
		{
			// The spec seems to say these should be supported, but
			// Intel drivers on Windows complain about them so let's not bother
			/*
			FRAGMENTPROGRAM(MAX_PROGRAM_ADDRESS_REGISTERS_ARB);
			FRAGMENTPROGRAM(MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB);
			*/
		}
	}

	if (ogl_HaveExtension("GL_ARB_geometry_shader4"))
	{
		INTEGER(MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB);
		INTEGER(MAX_GEOMETRY_OUTPUT_VERTICES_ARB);
		INTEGER(MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB);
		INTEGER(MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB);
		INTEGER(MAX_GEOMETRY_VARYING_COMPONENTS_ARB);
		INTEGER(MAX_VERTEX_VARYING_COMPONENTS_ARB);
	}

#else // CONFIG2_GLES

	// Core OpenGL ES 2.0:

	STRING(SHADING_LANGUAGE_VERSION);
	INTEGER(MAX_VERTEX_ATTRIBS);
	INTEGER(MAX_VERTEX_UNIFORM_VECTORS);
	INTEGER(MAX_VARYING_VECTORS);
	INTEGER(MAX_COMBINED_TEXTURE_IMAGE_UNITS);
	INTEGER(MAX_VERTEX_TEXTURE_IMAGE_UNITS);
	INTEGER(MAX_FRAGMENT_UNIFORM_VECTORS);
	INTEGER(MAX_TEXTURE_IMAGE_UNITS);
	INTEGER(MAX_RENDERBUFFER_SIZE);

#endif // CONFIG2_GLES
}
Beispiel #5
0
	static bool IsSupported()
	{
		return ogl_HaveExtension("GL_INTEL_performance_queries");
	}
Beispiel #6
0
	static bool IsSupported()
	{
		return ogl_HaveExtension("GL_EXT_timer_query");
	}