mesa.c
来自「Wine-20031016」· C语言 代码 · 共 1,666 行 · 第 1/5 页
C
1,666 行
/* Direct3D Device * Copyright (c) 1998 Lionel ULMER * * This file contains the MESA implementation of all the D3D devices that * Wine supports. * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include "config.h"#include "wine/port.h"#include <stdarg.h>#include <string.h>#include <math.h>#define NONAMELESSUNION#define NONAMELESSSTRUCT#include "windef.h"#include "winbase.h"#include "winerror.h"#include "objbase.h"#include "wingdi.h"#include "ddraw.h"#include "d3d.h"#include "wine/debug.h"#include "wine/library.h"#include "mesa_private.h"#include "main.h"WINE_DEFAULT_DEBUG_CHANNEL(ddraw);WINE_DECLARE_DEBUG_CHANNEL(ddraw_geom);WINE_DECLARE_DEBUG_CHANNEL(ddraw_fps);/* x11drv GDI escapes */#define X11DRV_ESCAPE 6789enum x11drv_escape_codes{ X11DRV_GET_DISPLAY, /* get X11 display for a DC */ X11DRV_GET_DRAWABLE, /* get current drawable for a DC */ X11DRV_GET_FONT, /* get current X font for a DC */};/* They are non-static as they are used by Direct3D in the creation function */const GUID IID_D3DDEVICE_OpenGL = { 0x31416d44, 0x86ae, 0x11d2, { 0x82,0x2d,0xa8,0xd5,0x31,0x87,0xca,0xfa }};const float id_mat[16] = { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0};/* This is filled at DLL loading time */static D3DDEVICEDESC7 opengl_device_caps;GL_EXTENSIONS_LIST GL_extensions;static void draw_primitive_strided(IDirect3DDeviceImpl *This, D3DPRIMITIVETYPE d3dptPrimitiveType, DWORD d3dvtVertexType, LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, DWORD dwVertexCount, LPWORD dwIndices, DWORD dwIndexCount, DWORD dwFlags) ;static DWORD draw_primitive_handle_textures(IDirect3DDeviceImpl *This);/* retrieve the X display to use on a given DC */inline static Display *get_display( HDC hdc ){ Display *display; enum x11drv_escape_codes escape = X11DRV_GET_DISPLAY; if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape, sizeof(display), (LPSTR)&display )) display = NULL; return display;}#define UNLOCK_TEX_SIZE 256#define DEPTH_RANGE_BIT (0x00000001 << 0)#define VIEWPORT_BIT (0x00000001 << 1)static DWORD d3ddevice_set_state_for_flush(IDirect3DDeviceImpl *d3d_dev, LPCRECT pRect, BOOLEAN use_alpha, BOOLEAN *initial) { IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev; DWORD opt_bitmap = 0x00000000; if (gl_d3d_dev->current_active_tex_unit != GL_TEXTURE0_WINE) { GL_extensions.glActiveTexture(GL_TEXTURE0_WINE); gl_d3d_dev->current_active_tex_unit = GL_TEXTURE0_WINE; } if (gl_d3d_dev->unlock_tex == 0) { glGenTextures(1, &gl_d3d_dev->unlock_tex); glBindTexture(GL_TEXTURE_2D, gl_d3d_dev->unlock_tex); *initial = TRUE; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); } else { glBindTexture(GL_TEXTURE_2D, gl_d3d_dev->unlock_tex); *initial = FALSE; } if (d3d_dev->tex_mat_is_identity[0] == FALSE) { glMatrixMode(GL_TEXTURE); glLoadIdentity(); } if (gl_d3d_dev->transform_state != GL_TRANSFORM_ORTHO) { gl_d3d_dev->transform_state = GL_TRANSFORM_ORTHO; d3ddevice_set_ortho(d3d_dev); } if (gl_d3d_dev->depth_test != FALSE) glDisable(GL_DEPTH_TEST); if ((gl_d3d_dev->current_bound_texture[0] == NULL) || (d3d_dev->state_block.texture_stage_state[0][D3DTSS_COLOROP - 1] == D3DTOP_DISABLE)) glEnable(GL_TEXTURE_2D); if (gl_d3d_dev->current_bound_texture[1] != NULL) { if (gl_d3d_dev->current_active_tex_unit != GL_TEXTURE1_WINE) { GL_extensions.glActiveTexture(GL_TEXTURE1_WINE); gl_d3d_dev->current_active_tex_unit = GL_TEXTURE1_WINE; } /* 'unbound' texture level 1 in that case to disable multi-texturing */ glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); } glEnable(GL_SCISSOR_TEST); if ((d3d_dev->active_viewport.dvMinZ != 0.0) || (d3d_dev->active_viewport.dvMaxZ != 1.0)) { glDepthRange(0.0, 1.0); opt_bitmap |= DEPTH_RANGE_BIT; } if ((d3d_dev->active_viewport.dwX != 0) || (d3d_dev->active_viewport.dwY != 0) || (d3d_dev->active_viewport.dwWidth != d3d_dev->surface->surface_desc.dwWidth) || (d3d_dev->active_viewport.dwHeight != d3d_dev->surface->surface_desc.dwHeight)) { glViewport(0, 0, d3d_dev->surface->surface_desc.dwWidth, d3d_dev->surface->surface_desc.dwHeight); opt_bitmap |= VIEWPORT_BIT; } glScissor(pRect->left, d3d_dev->surface->surface_desc.dwHeight - pRect->bottom, pRect->right - pRect->left, pRect->bottom - pRect->top); if (gl_d3d_dev->lighting != FALSE) glDisable(GL_LIGHTING); if (gl_d3d_dev->cull_face != FALSE) glDisable(GL_CULL_FACE); if (use_alpha) { if (gl_d3d_dev->alpha_test == FALSE) glEnable(GL_ALPHA_TEST); if (((d3d_dev->state_block.render_state[D3DRENDERSTATE_ALPHAREF - 1] & 0x000000FF) != 0x00) || ((d3d_dev->state_block.render_state[D3DRENDERSTATE_ALPHAFUNC - 1]) != D3DCMP_GREATER)) { glAlphaFunc(GL_GREATER, 0.0); } } else { if (gl_d3d_dev->alpha_test != FALSE) glDisable(GL_ALPHA_TEST); } if (gl_d3d_dev->stencil_test != FALSE) glDisable(GL_STENCIL_TEST); if (gl_d3d_dev->blending != FALSE) glDisable(GL_BLEND); if (gl_d3d_dev->fogging != FALSE) glDisable(GL_FOG); if (gl_d3d_dev->current_tex_env != GL_REPLACE) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); return opt_bitmap;}static void d3ddevice_restore_state_after_flush(IDirect3DDeviceImpl *d3d_dev, DWORD opt_bitmap, BOOLEAN use_alpha) { IDirect3DDeviceGLImpl* gl_d3d_dev = (IDirect3DDeviceGLImpl*) d3d_dev; /* And restore all the various states modified by this code */ if (gl_d3d_dev->depth_test != 0) glEnable(GL_DEPTH_TEST); if (gl_d3d_dev->lighting != 0) glEnable(GL_LIGHTING); if ((gl_d3d_dev->alpha_test != 0) && (use_alpha == 0)) glEnable(GL_ALPHA_TEST); else if ((gl_d3d_dev->alpha_test == 0) && (use_alpha != 0)) glDisable(GL_ALPHA_TEST); if (use_alpha) { if (((d3d_dev->state_block.render_state[D3DRENDERSTATE_ALPHAREF - 1] & 0x000000FF) != 0x00) || ((d3d_dev->state_block.render_state[D3DRENDERSTATE_ALPHAFUNC - 1]) != D3DCMP_GREATER)) { glAlphaFunc(convert_D3D_compare_to_GL(d3d_dev->state_block.render_state[D3DRENDERSTATE_ALPHAFUNC - 1]), (d3d_dev->state_block.render_state[D3DRENDERSTATE_ALPHAREF - 1] & 0x000000FF) / 255.0); } } if (gl_d3d_dev->stencil_test != 0) glEnable(GL_STENCIL_TEST); if (gl_d3d_dev->cull_face != 0) glEnable(GL_CULL_FACE); if (gl_d3d_dev->blending != 0) glEnable(GL_BLEND); if (gl_d3d_dev->fogging != 0) glEnable(GL_FOG); glDisable(GL_SCISSOR_TEST); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, gl_d3d_dev->current_tex_env); if (opt_bitmap & DEPTH_RANGE_BIT) { glDepthRange(d3d_dev->active_viewport.dvMinZ, d3d_dev->active_viewport.dvMaxZ); } if (opt_bitmap & VIEWPORT_BIT) { glViewport(d3d_dev->active_viewport.dwX, d3d_dev->surface->surface_desc.dwHeight - (d3d_dev->active_viewport.dwHeight + d3d_dev->active_viewport.dwY), d3d_dev->active_viewport.dwWidth, d3d_dev->active_viewport.dwHeight); } if (d3d_dev->tex_mat_is_identity[0] == FALSE) { d3d_dev->matrices_updated(d3d_dev, TEXMAT0_CHANGED); } /* This is a hack to prevent querying the current texture from GL. Basically, at the next DrawPrimitive call, this will bind the correct texture to this stage. */ gl_d3d_dev->current_bound_texture[0] = (IDirectDrawSurfaceImpl *) 0x00000001; gl_d3d_dev->current_bound_texture[1] = (IDirectDrawSurfaceImpl *) 0x00000000; if (d3d_dev->state_block.texture_stage_state[0][D3DTSS_COLOROP - 1] == D3DTOP_DISABLE) glDisable(GL_TEXTURE_2D);}/* retrieve the X drawable to use on a given DC */inline static Drawable get_drawable( HDC hdc ){ Drawable drawable; enum x11drv_escape_codes escape = X11DRV_GET_DRAWABLE; if (!ExtEscape( hdc, X11DRV_ESCAPE, sizeof(escape), (LPCSTR)&escape, sizeof(drawable), (LPSTR)&drawable )) drawable = 0; return drawable;}/* This is unnecessarely complicated :-) */#define MEASUREMENT_WINDOW 5#define NUMBER_OF_WINDOWS 10static LONGLONG perf_freq;static LONGLONG perf_storage[NUMBER_OF_WINDOWS];static LONGLONG prev_time = 0;static unsigned int current_window;static unsigned int measurements_in_window;static unsigned int valid_windows;static BOOL opengl_flip( LPVOID dev, LPVOID drawable){ IDirect3DDeviceImpl *d3d_dev = (IDirect3DDeviceImpl *) dev; IDirect3DDeviceGLImpl *gl_d3d_dev = (IDirect3DDeviceGLImpl *) dev; TRACE("(%p, %ld)\n", gl_d3d_dev->display,(Drawable)drawable); ENTER_GL(); if (gl_d3d_dev->state[WINE_GL_BUFFER_BACK] == SURFACE_MEMORY_DIRTY) { d3d_dev->flush_to_framebuffer(d3d_dev, &(gl_d3d_dev->lock_rect[WINE_GL_BUFFER_BACK]), gl_d3d_dev->lock_surf[WINE_GL_BUFFER_BACK]); } gl_d3d_dev->state[WINE_GL_BUFFER_BACK] = SURFACE_GL; gl_d3d_dev->state[WINE_GL_BUFFER_FRONT] = SURFACE_GL; glXSwapBuffers(gl_d3d_dev->display, (Drawable)drawable); LEAVE_GL(); if (TRACE_ON(ddraw_fps)) { LONGLONG current_time; LONGLONG frame_duration; QueryPerformanceCounter((LARGE_INTEGER *) ¤t_time); if (prev_time != 0) { LONGLONG total_time = 0; int tot_meas; frame_duration = current_time - prev_time; prev_time = current_time; perf_storage[current_window] += frame_duration; measurements_in_window++; if (measurements_in_window >= MEASUREMENT_WINDOW) { current_window++; valid_windows++; if (valid_windows < NUMBER_OF_WINDOWS) { int i; tot_meas = valid_windows * MEASUREMENT_WINDOW; for (i = 0; i < valid_windows; i++) { total_time += perf_storage[i]; } } else { int i; tot_meas = NUMBER_OF_WINDOWS * MEASUREMENT_WINDOW; for (i = 0; i < NUMBER_OF_WINDOWS; i++) { total_time += perf_storage[i]; } } TRACE_(ddraw_fps)(" %9.5f\n", (double) (perf_freq * tot_meas) / (double) total_time); if (current_window >= NUMBER_OF_WINDOWS) { current_window = 0; } perf_storage[current_window] = 0; measurements_in_window = 0; } } else { prev_time = current_time; memset(perf_storage, 0, sizeof(perf_storage)); current_window = 0; valid_windows = 0; measurements_in_window = 0; QueryPerformanceFrequency((LARGE_INTEGER *) &perf_freq); } } return TRUE;}/******************************************************************************* * OpenGL static functions */static void set_context(IDirect3DDeviceImpl* This){ IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This; TRACE("glxMakeCurrent %p, %ld, %p\n",glThis->display,glThis->drawable, glThis->gl_context); ENTER_GL(); if (glXMakeCurrent(glThis->display, glThis->drawable, glThis->gl_context) == False) { ERR("Error in setting current context (context %p drawable %ld)!\n", glThis->gl_context, glThis->drawable); } LEAVE_GL();}static void fill_opengl_caps(D3DDEVICEDESC *d1){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?