⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 directx.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * IWineD3D implementation
 *
 * Copyright 2002-2004 Jason Edmeades
 * Copyright 2003-2004 Raphael Junqueira
 * Copyright 2004 Christian Costa
 * Copyright 2005 Oliver Stieber
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

/* Compile time diagnostics: */

#ifndef DEBUG_SINGLE_MODE
/* Set to 1 to force only a single display mode to be exposed: */
#define DEBUG_SINGLE_MODE 0
#endif


#include "config.h"
#include <assert.h>
#include "wined3d_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(d3d_caps);

/* Extension detection */
static const struct {
    const char *extension_string;
    GL_SupportedExt extension;
} EXTENSION_MAP[] = {
    /* APPLE */
    {"GL_APPLE_client_storage",             APPLE_CLIENT_STORAGE},
    {"GL_APPLE_fence",                      APPLE_FENCE},

    /* ATI */
    {"GL_ATI_separate_stencil",             ATI_SEPARATE_STENCIL},
    {"GL_ATI_texture_env_combine3",         ATI_TEXTURE_ENV_COMBINE3},
    {"GL_ATI_texture_mirror_once",          ATI_TEXTURE_MIRROR_ONCE},
    {"GL_ATI_envmap_bumpmap",               ATI_ENVMAP_BUMPMAP},

    /* ARB */
    {"GL_ARB_draw_buffers",                 ARB_DRAW_BUFFERS},
    {"GL_ARB_fragment_program",             ARB_FRAGMENT_PROGRAM},
    {"GL_ARB_fragment_shader",              ARB_FRAGMENT_SHADER},
    {"GL_ARB_half_float_pixel",             ARB_HALF_FLOAT_PIXEL},
    {"GL_ARB_imaging",                      ARB_IMAGING},
    {"GL_ARB_multisample",                  ARB_MULTISAMPLE}, /* needs GLX_ARB_MULTISAMPLE as well */
    {"GL_ARB_multitexture",                 ARB_MULTITEXTURE},
    {"GL_ARB_occlusion_query",              ARB_OCCLUSION_QUERY},
    {"GL_ARB_pixel_buffer_object",          ARB_PIXEL_BUFFER_OBJECT},
    {"GL_ARB_point_parameters",             ARB_POINT_PARAMETERS},
    {"GL_ARB_point_sprite",                 ARB_POINT_SPRITE},
    {"GL_ARB_texture_border_clamp",         ARB_TEXTURE_BORDER_CLAMP},
    {"GL_ARB_texture_compression",          ARB_TEXTURE_COMPRESSION},
    {"GL_ARB_texture_cube_map",             ARB_TEXTURE_CUBE_MAP},
    {"GL_ARB_texture_env_add",              ARB_TEXTURE_ENV_ADD},
    {"GL_ARB_texture_env_combine",          ARB_TEXTURE_ENV_COMBINE},
    {"GL_ARB_texture_env_dot3",             ARB_TEXTURE_ENV_DOT3},
    {"GL_ARB_texture_float",                ARB_TEXTURE_FLOAT},
    {"GL_ARB_texture_mirrored_repeat",      ARB_TEXTURE_MIRRORED_REPEAT},
    {"GL_ARB_texture_non_power_of_two",     ARB_TEXTURE_NON_POWER_OF_TWO},
    {"GL_ARB_vertex_blend",                 ARB_VERTEX_BLEND},
    {"GL_ARB_vertex_buffer_object",         ARB_VERTEX_BUFFER_OBJECT},
    {"GL_ARB_vertex_program",               ARB_VERTEX_PROGRAM},
    {"GL_ARB_vertex_shader",                ARB_VERTEX_SHADER},

    /* EXT */
    {"GL_EXT_blend_minmax",                 EXT_BLEND_MINMAX},
    {"GL_EXT_fog_coord",                    EXT_FOG_COORD},
    {"GL_EXT_framebuffer_blit",             EXT_FRAMEBUFFER_BLIT},
    {"GL_EXT_framebuffer_object",           EXT_FRAMEBUFFER_OBJECT},
    {"GL_EXT_paletted_texture",             EXT_PALETTED_TEXTURE},
    {"GL_EXT_point_parameters",             EXT_POINT_PARAMETERS},
    {"GL_EXT_secondary_color",              EXT_SECONDARY_COLOR},
    {"GL_EXT_stencil_two_side",             EXT_STENCIL_TWO_SIDE},
    {"GL_EXT_stencil_wrap",                 EXT_STENCIL_WRAP},
    {"GL_EXT_texture3D",                    EXT_TEXTURE3D},
    {"GL_EXT_texture_compression_s3tc",     EXT_TEXTURE_COMPRESSION_S3TC},
    {"GL_EXT_texture_env_add",              EXT_TEXTURE_ENV_ADD},
    {"GL_EXT_texture_env_combine",          EXT_TEXTURE_ENV_COMBINE},
    {"GL_EXT_texture_env_dot3",             EXT_TEXTURE_ENV_DOT3},
    {"GL_EXT_texture_sRGB",                 EXT_TEXTURE_SRGB},
    {"GL_EXT_texture_filter_anisotropic",   EXT_TEXTURE_FILTER_ANISOTROPIC},
    {"GL_EXT_texture_lod",                  EXT_TEXTURE_LOD},
    {"GL_EXT_texture_lod_bias",             EXT_TEXTURE_LOD_BIAS},
    {"GL_EXT_vertex_shader",                EXT_VERTEX_SHADER},
    {"GL_EXT_vertex_weighting",             EXT_VERTEX_WEIGHTING},

    /* NV */
    {"GL_NV_half_float",                    NV_HALF_FLOAT},
    {"GL_NV_fence",                         NV_FENCE},
    {"GL_NV_fog_distance",                  NV_FOG_DISTANCE},
    {"GL_NV_fragment_program",              NV_FRAGMENT_PROGRAM},
    {"GL_NV_fragment_program2",             NV_FRAGMENT_PROGRAM2},
    {"GL_NV_register_combiners",            NV_REGISTER_COMBINERS},
    {"GL_NV_register_combiners2",           NV_REGISTER_COMBINERS2},
    {"GL_NV_texgen_reflection",             NV_TEXGEN_REFLECTION},
    {"GL_NV_texture_env_combine4",          NV_TEXTURE_ENV_COMBINE4},
    {"GL_NV_texture_shader",                NV_TEXTURE_SHADER},
    {"GL_NV_texture_shader2",               NV_TEXTURE_SHADER2},
    {"GL_NV_texture_shader3",               NV_TEXTURE_SHADER3},
    {"GL_NV_occlusion_query",               NV_OCCLUSION_QUERY},
    {"GL_NV_vertex_program",                NV_VERTEX_PROGRAM},
    {"GL_NV_vertex_program1_1",             NV_VERTEX_PROGRAM1_1},
    {"GL_NV_vertex_program2",               NV_VERTEX_PROGRAM2},
    {"GL_NV_vertex_program3",               NV_VERTEX_PROGRAM3},
};

/**********************************************************
 * Utility functions follow
 **********************************************************/

/* Adapters */
static int numAdapters = 0;
static struct WineD3DAdapter Adapters[1];

/* lookup tables */
int minLookup[MAX_LOOKUPS];
int maxLookup[MAX_LOOKUPS];
DWORD *stateLookup[MAX_LOOKUPS];

DWORD minMipLookup[WINED3DTEXF_ANISOTROPIC + 1][WINED3DTEXF_LINEAR + 1];


/**
 * Note: GL seems to trap if GetDeviceCaps is called before any HWND's created
 * ie there is no GL Context - Get a default rendering context to enable the
 * function query some info from GL
 */

static int             wined3d_fake_gl_context_ref = 0;
static BOOL            wined3d_fake_gl_context_foreign;
static BOOL            wined3d_fake_gl_context_available = FALSE;
static HDC             wined3d_fake_gl_context_hdc = NULL;
static HWND            wined3d_fake_gl_context_hwnd = NULL;

static CRITICAL_SECTION wined3d_fake_gl_context_cs;
static CRITICAL_SECTION_DEBUG wined3d_fake_gl_context_cs_debug =
{
    0, 0, &wined3d_fake_gl_context_cs,
    { &wined3d_fake_gl_context_cs_debug.ProcessLocksList,
      &wined3d_fake_gl_context_cs_debug.ProcessLocksList },
    0, 0, { (DWORD_PTR)(__FILE__ ": wined3d_fake_gl_context_cs") }
};
static CRITICAL_SECTION wined3d_fake_gl_context_cs = { &wined3d_fake_gl_context_cs_debug, -1, 0, 0, 0, 0 };

static void WineD3D_ReleaseFakeGLContext(void) {
    HGLRC glCtx;

    EnterCriticalSection(&wined3d_fake_gl_context_cs);

    if(!wined3d_fake_gl_context_available) {
        TRACE_(d3d_caps)("context not available\n");
        LeaveCriticalSection(&wined3d_fake_gl_context_cs);
        return;
    }

    glCtx = pwglGetCurrentContext();

    TRACE_(d3d_caps)("decrementing ref from %i\n", wined3d_fake_gl_context_ref);
    if (0 == (--wined3d_fake_gl_context_ref) ) {
        if(!wined3d_fake_gl_context_foreign && glCtx) {
            TRACE_(d3d_caps)("destroying fake GL context\n");
            pwglMakeCurrent(NULL, NULL);
            pwglDeleteContext(glCtx);
        }
        if(wined3d_fake_gl_context_hdc)
            ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
        wined3d_fake_gl_context_hdc = NULL; /* Make sure we don't think that it is still around */
        if(wined3d_fake_gl_context_hwnd)
            DestroyWindow(wined3d_fake_gl_context_hwnd);
        wined3d_fake_gl_context_hwnd = NULL;
        wined3d_fake_gl_context_available = FALSE;
    }
    assert(wined3d_fake_gl_context_ref >= 0);

    LeaveCriticalSection(&wined3d_fake_gl_context_cs);
    LEAVE_GL();
}

static BOOL WineD3D_CreateFakeGLContext(void) {
    HGLRC glCtx = NULL;

    ENTER_GL();
    EnterCriticalSection(&wined3d_fake_gl_context_cs);

    TRACE("getting context...\n");
    if(wined3d_fake_gl_context_ref > 0) goto ret;
    assert(0 == wined3d_fake_gl_context_ref);

    wined3d_fake_gl_context_foreign = TRUE;

    glCtx = pwglGetCurrentContext();
    if (!glCtx) {
        PIXELFORMATDESCRIPTOR pfd;
        int iPixelFormat;

        wined3d_fake_gl_context_foreign = FALSE;

        /* We need a fake window as a hdc retrieved using GetDC(0) can't be used for much GL purposes */
        wined3d_fake_gl_context_hwnd = CreateWindowA("WineD3D_OpenGL", "WineD3D fake window", WS_OVERLAPPEDWINDOW,        10, 10, 10, 10, NULL, NULL, NULL, NULL);
        if(!wined3d_fake_gl_context_hwnd) {
            ERR("HWND creation failed!\n");
            goto fail;
        }
        wined3d_fake_gl_context_hdc = GetDC(wined3d_fake_gl_context_hwnd);
        if(!wined3d_fake_gl_context_hdc) {
            ERR("GetDC failed!\n");
            goto fail;
        }

        /* PixelFormat selection */
        ZeroMemory(&pfd, sizeof(pfd));
        pfd.nSize      = sizeof(pfd);
        pfd.nVersion   = 1;
        pfd.dwFlags    = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;/*PFD_GENERIC_ACCELERATED*/
        pfd.iPixelType = PFD_TYPE_RGBA;
        pfd.cColorBits = 32;
        pfd.iLayerType = PFD_MAIN_PLANE;

        iPixelFormat = ChoosePixelFormat(wined3d_fake_gl_context_hdc, &pfd);
        if(!iPixelFormat) {
            /* If this happens something is very wrong as ChoosePixelFormat barely fails */
            ERR("Can't find a suitable iPixelFormat\n");
            goto fail;
        }
        DescribePixelFormat(wined3d_fake_gl_context_hdc, iPixelFormat, sizeof(pfd), &pfd);
        SetPixelFormat(wined3d_fake_gl_context_hdc, iPixelFormat, &pfd);

        /* Create a GL context */
        glCtx = pwglCreateContext(wined3d_fake_gl_context_hdc);
        if (!glCtx) {
            WARN_(d3d_caps)("Error creating default context for capabilities initialization\n");
            goto fail;
        }

        /* Make it the current GL context */
        if (!pwglMakeCurrent(wined3d_fake_gl_context_hdc, glCtx)) {
            WARN_(d3d_caps)("Error setting default context as current for capabilities initialization\n");
            goto fail;
        }
    }

  ret:
    TRACE("incrementing ref from %i\n", wined3d_fake_gl_context_ref);
    wined3d_fake_gl_context_ref++;
    wined3d_fake_gl_context_available = TRUE;
    LeaveCriticalSection(&wined3d_fake_gl_context_cs);
    return TRUE;
  fail:
    if(wined3d_fake_gl_context_hdc)
        ReleaseDC(wined3d_fake_gl_context_hwnd, wined3d_fake_gl_context_hdc);
    wined3d_fake_gl_context_hdc = NULL;
    if(wined3d_fake_gl_context_hwnd)
        DestroyWindow(wined3d_fake_gl_context_hwnd);
    wined3d_fake_gl_context_hwnd = NULL;
    if(glCtx) pwglDeleteContext(glCtx);
    LeaveCriticalSection(&wined3d_fake_gl_context_cs);
    LEAVE_GL();
    return FALSE;
}


/**********************************************************
 * IUnknown parts follows
 **********************************************************/

static HRESULT WINAPI IWineD3DImpl_QueryInterface(IWineD3D *iface,REFIID riid,LPVOID *ppobj)
{
    IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;

    TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppobj);
    if (IsEqualGUID(riid, &IID_IUnknown)
        || IsEqualGUID(riid, &IID_IWineD3DBase)
        || IsEqualGUID(riid, &IID_IWineD3DDevice)) {
        IUnknown_AddRef(iface);
        *ppobj = This;
        return S_OK;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -