📄 directx.c
字号:
/*
* 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 + -