mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-10 12:41:35 -10:00
- updated OpenGL code (basic shader support, etc.) - new ships lab code - scripting RTT fixes - don't let FRED hog CPU time
1631 lines
47 KiB
C++
1631 lines
47 KiB
C++
/*
|
|
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
|
*
|
|
* All source code herein is the property of Volition, Inc. You may not sell
|
|
* or otherwise commercially exploit the source or things you created based on the
|
|
* source.
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* $Log: not supported by cvs2svn $
|
|
* Revision 2.59.2.2 2006/11/15 00:47:57 taylor
|
|
* properly support the updated window create code (all told: should take of of Mantis bugs #542, #624, #1140, and possibly #962 and #1124)
|
|
*
|
|
* Revision 2.59.2.1 2006/08/22 05:41:35 taylor
|
|
* clean up the grstub mess (for work on standalone server, and just for sanity sake)
|
|
* move color and shader functions to 2d.cpp since they are exactly the same everywhere
|
|
* don't bother with the function pointer for gr_set_font(), it's the same everywhere anyway
|
|
*
|
|
* Revision 2.59 2006/06/01 04:44:19 taylor
|
|
* fix the scope issues that someone complained about in the forums
|
|
*
|
|
* Revision 2.58 2006/05/27 17:07:48 taylor
|
|
* remove grd3dparticle.* and grd3dbatch.*, they are obsolete
|
|
* allow us to build without D3D support under Windows (just define NO_DIRECT3D)
|
|
* clean up TMAP flags
|
|
* fix a couple of minor OpenGL state change issues with spec and env map rendering
|
|
* make sure we build again for OS X (OGL extension functions work a little different there)
|
|
* render targets always need to be power-of-2 to avoid incomplete buffer issues in the code
|
|
* when we disable culling in opengl_3dunlit be sure that we re-enable it on exit of function
|
|
* re-fix screenshots
|
|
* add true alpha blending support (with cmdline for now since the artwork has the catch up)
|
|
* draw lines with float positioning, to be more accurate with resizing on non-standard resolutions
|
|
* don't load cubemaps from file for D3D, not sure how to do it anyway
|
|
* update geometry batcher code, memory fixes, dynamic stuff, basic fixage, etc.
|
|
*
|
|
* Revision 2.57 2006/04/20 06:32:01 Goober5000
|
|
* proper capitalization according to Volition
|
|
*
|
|
* Revision 2.56 2006/04/15 00:13:22 phreak
|
|
* gr_flash_alpha(), much like gr_flash(), but allows an alpha value to be passed
|
|
*
|
|
* Revision 2.55 2006/02/25 21:47:00 Goober5000
|
|
* spelling
|
|
*
|
|
* Revision 2.54 2006/01/20 17:15:16 taylor
|
|
* gr_*_bitmap_ex() stuff, D3D side is 100% untested to even compile
|
|
* several other very minor changes as well
|
|
*
|
|
* Revision 2.53 2005/12/06 02:53:02 taylor
|
|
* clean up some D3D debug messages to better match new OGL messages (for easier debugging)
|
|
* remove D3D_32bit variable since it's basically useless and the same thing can be done another way
|
|
*
|
|
* Revision 2.52 2005/11/13 06:44:18 taylor
|
|
* small bit of EFF cleanup
|
|
* add -img2dds support
|
|
* cleanup some D3D stuff (missing a lot since the old code is so unstable I couldn't get it working like I wanted)
|
|
* some minor OGL cleanup and small performance changes
|
|
* converge the various pcx_read_bitmap* functions into one
|
|
* cleanup/rename/remove some cmdline options
|
|
*
|
|
* Revision 2.51 2005/08/20 20:34:51 taylor
|
|
* some bmpman and render_target function name changes so that they make sense
|
|
* always use bm_set_render_target() rather than the gr_ version so that the graphics state is set properly
|
|
* save the original gamma ramp on OGL init so that it can be restored on exit
|
|
*
|
|
* Revision 2.50 2005/05/01 23:23:18 phreak
|
|
* added CVS info to top of file.
|
|
*
|
|
*
|
|
*/
|
|
|
|
#ifndef NO_DIRECT3D
|
|
|
|
#include "grd3dsetup.h"
|
|
#include <d3d8.h>
|
|
|
|
#include "osapi/osapi.h"
|
|
#include "io/mouse.h"
|
|
#include "globalincs/systemvars.h"
|
|
|
|
#include "graphics/2d.h"
|
|
#include "graphics/grinternal.h"
|
|
|
|
#include "graphics/grd3d.h"
|
|
#include "graphics/grd3dinternal.h"
|
|
#include "graphics/grd3dbmpman.h"
|
|
#include "graphics/grd3dlight.h"
|
|
#include "graphics/grd3dstateblock.h"
|
|
|
|
#include "debugconsole/timerbar.h"
|
|
#include "debugconsole/dbugfile.h"
|
|
#include "cmdline/cmdline.h"
|
|
#include "ddsutils/ddsutils.h"
|
|
|
|
|
|
|
|
// Lets define our global D3D variables
|
|
IDirect3D8 *GlobalD3DVars::lpD3D = NULL;
|
|
IDirect3DDevice8 *GlobalD3DVars::lpD3DDevice = NULL;
|
|
|
|
D3DCAPS8 GlobalD3DVars::d3d_caps;
|
|
D3DPRESENT_PARAMETERS GlobalD3DVars::d3dpp;
|
|
|
|
bool GlobalD3DVars::D3D_inited = 0;
|
|
bool GlobalD3DVars::D3D_activate = 0;
|
|
bool GlobalD3DVars::D3D_Antialiasing = 0;
|
|
bool GlobalD3DVars::D3D_window = 0;
|
|
|
|
int GlobalD3DVars::D3D_rendition_uvs = 0;
|
|
int GlobalD3DVars::D3D_zbias = 1;
|
|
|
|
float GlobalD3DVars::texture_adjust_u = 0;
|
|
float GlobalD3DVars::texture_adjust_v = 0;
|
|
|
|
ID3DXMatrixStack *world_matrix_stack, *view_matrix_stack, *proj_matrix_stack;
|
|
|
|
const int MULTISAMPLE_MAX = 16;
|
|
const D3DMULTISAMPLE_TYPE multisample_types[MULTISAMPLE_MAX] =
|
|
{
|
|
D3DMULTISAMPLE_NONE,
|
|
D3DMULTISAMPLE_2_SAMPLES,
|
|
D3DMULTISAMPLE_3_SAMPLES,
|
|
D3DMULTISAMPLE_4_SAMPLES,
|
|
D3DMULTISAMPLE_5_SAMPLES,
|
|
D3DMULTISAMPLE_6_SAMPLES,
|
|
D3DMULTISAMPLE_7_SAMPLES,
|
|
D3DMULTISAMPLE_8_SAMPLES,
|
|
D3DMULTISAMPLE_9_SAMPLES,
|
|
D3DMULTISAMPLE_10_SAMPLES,
|
|
D3DMULTISAMPLE_11_SAMPLES,
|
|
D3DMULTISAMPLE_12_SAMPLES,
|
|
D3DMULTISAMPLE_13_SAMPLES,
|
|
D3DMULTISAMPLE_14_SAMPLES,
|
|
D3DMULTISAMPLE_15_SAMPLES,
|
|
D3DMULTISAMPLE_16_SAMPLES
|
|
};
|
|
|
|
char Device_init_error[512] = "No errror set";
|
|
RECT D3D_cursor_clip_rect;
|
|
|
|
D3DMATERIAL8 material;
|
|
|
|
// DirectDraw structures used without DD
|
|
// To contain shift and scale variables to convert graphics files to textures
|
|
PIXELFORMAT AlphaTextureFormat;
|
|
PIXELFORMAT NonAlphaTextureFormat;
|
|
|
|
D3DFORMAT default_non_alpha_tformat = D3DFMT_UNKNOWN;
|
|
D3DFORMAT default_alpha_tformat = D3DFMT_UNKNOWN;
|
|
D3DFORMAT default_compressed_format = D3DFMT_UNKNOWN;
|
|
|
|
void d3d_clip_cursor()
|
|
{
|
|
if (Cmdline_window) return;
|
|
|
|
GetWindowRect((HWND)os_get_window(), &D3D_cursor_clip_rect);
|
|
ClipCursor(&D3D_cursor_clip_rect);
|
|
}
|
|
|
|
// Outputs a format to debug console
|
|
void d3d_dump_format(PIXELFORMAT *pf)
|
|
{
|
|
unsigned long m;
|
|
int r, g, b, a;
|
|
for (r = 0, m = pf->dwRBitMask; !(m & 1); r++, m >>= 1);
|
|
for (r = 0; m & 1; r++, m >>= 1);
|
|
for (g = 0, m = pf->dwGBitMask; !(m & 1); g++, m >>= 1);
|
|
for (g = 0; m & 1; g++, m >>= 1);
|
|
for (b = 0, m = pf->dwBBitMask; !(m & 1); b++, m >>= 1);
|
|
for (b = 0; m & 1; b++, m >>= 1);
|
|
if ( pf->dw_is_alpha_mode == true ) {
|
|
for (a = 0, m = pf->dwRGBAlphaBitMask; !(m & 1); a++, m >>= 1);
|
|
for (a = 0; m & 1; a++, m >>= 1);
|
|
mprintf(( "ARGB, %d:%d:%d:%d\n", a, r, g, b ));
|
|
} else {
|
|
a = 0;
|
|
mprintf(( "RGB, %d:%d:%d\n", r, g, b ));
|
|
}
|
|
}
|
|
|
|
extern int Gr_inited;
|
|
|
|
void gr_d3d_activate(int active)
|
|
{
|
|
//mprintf(( "Direct3D activate: %d\n", active ));
|
|
|
|
HWND hwnd = (HWND)os_get_window();
|
|
|
|
if ( active ) {
|
|
GlobalD3DVars::D3D_activate = 1;
|
|
|
|
if ( hwnd ) {
|
|
ShowWindow(hwnd,SW_RESTORE);
|
|
UpdateWindow( hwnd );
|
|
if(!Cmdline_window){
|
|
d3d_lost_device(true);
|
|
}
|
|
GetWindowRect(hwnd, &D3D_cursor_clip_rect);
|
|
d3d_clip_cursor();
|
|
ShowCursor(FALSE);
|
|
}
|
|
|
|
} else {
|
|
|
|
GlobalD3DVars::D3D_activate = 0;
|
|
|
|
if ( hwnd ) {
|
|
// d3d_lost_device();
|
|
if(!Cmdline_window){
|
|
GlobalD3DVars::d3dpp.Windowed = true;
|
|
d3d_lost_device(true);
|
|
//you will minimize! /*twitch*/
|
|
GlobalD3DVars::d3dpp.Windowed = false;
|
|
}
|
|
ClipCursor(NULL);
|
|
ShowCursor(TRUE);
|
|
UpdateWindow( hwnd );
|
|
ShowWindow(hwnd,SW_MINIMIZE);
|
|
}
|
|
}
|
|
// ID3DXMatrixStack *world_matrix_stack, *view_matrix_stack, *proj_matrix_stack;
|
|
|
|
}
|
|
|
|
void d3d_setup_format_components(
|
|
PIXELFORMAT *surface, color_gun *r_gun, color_gun *g_gun, color_gun *b_gun, color_gun *a_gun)
|
|
{
|
|
int s;
|
|
unsigned long m;
|
|
|
|
for (s = 0, m = surface->dwRBitMask; !(m & 1); s++, m >>= 1);
|
|
r_gun->mask = surface->dwRBitMask;
|
|
r_gun->shift = s;
|
|
r_gun->scale = 255 / (surface->dwRBitMask >> s);
|
|
|
|
for (s = 0, m = surface->dwGBitMask; !(m & 1); s++, m >>= 1);
|
|
g_gun->mask = surface->dwGBitMask;
|
|
g_gun->shift = s;
|
|
g_gun->scale = 255 / (surface->dwGBitMask >> s);
|
|
|
|
for (s = 0, m = surface->dwBBitMask; !(m & 1); s++, m >>= 1);
|
|
b_gun->mask = surface->dwBBitMask;
|
|
b_gun->shift = s;
|
|
b_gun->scale = 255 / (surface->dwBBitMask >> s);
|
|
|
|
a_gun->mask = surface->dwRGBAlphaBitMask;
|
|
|
|
// UP: Filter out cases which cause infinite loops
|
|
if ((surface->dw_is_alpha_mode == true) && (surface->dwRGBAlphaBitMask != 0) )
|
|
{
|
|
// UP: This is the exact line causing problems - it formed an infinite loop
|
|
for (s = 0, m = surface->dwRGBAlphaBitMask; !(m & 1); s++, m >>= 1);
|
|
|
|
// Friendly debugging loop
|
|
// for (s = 0, m = surface->dwRGBAlphaBitMask; !(m & 1); s++)
|
|
// m >>= 1;
|
|
|
|
a_gun->shift = s;
|
|
a_gun->scale = 255 / (surface->dwRGBAlphaBitMask >> s);
|
|
}
|
|
else
|
|
{
|
|
a_gun->shift = 0;
|
|
a_gun->scale = 256;
|
|
}
|
|
}
|
|
|
|
void d3d_release_rendering_objects()
|
|
{
|
|
if ( GlobalD3DVars::lpD3DDevice ) {
|
|
GlobalD3DVars::lpD3DDevice->Release();
|
|
GlobalD3DVars::lpD3DDevice = NULL;
|
|
}
|
|
|
|
// DBUGFILE_OUTPUT_COUNTER(0, "Number of unfreed textures");
|
|
}
|
|
|
|
bool d3d_init_win32(int screen_width, int screen_height)
|
|
{
|
|
HWND hwnd = (HWND)os_get_window();
|
|
// RECT rect;
|
|
|
|
if ( !hwnd ) {
|
|
strcpy(Device_init_error, "Could not get application window handle");
|
|
return false;
|
|
}
|
|
/*
|
|
// windowed
|
|
if(GlobalD3DVars::D3D_window)
|
|
{
|
|
GetClientRect(hwnd, &rect);
|
|
SetWindowPos(hwnd, HWND_TOP, rect.left, rect.top, rect.bottom, rect.right, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE | SWP_DRAWFRAME);
|
|
} else {
|
|
// Prepare the window to go full screen
|
|
#ifndef NDEBUG
|
|
mprintf(( " Window in debugging mode... mouse clicking may cause problems!\n" ));
|
|
SetWindowLong( hwnd, GWL_EXSTYLE, 0 );
|
|
SetWindowLong( hwnd, GWL_STYLE, WS_POPUP );
|
|
ShowWindow(hwnd, SW_SHOWNORMAL );
|
|
RECT work_rect;
|
|
SystemParametersInfo( SPI_GETWORKAREA, 0, &work_rect, 0 );
|
|
SetWindowPos( hwnd, HWND_TOPMOST, work_rect.left, work_rect.top, gr_screen.max_w, gr_screen.max_h, 0 );
|
|
#else
|
|
SetWindowLong( hwnd, GWL_EXSTYLE, 0 );
|
|
SetWindowLong( hwnd, GWL_STYLE, WS_POPUP );
|
|
ShowWindow(hwnd, SW_SHOWNORMAL );
|
|
SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, gr_screen.max_w, gr_screen.max_h, 0 );
|
|
#endif
|
|
}
|
|
*/
|
|
|
|
SetForegroundWindow(hwnd);
|
|
SetActiveWindow(hwnd);
|
|
SetFocus(hwnd);
|
|
|
|
d3d_clip_cursor();
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Determines value of D3d_rendition_uvs
|
|
*
|
|
* @return void
|
|
*/
|
|
void d3d_detect_texture_origin_32()
|
|
{
|
|
int test_bmp = -1;
|
|
ubyte data[32*32];
|
|
color ac;
|
|
uint pix1b(0), pix2b(0);
|
|
|
|
mprintf(( "Detecting uv type...\n" ));
|
|
|
|
gr_set_gamma(1.0f);
|
|
gr_init_alphacolor(&ac,255,255,255,255);
|
|
|
|
memset( data, 0, 32*32 );
|
|
data[15*32+15] = 14;
|
|
|
|
test_bmp = bm_create( 8, 32, 32, data, BMP_AABITMAP );
|
|
|
|
mprintf(( "Trial #1\n" ));
|
|
GlobalD3DVars::D3D_rendition_uvs = 0;
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_set_color_fast(&ac);
|
|
gr_set_bitmap( test_bmp );
|
|
gr_aabitmap_ex(0, 0, 32, 32, 15, 15);
|
|
Mouse_hidden++;
|
|
gr_flip();
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_flip();
|
|
Mouse_hidden--;
|
|
|
|
mprintf(( "Trial #2\n" ));
|
|
GlobalD3DVars::D3D_rendition_uvs = 1;
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_set_color_fast(&ac);
|
|
gr_set_bitmap( test_bmp );
|
|
gr_aabitmap_ex(0, 0, 32, 32, 15, 15);
|
|
Mouse_hidden++;
|
|
gr_flip();
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_flip();
|
|
Mouse_hidden--;
|
|
|
|
bm_release(test_bmp);
|
|
|
|
if ( (pix1b!=0) || (pix2b!=0) ) {
|
|
GlobalD3DVars::D3D_rendition_uvs = 1;
|
|
} else {
|
|
GlobalD3DVars::D3D_rendition_uvs = 0;
|
|
}
|
|
|
|
mprintf(( "Rendition uvs: %d\n", GlobalD3DVars::D3D_rendition_uvs ));
|
|
}
|
|
|
|
/**
|
|
* Determines value of D3d_rendition_uvs
|
|
*
|
|
* @return void
|
|
*/
|
|
void d3d_detect_texture_origin_16()
|
|
{
|
|
int test_bmp = -1;
|
|
ubyte data[32*32];
|
|
color ac;
|
|
ushort pix1b(0), pix2b(0);
|
|
|
|
mprintf(( "Detecting uv type...\n" ));
|
|
|
|
gr_set_gamma(1.0f);
|
|
gr_init_alphacolor(&ac,255,255,255,255);
|
|
|
|
memset( data, 0, 32*32 );
|
|
data[15*32+15] = 14;
|
|
|
|
test_bmp = bm_create( 8, 32, 32, data, BMP_AABITMAP );
|
|
|
|
mprintf(( "Trial #1\n" ));
|
|
GlobalD3DVars::D3D_rendition_uvs = 0;
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_set_color_fast(&ac);
|
|
gr_set_bitmap( test_bmp );
|
|
gr_aabitmap_ex(0, 0, 32, 32, 15, 15);
|
|
Mouse_hidden++;
|
|
gr_flip();
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_flip();
|
|
Mouse_hidden--;
|
|
|
|
mprintf(( "Trial #2\n" ));
|
|
GlobalD3DVars::D3D_rendition_uvs = 1;
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_set_color_fast(&ac);
|
|
gr_set_bitmap( test_bmp );
|
|
gr_aabitmap_ex(0, 0, 32, 32, 15, 15);
|
|
Mouse_hidden++;
|
|
gr_flip();
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_flip();
|
|
Mouse_hidden--;
|
|
|
|
bm_release(test_bmp);
|
|
|
|
if ( (pix1b!=0) || (pix2b!=0) ) {
|
|
GlobalD3DVars::D3D_rendition_uvs = 1;
|
|
} else {
|
|
GlobalD3DVars::D3D_rendition_uvs = 0;
|
|
}
|
|
|
|
mprintf(( "Rendition uvs: %d\n", GlobalD3DVars::D3D_rendition_uvs ));
|
|
}
|
|
|
|
/**
|
|
* Determines value of D3D_line_offset
|
|
*
|
|
* @return void
|
|
*/
|
|
void d3d_detect_line_offset_32()
|
|
{
|
|
extern float D3D_line_offset;
|
|
|
|
color ac;
|
|
uint pix1a(0), pix2a(0);
|
|
|
|
mprintf(( "Detecting line offset...\n" ));
|
|
|
|
gr_set_gamma(1.0f);
|
|
gr_init_alphacolor(&ac, 255,255, 255, 255);
|
|
|
|
mprintf(( "Trial #1\n" ));
|
|
D3D_line_offset = 0.0f;
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_set_color_fast(&ac);
|
|
gr_line( 0,0,0,0 );
|
|
Mouse_hidden++;
|
|
gr_flip();
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_flip();
|
|
Mouse_hidden--;
|
|
|
|
mprintf(( "Trial #2\n" ));
|
|
D3D_line_offset = 0.5f;
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_set_color_fast(&ac);
|
|
gr_line( 0,0,0,0 );
|
|
Mouse_hidden++;
|
|
gr_flip();
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_flip();
|
|
Mouse_hidden--;
|
|
|
|
if ( (pix1a!=0) && (pix2a==0) ) {
|
|
D3D_line_offset = 0.0f;
|
|
} else if ( (pix1a==0) && (pix2a!=0) ) {
|
|
D3D_line_offset = 0.5f;
|
|
} else {
|
|
D3D_line_offset = 0.0f;
|
|
}
|
|
|
|
mprintf(( "Line offset: %.1f\n", D3D_line_offset ));
|
|
}
|
|
|
|
/**
|
|
* Determines value of D3D_line_offset
|
|
*
|
|
* @return void
|
|
*/
|
|
void d3d_detect_line_offset_16()
|
|
{
|
|
extern float D3D_line_offset;
|
|
|
|
color ac;
|
|
ushort pix1a(0), pix2a(0);
|
|
|
|
mprintf(( "Detecting line offset...\n" ));
|
|
|
|
gr_set_gamma(1.0f);
|
|
gr_init_alphacolor(&ac, 255,255, 255, 255);
|
|
|
|
mprintf(( "Trial #1\n" ));
|
|
D3D_line_offset = 0.0f;
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_set_color_fast(&ac);
|
|
gr_line( 0,0,0,0 );
|
|
Mouse_hidden++;
|
|
gr_flip();
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_flip();
|
|
Mouse_hidden--;
|
|
|
|
mprintf(( "Trial #2\n" ));
|
|
D3D_line_offset = 0.5f;
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_set_color_fast(&ac);
|
|
gr_line( 0,0,0,0 );
|
|
Mouse_hidden++;
|
|
gr_flip();
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_flip();
|
|
Mouse_hidden--;
|
|
|
|
if ( (pix1a!=0) && (pix2a==0) ) {
|
|
D3D_line_offset = 0.0f;
|
|
} else if ( (pix1a==0) && (pix2a!=0) ) {
|
|
D3D_line_offset = 0.5f;
|
|
} else {
|
|
D3D_line_offset = 0.0f;
|
|
}
|
|
|
|
mprintf(( "Line offset: %.1f\n", D3D_line_offset ));
|
|
}
|
|
|
|
/**
|
|
* D3D8 Launcher func: Return bit type for modes, those not listed or simply not valid for FS2
|
|
*
|
|
* @return int, 32, 16 or 0 if not valid
|
|
* @param D3DFORMAT type
|
|
*/
|
|
int d3d_get_mode_bit(D3DFORMAT type)
|
|
{
|
|
switch(type)
|
|
{
|
|
case D3DFMT_X8R8G8B8:
|
|
case D3DFMT_A8R8G8B8:
|
|
//case D3DFMT_A2B10G10R10:
|
|
return 32;
|
|
|
|
case D3DFMT_R8G8B8:
|
|
case D3DFMT_R5G6B5:
|
|
case D3DFMT_X1R5G5B5:
|
|
case D3DFMT_X4R4G4B4:
|
|
case D3DFMT_A1R5G5B5:
|
|
case D3DFMT_A4R4G4B4:
|
|
case D3DFMT_A8R3G3B2:
|
|
return 16;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* This checks that the given texture format is supported in the chosen adapter and mode
|
|
*
|
|
* @return bool
|
|
* @param D3DFORMAT tformat
|
|
*/
|
|
bool d3d_texture_format_is_supported(D3DFORMAT tformat, int adapter, D3DDISPLAYMODE *mode)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = GlobalD3DVars::lpD3D->CheckDeviceFormat(
|
|
adapter,
|
|
D3DDEVTYPE_HAL,
|
|
mode->Format,
|
|
0,
|
|
D3DRTYPE_TEXTURE,
|
|
tformat);
|
|
|
|
return SUCCEEDED(hr);
|
|
}
|
|
|
|
/**
|
|
* Fills the old style direct draw DDPIXELFORMAT with details needed for later
|
|
* We are not using direct draw, just making use of one of its structures
|
|
* The shift values are used to convert textures from load set to correct texture format
|
|
*
|
|
* @return void
|
|
* @param DDPIXELFORMAT *pixelf
|
|
* @param D3DFORMAT tformat
|
|
*/
|
|
void d3d_fill_pixel_format(PIXELFORMAT *pixelf, D3DFORMAT tformat)
|
|
{
|
|
switch(tformat)
|
|
{
|
|
case D3DFMT_X8R8G8B8:
|
|
pixelf->dwRGBBitCount = 32;
|
|
pixelf->dwRBitMask = 0xff0000;
|
|
pixelf->dwGBitMask = 0xff00;
|
|
pixelf->dwBBitMask = 0xff;
|
|
pixelf->dw_is_alpha_mode = false;
|
|
pixelf->dwRGBAlphaBitMask = 0;
|
|
printf(("Using: D3DFMT_X8R8G8B8"));
|
|
break;
|
|
case D3DFMT_R8G8B8:
|
|
pixelf->dwRGBBitCount = 24;
|
|
pixelf->dwRBitMask = 0xff0000;
|
|
pixelf->dwGBitMask = 0xff00;
|
|
pixelf->dwBBitMask = 0xff;
|
|
pixelf->dw_is_alpha_mode = false;
|
|
pixelf->dwRGBAlphaBitMask = 0;
|
|
printf(("Using: D3DFMT_R8G8B8"));
|
|
break;
|
|
case D3DFMT_X1R5G5B5:
|
|
pixelf->dwRGBBitCount = 16;
|
|
pixelf->dwRBitMask = 0x7c00;
|
|
pixelf->dwGBitMask = 0x3e0;
|
|
pixelf->dwBBitMask = 0x1f;
|
|
pixelf->dw_is_alpha_mode = false;
|
|
pixelf->dwRGBAlphaBitMask = 0;
|
|
printf(("Using: D3DFMT_X1R5G5B5"));
|
|
break;
|
|
case D3DFMT_R5G6B5:
|
|
pixelf->dwRGBBitCount = 16;
|
|
pixelf->dwRBitMask = 0xf800;
|
|
pixelf->dwGBitMask = 0x7e0;
|
|
pixelf->dwBBitMask = 0x1f;
|
|
pixelf->dw_is_alpha_mode = false;
|
|
pixelf->dwRGBAlphaBitMask = 0;
|
|
printf(("Using: D3DFMT_R5G6B5"));
|
|
break;
|
|
case D3DFMT_X4R4G4B4:
|
|
pixelf->dwRGBBitCount = 16;
|
|
pixelf->dwRBitMask = 0xf00;
|
|
pixelf->dwGBitMask = 0xf0;
|
|
pixelf->dwBBitMask = 0xf;
|
|
pixelf->dw_is_alpha_mode = false;
|
|
pixelf->dwRGBAlphaBitMask = 0;
|
|
printf(("Using: D3DFMT_X4R4G4B4"));
|
|
break;
|
|
case D3DFMT_A8R8G8B8:
|
|
pixelf->dwRGBBitCount = 32;
|
|
pixelf->dwRBitMask = 0xff0000;
|
|
pixelf->dwGBitMask = 0xff00;
|
|
pixelf->dwBBitMask = 0xff;
|
|
pixelf->dwRGBAlphaBitMask = 0xff000000;
|
|
pixelf->dw_is_alpha_mode = true;
|
|
printf(("Using: D3DFMT_A8R8G8B8"));
|
|
break;
|
|
case D3DFMT_A1R5G5B5:
|
|
pixelf->dwRGBBitCount = 16;
|
|
pixelf->dwRBitMask = 0x7c00;
|
|
pixelf->dwGBitMask = 0x3e0;
|
|
pixelf->dwBBitMask = 0x1f;
|
|
pixelf->dwRGBAlphaBitMask = 0x8000;
|
|
pixelf->dw_is_alpha_mode = true;
|
|
printf(("Using: D3DFMT_A1R5G5B5"));
|
|
break;
|
|
case D3DFMT_A4R4G4B4:
|
|
pixelf->dwRGBBitCount = 16;
|
|
pixelf->dwRBitMask = 0xf00;
|
|
pixelf->dwGBitMask = 0xf0;
|
|
pixelf->dwBBitMask = 0xf;
|
|
pixelf->dwRGBAlphaBitMask = 0xf000;
|
|
pixelf->dw_is_alpha_mode = true;
|
|
printf(("Using: D3DFMT_A4R4G4B4"));
|
|
break;
|
|
case D3DFMT_A8R3G3B2:
|
|
pixelf->dwRGBBitCount = 16;
|
|
pixelf->dwRBitMask = 0xe0;
|
|
pixelf->dwGBitMask = 0x1c;
|
|
pixelf->dwBBitMask = 0x3;
|
|
pixelf->dwRGBAlphaBitMask = 0xff00;
|
|
pixelf->dw_is_alpha_mode = true;
|
|
printf(("Using: D3DFMT_A8R3G3B2"));
|
|
break;
|
|
/*case D3DFMT_A2B10G10R10:
|
|
pixelf->dwRGBBitCount = 32;
|
|
pixelf->dwRBitMask = 0x3ff00000;
|
|
pixelf->dwGBitMask = 0xffc00;
|
|
pixelf->dwBBitMask = 0x3ff;
|
|
pixelf->dwRGBAlphaBitMask = 0xc0000000;
|
|
pixelf->dwFlags = DDPF_ALPHAPIXELS;
|
|
mprintf(("Using: D3DFMT_A2B10G10R10"));
|
|
break;*/
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Works out the best texture formats to use in the chosen mode
|
|
*
|
|
* @return void
|
|
*/
|
|
void d3d_determine_texture_formats(int adapter, D3DDISPLAYMODE *mode)
|
|
{
|
|
const int num_non_alpha = 3;
|
|
const int num_alpha = 4;
|
|
int i;
|
|
|
|
default_non_alpha_tformat = D3DFMT_UNKNOWN;
|
|
default_alpha_tformat = D3DFMT_UNKNOWN;
|
|
|
|
// Non alpha (listed from best to worst)
|
|
D3DFORMAT non_alpha_list[num_non_alpha] =
|
|
{
|
|
D3DFMT_A1R5G5B5,
|
|
D3DFMT_A4R4G4B4,
|
|
D3DFMT_A8R3G3B2,
|
|
};
|
|
|
|
// Alpha (listed from best to worst)
|
|
D3DFORMAT alpha_list[num_alpha] =
|
|
{
|
|
D3DFMT_A4R4G4B4,
|
|
D3DFMT_A1R5G5B5,
|
|
D3DFMT_A8R3G3B2,
|
|
};
|
|
|
|
// Go through the alpha list and find a texture format of a valid depth
|
|
// and is supported in this adapter mode
|
|
for(i = 0; i < num_alpha; i++) {
|
|
if(d3d_get_mode_bit(alpha_list[i]) != 16) {
|
|
continue;
|
|
}
|
|
|
|
if(d3d_texture_format_is_supported(alpha_list[i], adapter, mode) == true) {
|
|
default_alpha_tformat = alpha_list[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
// If this is unknown this has failed
|
|
if(default_alpha_tformat == D3DFMT_UNKNOWN) {
|
|
mprintf(("alpha texture format not selected"));
|
|
} else {
|
|
d3d_fill_pixel_format(&AlphaTextureFormat, default_alpha_tformat);
|
|
}
|
|
|
|
// Go through the non alpha list and find a texture format of a valid depth
|
|
// and is supported in this adapter mode
|
|
for(i = 0; i < num_non_alpha; i++)
|
|
{
|
|
if(d3d_get_mode_bit(non_alpha_list[i]) != 16)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if(d3d_texture_format_is_supported(non_alpha_list[i], adapter, mode) == true)
|
|
{
|
|
default_non_alpha_tformat = non_alpha_list[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
// If this is unknown this has failed
|
|
if(default_non_alpha_tformat == D3DFMT_UNKNOWN)
|
|
{
|
|
mprintf(("non alpha texture format not selected"));
|
|
}
|
|
else
|
|
{
|
|
// Um hack here, forget about non alpha formats!
|
|
d3d_fill_pixel_format(&NonAlphaTextureFormat, default_non_alpha_tformat);
|
|
}
|
|
|
|
// Check compressed textures here
|
|
Use_compressed_textures = ( d3d_texture_format_is_supported(D3DFMT_DXT1, adapter, mode) &&
|
|
d3d_texture_format_is_supported(D3DFMT_DXT3, adapter, mode) &&
|
|
d3d_texture_format_is_supported(D3DFMT_DXT5, adapter, mode) );
|
|
|
|
Texture_compression_available = ( d3d_texture_format_is_supported(D3DFMT_A8R8G8B8, adapter, mode) &&
|
|
d3d_texture_format_is_supported(D3DFMT_X8R8G8B8, adapter, mode) &&
|
|
Use_compressed_textures );
|
|
}
|
|
|
|
/**
|
|
* Sets up all the graphics function pointers to the relevent d3d functions
|
|
*
|
|
* @return void
|
|
*/
|
|
void d3d_setup_function_pointers()
|
|
{
|
|
// Set all the pointer to functions to the correct D3D functions
|
|
gr_screen.gf_flip = gr_d3d_flip;
|
|
gr_screen.gf_set_clip = gr_d3d_set_clip;
|
|
gr_screen.gf_reset_clip = gr_d3d_reset_clip;
|
|
|
|
gr_screen.gf_set_bitmap = gr_d3d_set_bitmap;
|
|
gr_screen.gf_clear = gr_d3d_clear;
|
|
gr_screen.gf_bitmap_ex = gr_d3d_bitmap_ex;
|
|
gr_screen.gf_aabitmap = gr_d3d_aabitmap;
|
|
gr_screen.gf_aabitmap_ex = gr_d3d_aabitmap_ex;
|
|
|
|
// gr_screen.gf_rect = gr_d3d_rect;
|
|
// gr_screen.gf_shade = gr_d3d_shade;
|
|
gr_screen.gf_string = gr_d3d_string;
|
|
gr_screen.gf_circle = gr_d3d_circle;
|
|
gr_screen.gf_curve = gr_d3d_curve;
|
|
|
|
gr_screen.gf_line = gr_d3d_line;
|
|
gr_screen.gf_aaline = gr_d3d_aaline;
|
|
gr_screen.gf_pixel = gr_d3d_pixel;
|
|
gr_screen.gf_scaler = gr_d3d_scaler;
|
|
gr_screen.gf_aascaler = gr_d3d_aascaler;
|
|
gr_screen.gf_tmapper = gr_d3d_tmapper;
|
|
|
|
gr_screen.gf_gradient = gr_d3d_gradient;
|
|
|
|
gr_screen.gf_set_palette = gr_d3d_set_palette;
|
|
gr_screen.gf_print_screen = gr_d3d_print_screen;
|
|
|
|
gr_screen.gf_fade_in = gr_d3d_fade_in;
|
|
gr_screen.gf_fade_out = gr_d3d_fade_out;
|
|
gr_screen.gf_flash = gr_d3d_flash;
|
|
gr_screen.gf_flash_alpha = gr_d3d_flash_alpha;
|
|
|
|
gr_screen.gf_zbuffer_get = gr_d3d_zbuffer_get;
|
|
gr_screen.gf_zbuffer_set = gr_d3d_zbuffer_set;
|
|
gr_screen.gf_zbuffer_clear = gr_d3d_zbuffer_clear;
|
|
|
|
gr_screen.gf_save_screen = gr_d3d_save_screen;
|
|
gr_screen.gf_restore_screen = gr_d3d_restore_screen;
|
|
gr_screen.gf_free_screen = gr_d3d_free_screen;
|
|
|
|
// Screen dumping stuff
|
|
gr_screen.gf_dump_frame_start = gr_d3d_dump_frame_start;
|
|
gr_screen.gf_dump_frame_stop = gr_d3d_dump_frame_stop;
|
|
gr_screen.gf_dump_frame = gr_d3d_dump_frame;
|
|
|
|
gr_screen.gf_set_gamma = gr_d3d_set_gamma;
|
|
|
|
// Lock/unlock stuff
|
|
gr_screen.gf_lock = gr_d3d_lock;
|
|
gr_screen.gf_unlock = gr_d3d_unlock;
|
|
|
|
// screen region
|
|
gr_screen.gf_get_region = gr_d3d_get_region;
|
|
|
|
// fog stuff
|
|
gr_screen.gf_fog_set = gr_d3d_fog_set;
|
|
|
|
// poly culling
|
|
gr_screen.gf_set_cull = gr_d3d_set_cull;
|
|
|
|
// cross fade
|
|
gr_screen.gf_cross_fade = gr_d3d_cross_fade;
|
|
|
|
// filtering
|
|
gr_screen.gf_filter_set = gr_d3d_filter_set;
|
|
|
|
// texture cache
|
|
gr_screen.gf_tcache_set = d3d_tcache_set;
|
|
|
|
// set clear color
|
|
gr_screen.gf_set_clear_color = gr_d3d_set_clear_color;
|
|
|
|
// preload a bitmap into texture memory
|
|
gr_screen.gf_preload = gr_d3d_preload;
|
|
|
|
// now for the bitmap functions
|
|
gr_screen.gf_bm_free_data = gr_d3d_bm_free_data;
|
|
gr_screen.gf_bm_create = gr_d3d_bm_create;
|
|
gr_screen.gf_bm_init = gr_d3d_bm_init;
|
|
gr_screen.gf_bm_load = gr_d3d_bm_load;
|
|
gr_screen.gf_bm_page_in_start = gr_d3d_bm_page_in_start;
|
|
gr_screen.gf_bm_lock = gr_d3d_bm_lock;
|
|
gr_screen.gf_bm_make_render_target = gr_d3d_bm_make_render_target;
|
|
gr_screen.gf_bm_set_render_target = gr_d3d_bm_set_render_target;
|
|
|
|
|
|
|
|
gr_screen.gf_push_texture_matrix = gr_d3d_push_texture_matrix;
|
|
gr_screen.gf_pop_texture_matrix = gr_d3d_pop_texture_matrix;
|
|
gr_screen.gf_translate_texture_matrix = gr_d3d_translate_texture_matrix;
|
|
|
|
gr_screen.gf_set_texture_addressing = gr_d3d_set_texture_addressing;
|
|
gr_screen.gf_zbias = gr_d3d_zbias;
|
|
gr_screen.gf_set_fill_mode = gr_d3d_set_fill_mode;
|
|
gr_screen.gf_set_texture_panning = d3d_set_texture_panning;
|
|
|
|
gr_screen.gf_start_state_block = gr_d3d_start_state_block;
|
|
gr_screen.gf_end_state_block = gr_d3d_end_state_block;
|
|
gr_screen.gf_set_state_block = gr_d3d_set_state_block;
|
|
|
|
if(!Cmdline_nohtl) {
|
|
gr_screen.gf_make_buffer = gr_d3d_make_buffer;
|
|
gr_screen.gf_destroy_buffer = gr_d3d_destroy_buffer;
|
|
gr_screen.gf_render_buffer = gr_d3d_render_buffer;
|
|
gr_screen.gf_set_buffer = gr_d3d_set_buffer;
|
|
gr_screen.gf_make_flat_buffer = gr_d3d_make_flat_buffer;
|
|
gr_screen.gf_make_line_buffer = gr_d3d_make_line_buffer;
|
|
|
|
gr_screen.gf_set_proj_matrix = gr_d3d_set_proj_matrix;
|
|
gr_screen.gf_end_proj_matrix = gr_d3d_end_proj_matrix;
|
|
gr_screen.gf_set_view_matrix = gr_d3d_set_view_matrix;
|
|
gr_screen.gf_end_view_matrix = gr_d3d_end_view_matrix;
|
|
gr_screen.gf_push_scale_matrix = gr_d3d_set_scale_matrix;
|
|
gr_screen.gf_pop_scale_matrix = gr_d3d_end_scale_matrix;
|
|
gr_screen.gf_start_instance_matrix = gr_d3d_start_instance_matrix;
|
|
gr_screen.gf_start_angles_instance_matrix = gr_d3d_start_angles_instance_matrix;
|
|
gr_screen.gf_end_instance_matrix = gr_d3d_end_instance_matrix;
|
|
|
|
gr_screen.gf_make_light = gr_d3d_make_light;
|
|
gr_screen.gf_modify_light = gr_d3d_modify_light;
|
|
gr_screen.gf_destroy_light = gr_d3d_destroy_light;
|
|
gr_screen.gf_set_light = gr_d3d_set_light;
|
|
gr_screen.gf_reset_lighting = gr_d3d_reset_lighting;
|
|
gr_screen.gf_set_ambient_light = gr_d3d_set_ambient_light;
|
|
|
|
gr_screen.gf_lighting = gr_d3d_lighting;
|
|
gr_screen.gf_center_alpha = gr_d3d_center_alpha;
|
|
|
|
gr_screen.gf_start_clip_plane = gr_d3d_start_clip;
|
|
gr_screen.gf_end_clip_plane = gr_d3d_end_clip;
|
|
gr_screen.gf_setup_background_fog = gr_d3d_setup_background_fog;
|
|
gr_screen.gf_draw_line_list = gr_d3d_draw_line_list;
|
|
gr_screen.gf_set_line_width = gr_d3d_set_line_width;
|
|
gr_screen.gf_draw_htl_line = gr_d3d_draw_htl_line;
|
|
gr_screen.gf_draw_htl_sphere = gr_d3d_draw_htl_sphere;
|
|
// gr_screen.gf_set_environment_mapping = d3d_render_to_env;
|
|
}
|
|
|
|
}
|
|
|
|
int d3d_match_mode(int adapter)
|
|
{
|
|
int num_modes = GlobalD3DVars::lpD3D->GetAdapterModeCount(adapter);
|
|
|
|
if(num_modes == 0) {
|
|
strcpy(Device_init_error, "No modes for this adapter");
|
|
return -1;
|
|
}
|
|
|
|
for(int i = 0; i < num_modes; i++)
|
|
{
|
|
D3DDISPLAYMODE mode;
|
|
GlobalD3DVars::lpD3D->EnumAdapterModes(adapter, i, &mode);
|
|
|
|
// ignore invalid modes
|
|
if(gr_screen.bits_per_pixel != d3d_get_mode_bit(mode.Format)) continue;
|
|
if(gr_screen.max_w != (int)mode.Width) continue;
|
|
if(gr_screen.max_h != (int)mode.Height) continue;
|
|
|
|
// This is the mode we want
|
|
return i;
|
|
}
|
|
|
|
strcpy(Device_init_error, "No suitable mode found");
|
|
return -1;
|
|
}
|
|
|
|
int d3d_check_multisample_types(int adapter, int chosen_ms, D3DFORMAT back_buffer_format, D3DFORMAT depth_buffer_format)
|
|
{
|
|
HRESULT hr;
|
|
int i;
|
|
|
|
// If fails try a lesser mode
|
|
for(i = chosen_ms; i >= 0; i--)
|
|
{
|
|
hr = GlobalD3DVars::lpD3D->CheckDeviceMultiSampleType(
|
|
adapter, D3DDEVTYPE_HAL, back_buffer_format, GlobalD3DVars::D3D_window, multisample_types[i]);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
DBUGFILE_OUTPUT_1("Failed aa %d",i);
|
|
continue;
|
|
}
|
|
|
|
hr = GlobalD3DVars::lpD3D->CheckDeviceMultiSampleType(
|
|
adapter, D3DDEVTYPE_HAL, depth_buffer_format, GlobalD3DVars::D3D_window, multisample_types[i]);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
DBUGFILE_OUTPUT_1("Failed aa %d",i);
|
|
continue;
|
|
}
|
|
|
|
// Success!
|
|
DBUGFILE_OUTPUT_1("Success aa %d",i);
|
|
return i;
|
|
}
|
|
|
|
// Now try higher modes
|
|
for(i = (chosen_ms + 1); i < MULTISAMPLE_MAX; i++)
|
|
{
|
|
hr = GlobalD3DVars::lpD3D->CheckDeviceMultiSampleType(
|
|
adapter, D3DDEVTYPE_HAL, back_buffer_format, GlobalD3DVars::D3D_window, multisample_types[i]);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
DBUGFILE_OUTPUT_1("Failed aa %d",i);
|
|
continue;
|
|
}
|
|
|
|
hr = GlobalD3DVars::lpD3D->CheckDeviceMultiSampleType(
|
|
adapter, D3DDEVTYPE_HAL, depth_buffer_format, GlobalD3DVars::D3D_window, multisample_types[i]);
|
|
|
|
if(FAILED(hr))
|
|
{
|
|
DBUGFILE_OUTPUT_1("Failed aa %d",i);
|
|
continue;
|
|
}
|
|
|
|
// Success!
|
|
DBUGFILE_OUTPUT_1("Success aa %d",i);
|
|
return i;
|
|
}
|
|
|
|
// Nothing found
|
|
DBUGFILE_OUTPUT_0("Terrible news, we didnt find a match");
|
|
return -1;
|
|
}
|
|
|
|
void d3d_compare_adapter(int adapter_choice)
|
|
{
|
|
HRESULT hrd, hrc;
|
|
D3DADAPTER_IDENTIFIER8 info_default, info_chosen;
|
|
hrd = GlobalD3DVars::lpD3D->GetAdapterIdentifier(D3DADAPTER_DEFAULT, D3DENUM_NO_WHQL_LEVEL, &info_default);
|
|
hrc = GlobalD3DVars::lpD3D->GetAdapterIdentifier(D3DADAPTER_DEFAULT, D3DENUM_NO_WHQL_LEVEL, &info_chosen);
|
|
|
|
if(FAILED(hrd) || FAILED(hrc))
|
|
{
|
|
DBUGFILE_OUTPUT_2("Failed to identify default %d, chosen %d",FAILED(hrd), FAILED(hrc));
|
|
return;
|
|
}
|
|
|
|
D3DADAPTER_IDENTIFIER8 *info = &info_default;
|
|
DBUGFILE_OUTPUT_0("Default:");
|
|
DBUGFILE_OUTPUT_2("%s %s",info->Driver, info->Description);
|
|
|
|
info = &info_chosen;
|
|
DBUGFILE_OUTPUT_0("Chosen:");
|
|
DBUGFILE_OUTPUT_2("%s %s",info->Driver, info->Description);
|
|
}
|
|
|
|
/**
|
|
* This deals totally with mode stuff
|
|
*
|
|
* @return bool
|
|
*/
|
|
bool d3d_init_device()
|
|
{
|
|
D3DDISPLAYMODE mode;
|
|
|
|
int adapter_choice = D3DADAPTER_DEFAULT;
|
|
|
|
// Set up the common device parameters
|
|
ZeroMemory( &GlobalD3DVars::d3dpp, sizeof(GlobalD3DVars::d3dpp) );
|
|
|
|
GlobalD3DVars::d3dpp.BackBufferCount = 1;
|
|
GlobalD3DVars::d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
|
GlobalD3DVars::d3dpp.EnableAutoDepthStencil = TRUE;
|
|
// This gets changed later
|
|
GlobalD3DVars::d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
|
|
|
|
if(Cmdline_nohtl) {
|
|
// Only need this for software fog
|
|
GlobalD3DVars::d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
|
|
}
|
|
|
|
extern int Cmdline_window;
|
|
extern int D3D_window;
|
|
int aatype_choice = 0;
|
|
GlobalD3DVars::D3D_window = Cmdline_window ? true : false;
|
|
|
|
// Get caps
|
|
bool got_caps =
|
|
SUCCEEDED(
|
|
GlobalD3DVars::lpD3D->GetDeviceCaps(
|
|
adapter_choice, D3DDEVTYPE_HAL, &GlobalD3DVars::d3d_caps));
|
|
|
|
if (GlobalD3DVars::D3D_window) {
|
|
// If we go windowed, then we need to adjust some other present parameters
|
|
if (FAILED(GlobalD3DVars::lpD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &mode )))
|
|
{
|
|
strcpy(Device_init_error, "Could not get adapter display mode");
|
|
return false;
|
|
}
|
|
|
|
GlobalD3DVars::d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
|
|
GlobalD3DVars::d3dpp.BackBufferWidth = (UINT)gr_screen.max_w;
|
|
GlobalD3DVars::d3dpp.BackBufferHeight = (UINT)gr_screen.max_h;
|
|
|
|
GlobalD3DVars::d3dpp.FullScreen_RefreshRateInHz = 0;
|
|
GlobalD3DVars::d3dpp.FullScreen_PresentationInterval = 0;
|
|
|
|
GlobalD3DVars::d3dpp.Windowed = TRUE;
|
|
} else {
|
|
|
|
// Attempt to get options from the registry
|
|
adapter_choice = os_config_read_uint( NULL, "D3D8_Adapter", 0xffff);
|
|
aatype_choice = os_config_read_uint( NULL, "D3D8_AAType", 0x0);
|
|
int mode_choice = d3d_match_mode(adapter_choice);
|
|
|
|
if(mode_choice == -1)
|
|
{
|
|
strcpy(Device_init_error, "Couldnt match mode");
|
|
return false;
|
|
}
|
|
|
|
// Sanity cap
|
|
if(aatype_choice < 0 || aatype_choice >= MULTISAMPLE_MAX)
|
|
{
|
|
aatype_choice = 0;
|
|
}
|
|
|
|
// Should only activate if a value in the registry is not set or its going to run in a window or
|
|
// a optional parameter forces it to run. Otherwise the mode values are taken from reg value
|
|
if( adapter_choice == 0xffff)
|
|
{
|
|
strcpy(Device_init_error, "DX8 options not set, please run launcher");
|
|
return false;
|
|
}
|
|
|
|
d3d_compare_adapter(adapter_choice);
|
|
|
|
if(FAILED(GlobalD3DVars::lpD3D->EnumAdapterModes(adapter_choice, mode_choice, &mode)))
|
|
{
|
|
sprintf(Device_init_error, "Could not use selected mode: %d", mode_choice);
|
|
return false;
|
|
}
|
|
|
|
GlobalD3DVars::D3D_Antialiasing = (aatype_choice != 0);
|
|
|
|
GlobalD3DVars::d3dpp.MultiSampleType = multisample_types[aatype_choice];
|
|
GlobalD3DVars::d3dpp.BackBufferWidth = mode.Width;
|
|
GlobalD3DVars::d3dpp.BackBufferHeight = mode.Height;
|
|
|
|
// Calculate texture pullback values
|
|
if(gr_screen.custom_size != -1)
|
|
{
|
|
GlobalD3DVars::texture_adjust_u = 0.0044f;
|
|
GlobalD3DVars::texture_adjust_v = 0.0044f;
|
|
gr_unsize_screen_posf(&GlobalD3DVars::texture_adjust_u, &GlobalD3DVars::texture_adjust_v);
|
|
}
|
|
|
|
GlobalD3DVars::d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
|
|
GlobalD3DVars::d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
|
|
|
if(Cmdline_no_vsync && got_caps && GlobalD3DVars::d3d_caps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) {
|
|
GlobalD3DVars::d3dpp.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
|
}
|
|
|
|
GlobalD3DVars::d3dpp.Windowed = FALSE;
|
|
}
|
|
|
|
D3DADAPTER_IDENTIFIER8 adapter_info;
|
|
if(SUCCEEDED(GlobalD3DVars::lpD3D->GetAdapterIdentifier(adapter_choice, D3DENUM_NO_WHQL_LEVEL, &adapter_info)))
|
|
{
|
|
mprintf((" Direct3D Adapter : %s\n", adapter_info.Description));
|
|
mprintf((" Direct3D Driver Version : %i.%i.%i.%i\n", HIWORD(adapter_info.DriverVersion.HighPart), LOWORD(adapter_info.DriverVersion.HighPart),
|
|
HIWORD(adapter_info.DriverVersion.LowPart), LOWORD(adapter_info.DriverVersion.LowPart)));
|
|
mprintf(("\n"));
|
|
}
|
|
|
|
GlobalD3DVars::d3dpp.BackBufferFormat = mode.Format;
|
|
|
|
//trying to use a higher bit depth in the back buffer, the deepest one posale -Bobboau
|
|
const int NUM_FORMATS = 3;
|
|
// const int NUM_FORMATS = 6;
|
|
|
|
enum _D3DFORMAT format_type[NUM_FORMATS] =
|
|
{D3DFMT_D24X8, D3DFMT_D32, D3DFMT_D16};
|
|
// {D3DFMT_D32, D3DFMT_D24X4S4, D3DFMT_D24S8, D3DFMT_D24X8, D3DFMT_D16, D3DFMT_D15S1};
|
|
|
|
const int NUM_VPTYPES = 3;
|
|
DWORD vptypes[NUM_VPTYPES] = {
|
|
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
|
D3DCREATE_MIXED_VERTEXPROCESSING,
|
|
D3DCREATE_SOFTWARE_VERTEXPROCESSING};
|
|
|
|
// Use a pure device if we can, it really speeds things up
|
|
// However it means we cant use Get* functions (aside from GetFrontBuffer, GetCaps, etc)
|
|
if(got_caps && GlobalD3DVars::d3d_caps.DevCaps & D3DDEVCAPS_PUREDEVICE) {
|
|
vptypes[0] |= D3DCREATE_PUREDEVICE;
|
|
mprintf((" Using PURE D3D Device\n"));
|
|
}
|
|
|
|
bool have_device = false;
|
|
for(int vp = 0; vp < NUM_VPTYPES; vp++)
|
|
{
|
|
// It trys to use the highest suported back buffer through trial and error,
|
|
// I wraped the existing code in a for loop to cycle through the diferent formats -Bobboau
|
|
for(int t = 0; t < NUM_FORMATS; t++){
|
|
|
|
GlobalD3DVars::d3dpp.AutoDepthStencilFormat = format_type[t];
|
|
|
|
int aaresult = d3d_check_multisample_types(
|
|
adapter_choice, aatype_choice,
|
|
GlobalD3DVars::d3dpp.BackBufferFormat,
|
|
GlobalD3DVars::d3dpp.AutoDepthStencilFormat);
|
|
|
|
if(aaresult == -1)
|
|
continue;
|
|
|
|
GlobalD3DVars::d3dpp.MultiSampleType = multisample_types[aaresult];
|
|
|
|
|
|
if( SUCCEEDED( GlobalD3DVars::lpD3D->CreateDevice(
|
|
adapter_choice,
|
|
D3DDEVTYPE_HAL,
|
|
(HWND) os_get_window(),
|
|
vptypes[vp],
|
|
&GlobalD3DVars::d3dpp,
|
|
&GlobalD3DVars::lpD3DDevice) ) ) {
|
|
have_device = true;
|
|
DBUGFILE_OUTPUT_2("Depth buffer format %d, aaresult %d",t,aaresult);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(have_device == true) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// This is bad, the mode hasnt initialised
|
|
if (have_device == false)
|
|
{
|
|
|
|
sprintf(Device_init_error, "Failed to get init mode");
|
|
|
|
// Lets draw attension to this bug which we dont yet understand
|
|
if(got_caps == false)
|
|
{
|
|
sprintf(Device_init_error,
|
|
"Failed to get init mode AND GETCAPS FAILED\n"
|
|
"Please contact Random Tiger about this problem directly\n"
|
|
"[email protected]");
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
GlobalD3DVars::d3dpp.BackBufferWidth = mode.Width;
|
|
|
|
d3d_determine_texture_formats(adapter_choice, &mode);
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
void d3d_init_vars_from_reg()
|
|
{
|
|
// Not sure now relevent this is now
|
|
uint tmp = os_config_read_uint( NULL, "D3DTextureOrigin", 0xFFFF );
|
|
|
|
if ( tmp != 0xFFFF ) {
|
|
GlobalD3DVars::D3D_rendition_uvs = ( tmp ) ? 1 : 0;
|
|
}
|
|
|
|
#if 0
|
|
else {
|
|
if(gr_screen.bits_per_pixel == 32){
|
|
d3d_detect_texture_origin_32();
|
|
} else {
|
|
d3d_detect_texture_origin_16();
|
|
}
|
|
}
|
|
|
|
mprintf((" D3d_rendition_uvs: %d",GlobalD3DVars::D3D_rendition_uvs));
|
|
|
|
// Not sure now relevent this is now
|
|
tmp = os_config_read_uint( NULL, "D3DLineOffset", 0xFFFF );
|
|
|
|
extern float D3D_line_offset;
|
|
if ( tmp != 0xFFFF ) {
|
|
D3D_line_offset = ( tmp ) ? 0.5f : 0.0f;
|
|
} else {
|
|
if(gr_screen.bits_per_pixel == 32){
|
|
d3d_detect_line_offset_32();
|
|
} else {
|
|
d3d_detect_line_offset_16();
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void d3d_setup_color()
|
|
{
|
|
// RT This stuff is needed for software fog
|
|
Gr_current_red = &Gr_red;
|
|
Gr_current_blue = &Gr_blue;
|
|
Gr_current_green = &Gr_green;
|
|
Gr_current_alpha = &Gr_alpha;
|
|
|
|
PIXELFORMAT temp_format;
|
|
d3d_fill_pixel_format(&temp_format, GlobalD3DVars::d3dpp.BackBufferFormat);
|
|
|
|
d3d_setup_format_components(&temp_format, Gr_current_red, Gr_current_green, Gr_current_blue, Gr_current_alpha);
|
|
|
|
d3d_setup_format_components(&NonAlphaTextureFormat, &Gr_t_red, &Gr_t_green, &Gr_t_blue, &Gr_t_alpha);
|
|
d3d_setup_format_components(&AlphaTextureFormat, &Gr_ta_red, &Gr_ta_green, &Gr_ta_blue, &Gr_ta_alpha);
|
|
|
|
mprintf(( " Alpha texture format = " ));
|
|
d3d_dump_format(&AlphaTextureFormat);
|
|
|
|
mprintf(( " Non-alpha texture format = " ));
|
|
d3d_dump_format(&NonAlphaTextureFormat);
|
|
|
|
if(!Cmdline_nohtl) {
|
|
|
|
extern D3DMATERIAL8 material;
|
|
ZeroMemory(&material,sizeof(D3DMATERIAL8));
|
|
material.Diffuse.r = 1.0f;
|
|
material.Diffuse.g = 1.0f;
|
|
material.Diffuse.b = 1.0f;
|
|
material.Diffuse.a = 1.0f;
|
|
|
|
material.Ambient.r = 1.0f;
|
|
material.Ambient.g = 1.0f;
|
|
material.Ambient.b = 1.0f;
|
|
material.Ambient.a = 1.0f;
|
|
|
|
material.Emissive.r = 0.0f;
|
|
material.Emissive.g = 0.0f;
|
|
material.Emissive.b = 0.0f;
|
|
material.Emissive.a = 0.0f;
|
|
|
|
material.Specular.r = 1.0f;
|
|
material.Specular.g = 1.0f;
|
|
material.Specular.b = 1.0f;
|
|
material.Specular.a = 1.0f;
|
|
|
|
material.Power = 16.0f;
|
|
|
|
GlobalD3DVars::lpD3DDevice->SetMaterial(&material);
|
|
}
|
|
}
|
|
|
|
bool d3d_inspect_caps()
|
|
{
|
|
GlobalD3DVars::lpD3DDevice->GetDeviceCaps(&GlobalD3DVars::d3d_caps);
|
|
|
|
int not_good = 0;
|
|
|
|
char missing_features[128*1024];
|
|
|
|
strcpy( missing_features, XSTR("Your video card is missing the following features required by FreeSpace:\r\n\r\n",623) );
|
|
|
|
// fog
|
|
if ( !(GlobalD3DVars::d3d_caps.RasterCaps & D3DPRASTERCAPS_FOGVERTEX) &&
|
|
!(GlobalD3DVars::d3d_caps.RasterCaps & D3DPRASTERCAPS_FOGTABLE)){
|
|
|
|
strcat( missing_features, XSTR("Vertex fog or Table fog\r\n", 1499) );
|
|
not_good++;
|
|
}
|
|
|
|
// Texture blending values
|
|
if ( !(GlobalD3DVars::d3d_caps.TextureOpCaps & D3DTEXOPCAPS_MODULATE )) {
|
|
strcat( missing_features, XSTR("Texture blending mode = Modulate\r\n", 624) );
|
|
not_good++;
|
|
}
|
|
|
|
if ( !(GlobalD3DVars::d3d_caps.SrcBlendCaps & (D3DPBLENDCAPS_SRCALPHA|D3DPBLENDCAPS_BOTHSRCALPHA)) ) {
|
|
strcat( missing_features, XSTR("Source blending mode = SRCALPHA or BOTHSRCALPHA\r\n", 625) );
|
|
not_good++;
|
|
}
|
|
|
|
// Dest blending values
|
|
if ( !(GlobalD3DVars::d3d_caps.DestBlendCaps & (D3DPBLENDCAPS_INVSRCALPHA|D3DPBLENDCAPS_BOTHINVSRCALPHA)) ) {
|
|
strcat( missing_features, XSTR("Destination blending mode = INVSRCALPHA or BOTHINVSRCALPHA\r\n",626) );
|
|
not_good++;
|
|
}
|
|
|
|
if ( not_good ) {
|
|
strcpy(Device_init_error, missing_features);
|
|
// return false; I dont think it should fail on this - RT
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
/*
|
|
enum stage_state{
|
|
NONE = -1,
|
|
INITIAL = 0,
|
|
DEFUSE = 1,
|
|
GLOW_MAPPED_DEFUSE = 2,
|
|
NONMAPPED_SPECULAR = 3,
|
|
GLOWMAPPED_NONMAPPED_SPECULAR = 4,
|
|
MAPPED_SPECULAR = 5,
|
|
CELL = 6,
|
|
GLOWMAPPED_CELL = 7,
|
|
ADDITIVE_GLOWMAPPING = 8,
|
|
SINGLE_PASS_SPECMAPPING = 9,
|
|
SINGLE_PASS_GLOW_SPEC_MAPPING = 10,
|
|
BACKGROUND_FOG = 11,
|
|
ENV = 12
|
|
};
|
|
*/
|
|
/*
|
|
void d3d_set_initial_render_state(bool set = true) ;
|
|
void set_stage_for_defuse(bool set = true);
|
|
void set_stage_for_glow_mapped_defuse(bool set = true);
|
|
void set_stage_for_defuse_and_non_mapped_spec(bool set = true);
|
|
void set_stage_for_glow_mapped_defuse_and_non_mapped_spec(bool set = true);
|
|
bool set_stage_for_spec_mapped(bool set = true);
|
|
void set_stage_for_cell_shaded(bool set = true);
|
|
void set_stage_for_cell_glowmapped_shaded(bool set = true);
|
|
void set_stage_for_additive_glowmapped(bool set = true);
|
|
void set_stage_for_background_fog(bool set = true);
|
|
bool set_stage_for_env_mapped(bool set = true);
|
|
void set_stage_for_single_pass_specmapping(int SAME, bool set = true);
|
|
void set_stage_for_single_pass_glow_specmapping(int SAME, bool set = true);
|
|
*/
|
|
|
|
DWORD
|
|
initial_state_block,
|
|
defuse_state_block,
|
|
glow_mapped_defuse_state_block,
|
|
nonmapped_specular_state_block,
|
|
glow_mapped_nonmapped_specular_state_block,
|
|
mapped_specular_state_block,
|
|
cell_state_block,
|
|
glow_mapped_cell_state_block,
|
|
additive_glow_mapping_state_block,
|
|
//single_pass_specmapping_state_block,
|
|
//single_pass_glow_spec_mapping_state_block,
|
|
background_fog_state_block,
|
|
env_state_block,
|
|
cloak_state_block;
|
|
|
|
void d3d_generate_state_blocks(){
|
|
GlobalD3DVars::lpD3DDevice->CreateStateBlock(D3DSBT_PIXELSTATE, &initial_state_block);
|
|
GlobalD3DVars::lpD3DDevice->CreateStateBlock(D3DSBT_PIXELSTATE, &defuse_state_block);
|
|
GlobalD3DVars::lpD3DDevice->CreateStateBlock(D3DSBT_PIXELSTATE, &glow_mapped_defuse_state_block);
|
|
GlobalD3DVars::lpD3DDevice->CreateStateBlock(D3DSBT_PIXELSTATE, &nonmapped_specular_state_block);
|
|
GlobalD3DVars::lpD3DDevice->CreateStateBlock(D3DSBT_PIXELSTATE, &glow_mapped_nonmapped_specular_state_block);
|
|
GlobalD3DVars::lpD3DDevice->CreateStateBlock(D3DSBT_PIXELSTATE, &mapped_specular_state_block);
|
|
GlobalD3DVars::lpD3DDevice->CreateStateBlock(D3DSBT_PIXELSTATE, &cell_state_block);
|
|
GlobalD3DVars::lpD3DDevice->CreateStateBlock(D3DSBT_PIXELSTATE, &glow_mapped_cell_state_block);
|
|
GlobalD3DVars::lpD3DDevice->CreateStateBlock(D3DSBT_PIXELSTATE, &additive_glow_mapping_state_block);
|
|
// CreateStateBlock(D3DSBT_PIXELSTATE, &single_pass_specmapping_state_block);
|
|
// CreateStateBlock(D3DSBT_PIXELSTATE, &single_pass_glow_spec_mapping_state_block);
|
|
GlobalD3DVars::lpD3DDevice->CreateStateBlock(D3DSBT_PIXELSTATE, &background_fog_state_block);
|
|
GlobalD3DVars::lpD3DDevice->CreateStateBlock(D3DSBT_PIXELSTATE, &env_state_block);
|
|
GlobalD3DVars::lpD3DDevice->CreateStateBlock(D3DSBT_PIXELSTATE, &cloak_state_block);
|
|
|
|
GlobalD3DVars::lpD3DDevice->BeginStateBlock();
|
|
d3d_set_initial_render_state(true);
|
|
GlobalD3DVars::lpD3DDevice->EndStateBlock(&initial_state_block);
|
|
|
|
GlobalD3DVars::lpD3DDevice->BeginStateBlock();
|
|
set_stage_for_defuse(true);
|
|
GlobalD3DVars::lpD3DDevice->EndStateBlock(&defuse_state_block);
|
|
|
|
GlobalD3DVars::lpD3DDevice->BeginStateBlock();
|
|
set_stage_for_glow_mapped_defuse(true);
|
|
GlobalD3DVars::lpD3DDevice->EndStateBlock(&glow_mapped_defuse_state_block);
|
|
|
|
GlobalD3DVars::lpD3DDevice->BeginStateBlock();
|
|
set_stage_for_defuse_and_non_mapped_spec(true);
|
|
GlobalD3DVars::lpD3DDevice->EndStateBlock(&nonmapped_specular_state_block);
|
|
|
|
GlobalD3DVars::lpD3DDevice->BeginStateBlock();
|
|
set_stage_for_glow_mapped_defuse_and_non_mapped_spec(true);
|
|
GlobalD3DVars::lpD3DDevice->EndStateBlock(&glow_mapped_nonmapped_specular_state_block);
|
|
|
|
GlobalD3DVars::lpD3DDevice->BeginStateBlock();
|
|
set_stage_for_spec_mapped(true);
|
|
GlobalD3DVars::lpD3DDevice->EndStateBlock(&mapped_specular_state_block);
|
|
|
|
GlobalD3DVars::lpD3DDevice->BeginStateBlock();
|
|
set_stage_for_cell_shaded(true);
|
|
GlobalD3DVars::lpD3DDevice->EndStateBlock(&glow_mapped_cell_state_block);
|
|
|
|
GlobalD3DVars::lpD3DDevice->BeginStateBlock();
|
|
set_stage_for_cell_glowmapped_shaded(true);
|
|
GlobalD3DVars::lpD3DDevice->EndStateBlock(&glow_mapped_cell_state_block);
|
|
|
|
GlobalD3DVars::lpD3DDevice->BeginStateBlock();
|
|
set_stage_for_additive_glowmapped(true);
|
|
GlobalD3DVars::lpD3DDevice->EndStateBlock(&additive_glow_mapping_state_block);
|
|
|
|
GlobalD3DVars::lpD3DDevice->BeginStateBlock();
|
|
set_stage_for_background_fog(true);
|
|
GlobalD3DVars::lpD3DDevice->EndStateBlock(&background_fog_state_block);
|
|
|
|
GlobalD3DVars::lpD3DDevice->BeginStateBlock();
|
|
set_stage_for_env_mapped(true);
|
|
GlobalD3DVars::lpD3DDevice->EndStateBlock(&env_state_block);
|
|
|
|
/* GlobalD3DVars::lpD3DDevice->BeginStateBlock();
|
|
set_stage_for_cloaked(true);
|
|
GlobalD3DVars::lpD3DDevice->EndStateBlock(&cloak_state_block);
|
|
*/
|
|
}
|
|
|
|
void d3d_kill_state_blocks(){
|
|
GlobalD3DVars::lpD3DDevice->DeleteStateBlock( initial_state_block);
|
|
GlobalD3DVars::lpD3DDevice->DeleteStateBlock( defuse_state_block);
|
|
GlobalD3DVars::lpD3DDevice->DeleteStateBlock( glow_mapped_defuse_state_block);
|
|
GlobalD3DVars::lpD3DDevice->DeleteStateBlock( nonmapped_specular_state_block);
|
|
GlobalD3DVars::lpD3DDevice->DeleteStateBlock( glow_mapped_nonmapped_specular_state_block);
|
|
GlobalD3DVars::lpD3DDevice->DeleteStateBlock( mapped_specular_state_block);
|
|
GlobalD3DVars::lpD3DDevice->DeleteStateBlock( cell_state_block);
|
|
GlobalD3DVars::lpD3DDevice->DeleteStateBlock( glow_mapped_cell_state_block);
|
|
GlobalD3DVars::lpD3DDevice->DeleteStateBlock( additive_glow_mapping_state_block);
|
|
// DeleteStateBlock( &single_pass_specmapping_state_block);
|
|
// DeleteStateBlock( &single_pass_glow_spec_mapping_state_block);
|
|
GlobalD3DVars::lpD3DDevice->DeleteStateBlock( background_fog_state_block);
|
|
GlobalD3DVars::lpD3DDevice->DeleteStateBlock( env_state_block);
|
|
GlobalD3DVars::lpD3DDevice->DeleteStateBlock( cloak_state_block);
|
|
}
|
|
|
|
//void d3d_init_environment();
|
|
|
|
bool gr_d3d_init()
|
|
{
|
|
mprintf(( "Initializing Direct3D graphics device at %ix%i with %i-bit color...\n", gr_screen.max_w, gr_screen.max_h, gr_screen.bits_per_pixel ));
|
|
|
|
GlobalD3DVars::lpD3D = Direct3DCreate8( D3D_SDK_VERSION );
|
|
|
|
if( GlobalD3DVars::lpD3D == NULL ) {
|
|
sprintf(Device_init_error, "Please make sure you have DX8.1b installed");
|
|
return false;
|
|
}
|
|
|
|
// ShowCursor(false);
|
|
|
|
if(d3d_init_device() == false) {
|
|
// Func will give its own errors
|
|
return false;
|
|
}
|
|
|
|
if(d3d_inspect_caps() == false) {
|
|
// Func will give its own errors
|
|
return false;
|
|
}
|
|
|
|
if(d3d_init_win32(GlobalD3DVars::d3dpp.BackBufferWidth, GlobalD3DVars::d3dpp.BackBufferHeight) == false) {
|
|
// Func will give its own errors
|
|
return false;
|
|
}
|
|
|
|
if(d3d_init_light() == false) {
|
|
// Func will give its own errors
|
|
sprintf(Device_init_error, "Failed to setup lighting");
|
|
return false;
|
|
}
|
|
|
|
d3d_setup_color();
|
|
|
|
// Tell FreeSpace code that we're using Direct3D.
|
|
GlobalD3DVars::D3D_inited = true;
|
|
|
|
d3d_generate_state_blocks();
|
|
|
|
d3d_tcache_init();
|
|
|
|
d3d_setup_function_pointers();
|
|
d3d_init_vars_from_reg();
|
|
|
|
d3d_reset_render_states();
|
|
d3d_reset_texture_stage_states();
|
|
|
|
d3d_set_initial_render_state();
|
|
|
|
gr_d3d_activate(1);
|
|
|
|
D3DXCreateMatrixStack(0, &world_matrix_stack);
|
|
D3DXCreateMatrixStack(0, &view_matrix_stack);
|
|
D3DXCreateMatrixStack(0, &proj_matrix_stack);
|
|
|
|
d3d_start_frame();
|
|
|
|
Mouse_hidden++;
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
gr_flip();
|
|
gr_flip();
|
|
Mouse_hidden--;
|
|
|
|
mprintf(( " Max texture units: %i\n", GlobalD3DVars::d3d_caps.MaxSimultaneousTextures ));
|
|
mprintf(( " Max texture size: %ix%i\n", GlobalD3DVars::d3d_caps.MaxTextureWidth, GlobalD3DVars::d3d_caps.MaxTextureHeight ));
|
|
mprintf(( " Can use compressed textures: %s\n", Use_compressed_textures ? NOX("YES") : NOX("NO") ));
|
|
mprintf(( " Texture compression available: %s\n", Texture_compression_available ? NOX("YES") : NOX("NO") ));
|
|
|
|
TIMERBAR_SET_DRAW_FUNC(d3d_render_timer_bar);
|
|
|
|
// d3d_init_environment();
|
|
|
|
mprintf(("... Direct3D init is complete!\n"));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
void gr_d3d_cleanup()
|
|
{
|
|
if (!GlobalD3DVars::D3D_inited) return;
|
|
|
|
d3d_tcache_cleanup();
|
|
|
|
// Ensures gamma options dont return to the desktop
|
|
gr_d3d_set_gamma(1.0);
|
|
|
|
// release surfaces
|
|
d3d_release_rendering_objects();
|
|
|
|
if ( GlobalD3DVars::lpD3D ) {
|
|
GlobalD3DVars::lpD3D->Release();
|
|
GlobalD3DVars::lpD3D = NULL;
|
|
}
|
|
|
|
// restore windows clipping rectangle
|
|
ClipCursor(NULL);
|
|
GlobalD3DVars::D3D_inited = 0;
|
|
}
|
|
|
|
#endif // !NO_DIRECT3D
|