windows-nt/Source/XPSP1/NT/windows/appcompat/shims/external/emulateopengl_opengl32.cpp
2020-09-26 16:20:57 +08:00

5860 lines
198 KiB
C++

#include "precomp.h"
#pragma warning(disable : 4273)
#define D3D_OVERLOADS
#include <math.h>
#include <stdio.h>
#include "EmulateOpenGL_opengl32.hpp"
#define HOOK_WINDOW_PROC 0
#define GETPARMSFORDEBUG 0
#define DODPFS 0
void APIENTRY glEnd (void);
void APIENTRY glBegin (GLenum mode);
BOOL APIENTRY wglSwapIntervalEXT(GLint interval);
#define PI 3.1415926535897932384626433832795
Globals * g_OpenGLValues = NULL;
// The BOOL below comes from the shim command line. It can't be part of the Globals struct above
// because wglCreateContext memsets g_OpenGLValues to 0, but this is after the shim command line
// has been processed.
BOOL g_bDoTexelAlignmentHack = FALSE;
#if GETPARMSFORDEBUG || DODPFS
// converts doubles to ascii for debug output. it only shows 6 place precision.
void ftoa( double d, char *buf )
{
long l, i, j;
char *s, *n;
if( d < 0.0 )
{
d = -d;
n = "-";
}
else
{
n = "";
}
i = (long)d;
j = (long)((d - (double)i) * 100000);
if( j < 10 )
s = "00000";
else if( j < 100 )
s = "0000";
else if( j < 1000 )
s = "000";
else if( j < 10000 )
s = "00";
else if( j < 100000 )
s = "0";
else s = "";
sprintf( buf, "%s%d.%s%d", n, i, s, j );
}
#endif
inline void VertexBufferFilled()
{
if(g_OpenGLValues->m_nfv + g_OpenGLValues->m_vcnt >= (VBUFSIZE - MAXVERTSPERPRIM))
{
if(g_OpenGLValues->m_prim == GL_TRIANGLES)
{
if(g_OpenGLValues->m_vcnt % 3 == 0)
{
glEnd();
glBegin(GL_TRIANGLES);
}
}
else if(g_OpenGLValues->m_prim == GL_QUADS)
{
if(g_OpenGLValues->m_vcnt % 4 == 0)
{
glEnd();
glBegin(GL_QUADS);
}
}
else if(g_OpenGLValues->m_prim == GL_LINES)
{
if(g_OpenGLValues->m_vcnt % 2 == 0)
{
glEnd();
glBegin(GL_LINES);
}
}
}
}
inline void QuakeSetVertexShader(DWORD vs)
{
if(g_OpenGLValues->m_curshader != vs)
{
g_OpenGLValues->m_d3ddev->SetVertexShader(vs);
g_OpenGLValues->m_curshader = vs;
}
}
inline void QuakeSetStreamSource(DWORD i, IDirect3DVertexBuffer8 *pBuf, DWORD stride)
{
if(g_OpenGLValues->m_pStreams[i] != pBuf || g_OpenGLValues->m_pStrides[i] != stride)
{
g_OpenGLValues->m_d3ddev->SetStreamSource(i, pBuf, stride);
g_OpenGLValues->m_pStreams[i] = pBuf;
g_OpenGLValues->m_pStrides[i] = stride;
}
}
inline void MultiplyMatrix(D3DTRANSFORMSTATETYPE xfrm, const D3DMATRIX &min)
{
D3DMATRIX &mout = g_OpenGLValues->m_xfrm[xfrm];
for(unsigned i = 0; i < 4; ++i)
{
float a = mout.m[0][i];
float b = mout.m[1][i];
float c = mout.m[2][i];
float d = mout.m[3][i];
for(unsigned j = 0; j < 4; ++j)
{
mout.m[j][i] = min.m[j][0] * a + min.m[j][1] * b + min.m[j][2] * c + min.m[j][3] * d;
}
}
}
inline void MEMCPY(VOID *dst, const VOID *src, DWORD sz)
{
#ifdef _X86_
if((sz & 0x3) == 0)
{
_asm
{
mov ecx, sz;
mov esi, src;
mov edi, dst;
cld;
shr ecx, 2;
lp1: movsd;
dec ecx;
jnz lp1;
}
}
else
#endif
{
memcpy(dst, src, sz);
}
}
inline void Clamp(float *v)
{
if(*v < 0.f)
{
*v = 0.f;
}
else if(*v > 1.f)
{
*v = 1.f;
}
}
inline void Clamp(double *v)
{
if(*v < 0.)
{
*v = 0.;
}
else if(*v > 1.)
{
*v = 1.;
}
}
void QuakeSetTransform(D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX *m)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "QuakeSetTransform: 0x%X 0x%X", State, m );
#endif
static D3DMATRIX unity = {1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f};
if(State == D3DTS_PROJECTION)
{
D3DMATRIX f = *m;
f._13 = (m->_13 + m->_14) * 0.5f;
f._23 = (m->_23 + m->_24) * 0.5f;
f._33 = (m->_33 + m->_34) * 0.5f;
f._43 = (m->_43 + m->_44) * 0.5f;
if(g_OpenGLValues->m_scissoring)
{
FLOAT dvClipX, dvClipY, dvClipWidth, dvClipHeight;
RECT scirect, vwprect, xrect;
scirect.left = g_OpenGLValues->m_scix;
scirect.top = g_OpenGLValues->m_sciy;
scirect.right = g_OpenGLValues->m_scix + g_OpenGLValues->m_sciw;
scirect.bottom = g_OpenGLValues->m_sciy + g_OpenGLValues->m_scih;
vwprect.left = g_OpenGLValues->m_vwx;
vwprect.top = g_OpenGLValues->m_vwy;
vwprect.right = g_OpenGLValues->m_vwx + g_OpenGLValues->m_vww;
vwprect.bottom = g_OpenGLValues->m_vwy + g_OpenGLValues->m_vwh;
if(IntersectRect(&xrect, &scirect, &vwprect))
{
if(EqualRect(&xrect, &vwprect)) // Check whether viewport is completely within scissor rect
{
dvClipX = -1.f;
dvClipY = 1.f;
dvClipWidth = 2.f;
dvClipHeight = 2.f;
}
else
{
// We need to use xrect rather than scirect (ie clip scissor rect to viewport)
// and transform the clipped scissor rect into viewport relative coordinates
// to correctly compute the clip stuff
GLint scix = xrect.left - g_OpenGLValues->m_vwx;
GLint sciy = xrect.top - g_OpenGLValues->m_vwy;
GLsizei sciw = xrect.right - xrect.left;
GLsizei scih = xrect.bottom - xrect.top;
dvClipX = (2.f * scix) / g_OpenGLValues->m_vww - 1.0f;
dvClipY = (2.f * (sciy + scih)) / g_OpenGLValues->m_vwh - 1.0f;
dvClipWidth = (2.f * sciw) / g_OpenGLValues->m_vww;
dvClipHeight = (2.f * scih) / g_OpenGLValues->m_vwh;
}
}
else
{
#if DODPFS
OutputDebugStringA("Wrapper: non-intersecting scissor and viewport rects not implemented\n" );
#endif
return;
}
D3DMATRIX c;
// to prevent divide by zero from possibly happening (check bug #259251 in Whistler database)
if(dvClipWidth == 0.f)
dvClipWidth = 1.f;
if(dvClipHeight == 0.f)
dvClipHeight = 1.f;
c._11 = 2.f / dvClipWidth;
c._21 = 0.f;
c._31 = 0.f;
c._41 = -1.f - 2.f * (dvClipX / dvClipWidth);
c._12 = 0.f;
c._22 = 2.f / dvClipHeight;
c._32 = 0.f;
c._42 = 1.f - 2.f * (dvClipY / dvClipHeight);
c._13 = 0.f;
c._23 = 0.f;
c._33 = 1.f;
c._43 = 0.f;
c._14 = 0.f;
c._24 = 0.f;
c._34 = 0.f;
c._44 = 1.f;
D3DMATRIX t = g_OpenGLValues->m_xfrm[D3DTS_PROJECTION];
g_OpenGLValues->m_xfrm[D3DTS_PROJECTION] = c;
#if GETPARMSFORDEBUG
char buf1[40], buf2[40], buf3[40], buf4[40];
ftoa( dvClipX, buf1 );
ftoa( dvClipY, buf2 );
ftoa( dvClipWidth, buf3 );
ftoa( dvClipHeight, buf4 );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "QuakeSetTransform: DVCLIP: %s %s %s %s SCIRECT: %d %d %d %d VWPRECT: %d %d %d %d XRECT: %d %d %d %d", buf1, buf2, buf3, buf4, scirect.left, scirect.top, scirect.right, scirect.bottom, vwprect.left, vwprect.top, vwprect.right, vwprect.bottom, xrect.left, xrect.top, xrect.right, xrect.bottom );
#endif
MultiplyMatrix(D3DTS_PROJECTION, f);
f = g_OpenGLValues->m_xfrm[D3DTS_PROJECTION];
g_OpenGLValues->m_xfrm[D3DTS_PROJECTION] = t;
}
if( g_bDoTexelAlignmentHack )
{
// Translate all geometry by (-0.5 pixels in x, -0.5 pixels in y) along the screen/viewport plane.
// This helps force texels that were authored to be sampled pixel-aligned on OpenGL to be pixel-aligned on D3D.
float x = g_OpenGLValues->m_vport.Width ? (-1.f / g_OpenGLValues->m_vport.Width) : 0.0f;
float y = g_OpenGLValues->m_vport.Height ? (1.0f / g_OpenGLValues->m_vport.Height) : 0.0f;
f._11 = f._11 + f._14*x;
f._12 = f._12 + f._14*y;
f._21 = f._21 + f._24*x;
f._22 = f._22 + f._24*y;
f._31 = f._31 + f._34*x;
f._32 = f._32 + f._34*y;
f._41 = f._41 + f._44*x;
f._42 = f._42 + f._44*y;
}
g_OpenGLValues->m_d3ddev->SetTransform(State, &f);
}
else if(State == D3DTS_TEXTURE0 || State == D3DTS_TEXTURE1)
{
D3DMATRIX f;
f._11 = m->_11;
f._12 = m->_12;
f._13 = m->_14;
f._14 = 0.f;
f._21 = m->_21;
f._22 = m->_22;
f._23 = m->_24;
f._24 = 0.f;
f._31 = m->_41;
f._32 = m->_42;
f._33 = m->_44;
f._34 = 0.f;
f._41 = 0.f;
f._42 = 0.f;
f._43 = 0.f;
f._44 = 0.f;
g_OpenGLValues->m_d3ddev->SetTransform(State, &f);
if(memcmp(&unity, m, sizeof(D3DMATRIX)) != 0)
{
g_OpenGLValues->m_d3ddev->SetTextureStageState((DWORD)(State - D3DTS_TEXTURE0), D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED);
}
else
{
g_OpenGLValues->m_d3ddev->SetTextureStageState((DWORD)(State - D3DTS_TEXTURE0), D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE);
}
}
else
{
g_OpenGLValues->m_d3ddev->SetTransform(State, m);
}
}
void QuakeUpdateViewport()
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "QuakeUpdateViewport" );
#endif
if(g_OpenGLValues->m_scissoring)
{
RECT scirect, vwprect, xrect;
scirect.left = g_OpenGLValues->m_scix;
scirect.top = g_OpenGLValues->m_sciy;
scirect.right = g_OpenGLValues->m_scix + g_OpenGLValues->m_sciw;
scirect.bottom = g_OpenGLValues->m_sciy + g_OpenGLValues->m_scih;
vwprect.left = g_OpenGLValues->m_vwx;
vwprect.top = g_OpenGLValues->m_vwy;
vwprect.right = g_OpenGLValues->m_vwx + g_OpenGLValues->m_vww;
vwprect.bottom = g_OpenGLValues->m_vwy + g_OpenGLValues->m_vwh;
if(IntersectRect(&xrect, &scirect, &vwprect))
{
if(EqualRect(&xrect, &vwprect)) // Check whether viewport is completely within scissor rect
{
g_OpenGLValues->m_vport.X = g_OpenGLValues->m_vwx;
g_OpenGLValues->m_vport.Y = g_OpenGLValues->m_winHeight - (g_OpenGLValues->m_vwy + g_OpenGLValues->m_vwh);
g_OpenGLValues->m_vport.Width = g_OpenGLValues->m_vww;
g_OpenGLValues->m_vport.Height = g_OpenGLValues->m_vwh;
QuakeSetTransform(D3DTS_PROJECTION, &g_OpenGLValues->m_xfrm[D3DTS_PROJECTION]);
}
else
{
// We need to use xrect rather than scirect (ie clip scissor rect to viewport)
g_OpenGLValues->m_vport.X = xrect.left;
g_OpenGLValues->m_vport.Y = g_OpenGLValues->m_winHeight - xrect.bottom;
g_OpenGLValues->m_vport.Width = xrect.right - xrect.left;
g_OpenGLValues->m_vport.Height = xrect.bottom - xrect.top;
QuakeSetTransform(D3DTS_PROJECTION, &g_OpenGLValues->m_xfrm[D3DTS_PROJECTION]);
}
}
else
{
#if DODPFS
OutputDebugStringA("Wrapper: non-intersecting scissor and viewport rects not implemented\n");
#endif
return;
}
}
else
{
g_OpenGLValues->m_vport.X = g_OpenGLValues->m_vwx;
g_OpenGLValues->m_vport.Y = g_OpenGLValues->m_winHeight - (g_OpenGLValues->m_vwy + g_OpenGLValues->m_vwh);
g_OpenGLValues->m_vport.Width = g_OpenGLValues->m_vww;
g_OpenGLValues->m_vport.Height = g_OpenGLValues->m_vwh;
}
if(g_OpenGLValues->m_polyoffset && g_OpenGLValues->m_vport.MaxZ != 0.f)
{
D3DVIEWPORT8 vport(g_OpenGLValues->m_vport);
vport.MaxZ -= .001f;
#if GETPARMSFORDEBUG
char buf1[40], buf2[40];
ftoa( vport.MinZ, buf1 );
ftoa( vport.MaxZ, buf2 );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "QuakeUpdateViewport: vport=%d %d %d %d %s %s", vport.X, vport.Y, vport.Width, vport.Height, buf1, buf2 );
#endif
g_OpenGLValues->m_d3ddev->SetViewport(&vport);
}
else
{
#if GETPARMSFORDEBUG
char buf1[40], buf2[40];
ftoa( g_OpenGLValues->m_vport.MinZ, buf1 );
ftoa( g_OpenGLValues->m_vport.MaxZ, buf2 );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "QuakeUpdateViewport g_OpenGLValues->m_vport=%d %d %d %d %s %s", g_OpenGLValues->m_vport.X, g_OpenGLValues->m_vport.Y, g_OpenGLValues->m_vport.Width, g_OpenGLValues->m_vport.Height, buf1, buf2 );
#endif
g_OpenGLValues->m_d3ddev->SetViewport(&g_OpenGLValues->m_vport);
}
g_OpenGLValues->m_updvwp = FALSE;
}
void QuakeUpdateLights()
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "QuakeUpdateLights" );
#endif
for(unsigned i = 0; i < 8; ++i)
{
if(g_OpenGLValues->m_lightdirty & (1 << i))
{
D3DLIGHT8 light = g_OpenGLValues->m_light[i];
if(g_OpenGLValues->m_lightPositionW[i] == 0.f)
{
if(light.Phi == 180.f)
{
light.Type = D3DLIGHT_DIRECTIONAL;
}
else
{
light.Type = D3DLIGHT_SPOT;
light.Attenuation0 = 1.f;
light.Attenuation1 = 0.f;
light.Attenuation2 = 0.f;
}
}
else
{
if(light.Phi == 180.f)
{
light.Type = D3DLIGHT_POINT;
}
else
{
light.Type = D3DLIGHT_SPOT;
}
}
light.Phi *= float(PI / 90.);
g_OpenGLValues->m_d3ddev->SetLight(i, &light);
}
}
g_OpenGLValues->m_lightdirty = 0;
}
void QuakeSetTexturingState()
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "QuakeSetTexturingState" );
#endif
if(g_OpenGLValues->m_lightdirty != 0)
QuakeUpdateLights();
if(g_OpenGLValues->m_updvwp)
QuakeUpdateViewport();
if(g_OpenGLValues->m_texturing == TRUE) {
if(g_OpenGLValues->m_texHandleValid == FALSE) {
TexInfo &ti = g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[0]];
if(ti.m_dwStage != 0)
{
g_OpenGLValues->m_d3ddev->DeleteStateBlock(ti.m_block);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ADDRESSU,ti.m_addu);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ADDRESSV,ti.m_addv);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_MAGFILTER,ti.m_magmode);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_MINFILTER,ti.m_minmode);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_MIPFILTER,ti.m_mipmode);
g_OpenGLValues->m_d3ddev->SetTexture(0, ti.m_ddsurf);
g_OpenGLValues->m_d3ddev->EndStateBlock(&ti.m_block);
ti.m_dwStage = 0;
ti.m_capture = FALSE;
}
if(ti.m_capture)
{
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ADDRESSU,ti.m_addu);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ADDRESSV,ti.m_addv);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_MAGFILTER,ti.m_magmode);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_MINFILTER,ti.m_minmode);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_MIPFILTER,ti.m_mipmode);
g_OpenGLValues->m_d3ddev->SetTexture(0, ti.m_ddsurf);
g_OpenGLValues->m_d3ddev->CaptureStateBlock(ti.m_block);
ti.m_capture = FALSE;
}
else
{
g_OpenGLValues->m_d3ddev->ApplyStateBlock(ti.m_block);
}
switch(g_OpenGLValues->m_blendmode[0]) {
case GL_REPLACE:
switch(ti.m_internalformat) {
case 1:
case GL_LUMINANCE:
case GL_LUMINANCE8:
case 3:
case GL_RGB:
case GL_RGB5:
case GL_RGB8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[0][0]);
break;
case 4:
case GL_RGBA:
case GL_RGBA4:
case GL_RGBA8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[0][1]);
break;
case GL_ALPHA:
case GL_ALPHA8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[0][8]);
break;
}
break;
case GL_MODULATE:
switch(ti.m_internalformat) {
case 1:
case GL_LUMINANCE:
case GL_LUMINANCE8:
case 3:
case GL_RGB:
case GL_RGB5:
case GL_RGB8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[0][2]);
break;
case 4:
case GL_RGBA:
case GL_RGBA4:
case GL_RGBA8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[0][3]);
break;
case GL_ALPHA:
case GL_ALPHA8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[0][9]);
break;
}
break;
case GL_DECAL:
switch(ti.m_internalformat) {
case 3:
case GL_RGB:
case GL_RGB5:
case GL_RGB8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[0][4]);
break;
case 4:
case GL_RGBA:
case GL_RGBA4:
case GL_RGBA8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[0][5]);
break;
}
break;
case GL_BLEND:
switch(ti.m_internalformat) {
case 1:
case GL_LUMINANCE:
case GL_LUMINANCE8:
case 3:
case GL_RGB:
case GL_RGB5:
case GL_RGB8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[0][6]);
break;
case 4:
case GL_RGBA:
case GL_RGBA4:
case GL_RGBA8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[0][7]);
break;
case GL_ALPHA:
case GL_ALPHA8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[0][9]);
break;
}
break;
}
if(g_OpenGLValues->m_mtex != FALSE) {
TexInfo &ti2 = g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[1]];
if(ti2.m_dwStage != 1)
{
g_OpenGLValues->m_d3ddev->DeleteStateBlock(ti2.m_block);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ADDRESSU,ti2.m_addu);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ADDRESSV,ti2.m_addv);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_MAGFILTER,ti2.m_magmode);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_MINFILTER,ti2.m_minmode);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_MIPFILTER,ti2.m_mipmode);
g_OpenGLValues->m_d3ddev->SetTexture(1, ti2.m_ddsurf);
g_OpenGLValues->m_d3ddev->EndStateBlock(&ti2.m_block);
ti2.m_dwStage = 1;
ti2.m_capture = FALSE;
}
if(ti2.m_capture)
{
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ADDRESSU,ti2.m_addu);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ADDRESSV,ti2.m_addv);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_MAGFILTER,ti2.m_magmode);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_MINFILTER,ti2.m_minmode);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_MIPFILTER,ti2.m_mipmode);
g_OpenGLValues->m_d3ddev->SetTexture(1, ti2.m_ddsurf);
g_OpenGLValues->m_d3ddev->CaptureStateBlock(ti2.m_block);
ti2.m_capture = FALSE;
}
else
{
g_OpenGLValues->m_d3ddev->ApplyStateBlock(ti2.m_block);
}
switch(g_OpenGLValues->m_blendmode[1]) {
case GL_REPLACE:
switch(ti2.m_internalformat) {
case 1:
case GL_LUMINANCE:
case GL_LUMINANCE8:
case 3:
case GL_RGB:
case GL_RGB5:
case GL_RGB8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[1][0]);
break;
case 4:
case GL_RGBA:
case GL_RGBA4:
case GL_RGBA8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[1][1]);
break;
case GL_ALPHA:
case GL_ALPHA8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[1][8]);
break;
}
break;
case GL_MODULATE:
switch(ti2.m_internalformat) {
case 1:
case GL_LUMINANCE:
case GL_LUMINANCE8:
case 3:
case GL_RGB:
case GL_RGB5:
case GL_RGB8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[1][2]);
break;
case 4:
case GL_RGBA:
case GL_RGBA4:
case GL_RGBA8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[1][3]);
break;
case GL_ALPHA:
case GL_ALPHA8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[1][9]);
break;
}
break;
case GL_DECAL:
switch(ti2.m_internalformat) {
case 3:
case GL_RGB:
case GL_RGB5:
case GL_RGB8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[1][4]);
break;
case 4:
case GL_RGBA:
case GL_RGBA4:
case GL_RGBA8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[1][5]);
break;
}
break;
case GL_BLEND:
switch(ti2.m_internalformat) {
case 1:
case GL_LUMINANCE:
case GL_LUMINANCE8:
case 3:
case GL_RGB:
case GL_RGB5:
case GL_RGB8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[1][6]);
break;
case 4:
case GL_RGBA:
case GL_RGBA4:
case GL_RGBA8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[1][7]);
break;
case GL_ALPHA:
case GL_ALPHA8:
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_shaders[1][9]);
break;
}
break;
}
}
g_OpenGLValues->m_texHandleValid = TRUE;
}
}
}
void RawToCanon(DWORD dwFormat, DWORD dwInternalFormat, DWORD dwWidth, DWORD dwHeight, const void *lpPixels, DWORD *lpdwCanon)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "RawToCanon: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X", dwFormat, dwInternalFormat, dwWidth, dwHeight, lpPixels, lpdwCanon );
#endif
if(dwFormat == GL_RGBA)
{
switch(dwInternalFormat) {
case 1:
case GL_LUMINANCE:
case GL_LUMINANCE8:
case 3:
case 4:
case GL_RGB:
case GL_RGBA:
case GL_RGB5:
case GL_RGB8:
case GL_RGBA4:
case GL_RGBA8:
case GL_ALPHA:
case GL_ALPHA8:
MEMCPY(lpdwCanon, lpPixels, dwWidth * dwHeight * sizeof(DWORD));
break;
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper: (RawToCanon:GL_RGBA) InternalFormat not implemented (dwInternalFormat:0x%X)\n", dwInternalFormat );
OutputDebugStringA( junk );
#endif
}
}
else if(dwFormat == GL_RGB)
{
switch(dwInternalFormat) {
case 1:
case GL_LUMINANCE:
case GL_LUMINANCE8:
case 3:
case 4:
case GL_RGB:
case GL_RGBA:
case GL_RGB5:
case GL_RGB8:
case GL_RGBA4:
case GL_RGBA8:
{
int i, j = dwWidth * dwHeight;
unsigned char *pixels = (unsigned char*)lpPixels;
for(i = 0; i < j; ++i) {
lpdwCanon[i] = (unsigned(pixels[2]) << 16) | (unsigned(pixels[1]) << 8) | unsigned(pixels[0]);
pixels += 3;
}
}
break;
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper: (RawToCanon:GL_RGB) InternalFormat not implemented (dwInternalFormat:0x%X)\n", dwInternalFormat );
OutputDebugStringA( junk );
#endif
}
}
else if(dwFormat == GL_LUMINANCE)
{
switch(dwInternalFormat) {
case 1:
case GL_LUMINANCE:
case GL_LUMINANCE8:
{
int i, j = dwWidth * dwHeight;
for(i = 0; i < j; ++i) {
DWORD t = ((UCHAR*)lpPixels)[i];
lpdwCanon[i] = (t << 24) | (t << 16) | (t << 8) | t;
}
}
break;
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper: (RawToCanon:GL_LUMINANCE) InternalFormat not implemented (dwInternalFormat:0x%X)\n", dwInternalFormat );
OutputDebugStringA( junk );
#endif
}
}
else if(dwFormat == GL_ALPHA || dwFormat == GL_ALPHA8)
{
switch(dwInternalFormat) {
case GL_ALPHA:
case GL_ALPHA8:
{
int i, j = dwWidth * dwHeight;
for(i = 0; i < j; ++i) {
DWORD t = ((UCHAR*)lpPixels)[i];
lpdwCanon[i] = (t << 24) | (t << 16) | (t << 8) | t;
}
}
break;
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper: (RawToCanon:GL_ALPHA) InternalFormat not implemented (dwInternalFormat:0x%X)\n", dwInternalFormat );
OutputDebugStringA( junk );
#endif
}
}
#if DODPFS
else
{
char junk[256];
sprintf( junk, "Wrapper: Format not implemented (dwFormat:0x%X dwInternalFormat:0x%X)\n", dwFormat, dwInternalFormat );
OutputDebugStringA( junk );
}
#endif
}
void Resize(DWORD dwWidth, DWORD dwHeight, const DWORD *lpdwCanon,
DWORD dwNewWidth, DWORD dwNewHeight, DWORD *lpdwNewCanon)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "Resize: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X", dwWidth, dwHeight, lpdwCanon, dwNewWidth, dwNewHeight, lpdwNewCanon );
#endif
DWORD i, j;
double rx = (double)dwWidth / (double)dwNewWidth;
double ry = (double)dwHeight / (double)dwNewHeight;
for(i = 0; i < dwNewHeight; ++i)
for(j = 0; j < dwNewWidth; ++j)
lpdwNewCanon[i * dwNewWidth + j] = lpdwCanon[((DWORD)(i * ry)) * dwWidth + (DWORD)(j * rx)];
}
void CanonTo565(LPRECT lprect, const DWORD *lpdwCanon, D3DLOCKED_RECT* lpddsd)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "CanonTo565: 0x%X 0x%X 0x%X", lprect, lpdwCanon, lpddsd );
#endif
LONG i, j, k, l;
USHORT *lpPixels = (USHORT*)lpddsd->pBits;
for(k = lprect->top, i = 0; k < lprect->bottom; ++k, lpPixels = (USHORT*)((UCHAR*)lpPixels + lpddsd->Pitch) )
{
for (j = lprect->left, l = 0; j < lprect->right; ++j, ++i, ++l)
{
lpPixels[l] = (USHORT)(((lpdwCanon[i] & 0xF8) << 8) | ((lpdwCanon[i] & 0xFC00) >> 5) | ((lpdwCanon[i] & 0xF80000) >> 19));
}
}
}
void CanonTo555(LPRECT lprect, const DWORD *lpdwCanon, D3DLOCKED_RECT* lpddsd)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "CanonTo555: 0x%X 0x%X 0x%X", lprect, lpdwCanon, lpddsd );
#endif
LONG i, j, k, l;
USHORT *lpPixels = (USHORT*)lpddsd->pBits;
for(k = lprect->top, i = 0; k < lprect->bottom; ++k, lpPixels = (USHORT*)((UCHAR*)lpPixels + lpddsd->Pitch) )
{
for (j = lprect->left, l = 0; j < lprect->right; ++j, ++i, ++l)
{
lpPixels[l] = (USHORT)(((lpdwCanon[i] & 0xF8) << 7) | ((lpdwCanon[i] & 0xF800) >> 6) | ((lpdwCanon[i] & 0xF80000) >> 19));
}
}
}
void CanonTo4444(LPRECT lprect, const DWORD *lpdwCanon, D3DLOCKED_RECT* lpddsd)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "CanonTo4444: 0x%X 0x%X 0x%X", lprect, lpdwCanon, lpddsd );
#endif
LONG i, j, k, l;
USHORT *lpPixels = (USHORT*)lpddsd->pBits;
for(k = lprect->top, i = 0; k < lprect->bottom; ++k, lpPixels = (USHORT*)((UCHAR*)lpPixels + lpddsd->Pitch) )
{
for (j = lprect->left, l = 0; j < lprect->right; ++j, ++i, ++l)
{
lpPixels[l] = (USHORT)(((lpdwCanon[i] & 0xF0) << 4) | ((lpdwCanon[i] & 0xF000) >> 8) | ((lpdwCanon[i] & 0xF00000) >> 20) | ((lpdwCanon[i] & 0xF0000000) >> 16));
}
}
}
void CanonTo8888(LPRECT lprect, const DWORD *lpdwCanon, D3DLOCKED_RECT* lpddsd)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "CanonTo8888: 0x%X 0x%X 0x%X", lprect, lpdwCanon, lpddsd );
#endif
LONG i, j, k, l;
DWORD *lpPixels = (DWORD*)lpddsd->pBits;
for(k = lprect->top, i = 0; k < lprect->bottom; ++k, lpPixels = (DWORD*)((UCHAR*)lpPixels + lpddsd->Pitch) )
{
for (j = lprect->left, l = 0; j < lprect->right; ++j, ++i, ++l)
{
lpPixels[l] = ((lpdwCanon[i] & 0xFF00FF00) | ((lpdwCanon[i] & 0xFF) << 16) | ((lpdwCanon[i] & 0xFF0000) >> 16));
}
}
}
void CanonTo8(LPRECT lprect, const DWORD *lpdwCanon, D3DLOCKED_RECT* lpddsd)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "CanonTo8: 0x%X 0x%X 0x%X", lprect, lpdwCanon, lpddsd );
#endif
LONG i, j, k, l;
UCHAR *lpPixels = (UCHAR*)lpddsd->pBits;
for(k = lprect->top, i = 0; k < lprect->bottom; ++k, lpPixels = (UCHAR*)lpPixels + lpddsd->Pitch )
{
for (j = lprect->left, l = 0; j < lprect->right; ++j, ++i, ++l)
{
lpPixels[l] = (UCHAR)(lpdwCanon[i] >> 24);
}
}
}
void LoadSurface(LPDIRECT3DSURFACE8 lpDDS, DWORD dwFormat, DWORD dwInternalFormat,
DWORD dwWidth, DWORD dwHeight, DWORD dwNewWidth, DWORD dwNewHeight,
const void *pixels)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "LoadSurface: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X", lpDDS, dwFormat, dwInternalFormat, dwWidth, dwHeight, dwNewWidth, dwNewHeight, pixels );
#endif
D3DLOCKED_RECT ddsd;
HRESULT ddrval;
DWORD *lpdwCanon, *lpdwNewCanon;
RECT rect;
/*
* Convert the GL texture into a canonical format (8888),
* so that we can cleanly do image ops (such as resize) without
* having to worry about the bit format.
*/
lpdwCanon = (DWORD*)malloc(dwWidth * dwHeight * sizeof(DWORD));
if(lpdwCanon != NULL)
{
RawToCanon(dwFormat, dwInternalFormat, dwWidth, dwHeight, pixels, lpdwCanon);
/* Now resize the canon image */
if(dwWidth != dwNewWidth || dwHeight != dwNewHeight) {
lpdwNewCanon = (DWORD*)malloc(dwNewWidth * dwNewHeight * sizeof(DWORD));
if(lpdwNewCanon != NULL)
{
Resize(dwWidth, dwHeight, lpdwCanon, dwNewWidth, dwNewHeight, lpdwNewCanon);
free(lpdwCanon);
}
else
{
lpdwNewCanon = lpdwCanon;
}
}
else
lpdwNewCanon = lpdwCanon;
/*
* Lock the surface so it can be filled with the texture
*/
ddrval = lpDDS->LockRect(&ddsd, NULL, D3DLOCK_NOSYSLOCK);
if (FAILED(ddrval)) {
#if DODPFS
char junk[256];
sprintf( junk, "Lock failed while loading surface (0x%X)\n", ddrval );
OutputDebugStringA( junk );
#endif
free(lpdwNewCanon);
return;
}
D3DSURFACE_DESC sd;
lpDDS->GetDesc(&sd);
SetRect(&rect, 0, 0, sd.Width, sd.Height);
/* Copy the texture into the surface */
if(sd.Format == D3DFMT_L8) {
CanonTo8(&rect, lpdwNewCanon, &ddsd);
}
else if(sd.Format == D3DFMT_A8) {
CanonTo8(&rect, lpdwNewCanon, &ddsd);
}
else if(sd.Format == D3DFMT_A4R4G4B4) {
CanonTo4444(&rect, lpdwNewCanon, &ddsd);
}
else if(sd.Format == D3DFMT_R5G6B5) {
CanonTo565(&rect, lpdwNewCanon, &ddsd);
}
else if(sd.Format == D3DFMT_X1R5G5B5) {
CanonTo555(&rect, lpdwNewCanon, &ddsd);
}
else {
CanonTo8888(&rect, lpdwNewCanon, &ddsd);
}
free(lpdwNewCanon);
/*
* unlock the surface
*/
lpDDS->UnlockRect();
}
return;
}
HRESULT LoadSubSurface(LPDIRECT3DSURFACE8 lpDDS, DWORD dwFormat,
DWORD dwInternalFormat, DWORD dwWidth, DWORD dwHeight,
const void *pixels, LPRECT lpsubimage)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "LoadSubSurface: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X", lpDDS, dwFormat, dwInternalFormat, dwWidth, dwHeight, pixels, lpsubimage );
#endif
D3DLOCKED_RECT ddsd;
HRESULT ddrval;
DWORD *lpdwCanon, *lpdwNewCanon;
DWORD dwNewWidth=lpsubimage->right-lpsubimage->left;
DWORD dwNewHeight=lpsubimage->bottom-lpsubimage->top;
/*
* Lock the surface so it can be filled with the texture
*/
ddrval = lpDDS->LockRect(&ddsd, lpsubimage, D3DLOCK_NOSYSLOCK);
if (FAILED(ddrval)) {
#if DODPFS
char junk[256];
sprintf( junk, "Lock failed while loading surface (0x%X)\n", ddrval );
OutputDebugStringA( junk );
#endif
return ddrval;
}
D3DSURFACE_DESC sd;
lpDDS->GetDesc(&sd);
if((dwInternalFormat == 3 || dwInternalFormat == GL_RGB || dwInternalFormat == GL_RGB5) && sd.Format == D3DFMT_R5G6B5 &&
dwWidth == dwNewWidth && dwHeight == dwNewHeight) {
CanonTo565(lpsubimage,(const unsigned long*)pixels,&ddsd);
}
else if((dwInternalFormat == 3 || dwInternalFormat == GL_RGB || dwInternalFormat == GL_RGB5) && sd.Format == D3DFMT_X1R5G5B5 &&
dwWidth == dwNewWidth && dwHeight == dwNewHeight) {
CanonTo555(lpsubimage,(const unsigned long*)pixels,&ddsd);
}
else if((dwInternalFormat == GL_RGB8 || dwInternalFormat == GL_RGBA || dwInternalFormat == GL_RGBA8) && (sd.Format == D3DFMT_X8R8G8B8 || sd.Format == D3DFMT_A8R8G8B8) &&
dwWidth == dwNewWidth && dwHeight == dwNewHeight) {
CanonTo8888(lpsubimage,(const unsigned long*)pixels,&ddsd);
}
else {
/*
* Convert the GL texture into a canonical format (8888),
* so that we can cleanly do image ops (such as resize) without
* having to worry about the bit format.
*/
lpdwCanon = (DWORD*)malloc(dwWidth * dwHeight * sizeof(DWORD));
if(lpdwCanon != NULL)
{
RawToCanon(dwFormat, dwInternalFormat, dwWidth, dwHeight, pixels, lpdwCanon);
if(dwWidth != dwNewWidth || dwHeight != dwNewHeight)
{
/* Now resize the canon image */
lpdwNewCanon = (DWORD*)malloc(dwNewWidth * dwNewHeight * sizeof(DWORD));
if(lpdwNewCanon != NULL)
{
Resize(dwWidth, dwHeight, lpdwCanon, dwNewWidth, dwNewHeight, lpdwNewCanon);
free(lpdwCanon);
}
else
{
lpdwNewCanon=lpdwCanon;
}
}
else
{
lpdwNewCanon=lpdwCanon;
}
/* Copy the texture into the surface */
if(sd.Format == D3DFMT_L8) {
CanonTo8(lpsubimage,lpdwNewCanon,&ddsd);
}
else if(sd.Format == D3DFMT_A8) {
CanonTo8(lpsubimage,lpdwNewCanon,&ddsd);
}
else if(sd.Format == D3DFMT_A4R4G4B4) {
CanonTo4444(lpsubimage,lpdwNewCanon,&ddsd);
}
else if(sd.Format == D3DFMT_R5G6B5) {
CanonTo565(lpsubimage,lpdwNewCanon,&ddsd);
}
else if(sd.Format == D3DFMT_X1R5G5B5) {
CanonTo555(lpsubimage, lpdwNewCanon, &ddsd);
}
else {
CanonTo8888(lpsubimage, lpdwNewCanon, &ddsd);
}
free(lpdwNewCanon);
}
}
/*
* unlock the surface
*/
lpDDS->UnlockRect();
return S_OK;
}
HRESULT GrowVB(DWORD sz)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "GrowVB: 0x%X", sz );
#endif
if(sz > g_OpenGLValues->m_vbufsz)
{
HRESULT hr;
if(g_OpenGLValues->m_xyzbuf != 0)
{
g_OpenGLValues->m_xyzbuf->Release();
}
hr = g_OpenGLValues->m_d3ddev->CreateVertexBuffer(sz * 12, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &g_OpenGLValues->m_xyzbuf);
if( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: GrowVB: CreateVertexBuffer(1) failed (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
return hr;
}
if(g_OpenGLValues->m_colbuf != 0)
{
g_OpenGLValues->m_colbuf->Release();
}
hr = g_OpenGLValues->m_d3ddev->CreateVertexBuffer(sz * 4, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &g_OpenGLValues->m_colbuf);
if( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: GrowVB: CreateVertexBuffer(2) failed (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
return hr;
}
if(g_OpenGLValues->m_texbuf != 0)
{
g_OpenGLValues->m_texbuf->Release();
}
hr = g_OpenGLValues->m_d3ddev->CreateVertexBuffer(sz * 8, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &g_OpenGLValues->m_texbuf);
if( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: GrowVB: CreateVertexBuffer(3) failed (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
return hr;
}
if(g_OpenGLValues->m_tex2buf != 0)
{
g_OpenGLValues->m_tex2buf->Release();
}
hr = g_OpenGLValues->m_d3ddev->CreateVertexBuffer(sz * 8, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &g_OpenGLValues->m_tex2buf);
if( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: GrowVB: CreateVertexBuffer(4) failed (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
return hr;
}
g_OpenGLValues->m_vbufoff = 0;
g_OpenGLValues->m_vbufsz = sz;
}
return S_OK;
}
HRESULT GrowIB(DWORD sz)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "GrowIB: 0x%X", sz );
#endif
if(sz > g_OpenGLValues->m_ibufsz)
{
if(g_OpenGLValues->m_ibuf != 0)
{
g_OpenGLValues->m_ibuf->Release();
}
HRESULT hr = g_OpenGLValues->m_d3ddev->CreateIndexBuffer(sz * 2, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &g_OpenGLValues->m_ibuf);
if( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: GrowIB: CreateIndexBuffer failed (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
return hr;
}
g_OpenGLValues->m_d3ddev->SetIndices(g_OpenGLValues->m_ibuf, 0);
g_OpenGLValues->m_ibufoff = 0;
g_OpenGLValues->m_ibufsz = sz;
}
return S_OK;
}
///////////////////////////// BEGIN API ENTRIES ///////////////////////////////////////////////////
void APIENTRY glActiveTextureARB(GLenum texture)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glActiveTextureARB: 0x%X", texture );
#endif
g_OpenGLValues->m_curtgt = texture == GL_TEXTURE0_ARB ? 0 : 1;
}
void APIENTRY glAlphaFunc (GLenum func, GLclampf ref)
{
#if GETPARMSFORDEBUG
char log[256];
char l[40];
ftoa( (double)ref, l );
sprintf( log, "glAlphaFunc: 0x%X %s", func, l );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
DWORD funcvalue;
switch(func) {
case GL_NEVER:
funcvalue=D3DCMP_NEVER;
break;
case GL_LESS:
funcvalue=D3DCMP_LESS;
break;
case GL_EQUAL:
funcvalue=D3DCMP_EQUAL;
break;
case GL_LEQUAL:
funcvalue=D3DCMP_LESSEQUAL;
break;
case GL_GREATER:
funcvalue=D3DCMP_GREATER;
break;
case GL_NOTEQUAL:
funcvalue=D3DCMP_NOTEQUAL;
break;
case GL_GEQUAL:
funcvalue=D3DCMP_GREATEREQUAL;
break;
case GL_ALWAYS:
funcvalue=D3DCMP_ALWAYS;
break;
}
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_ALPHAFUNC, funcvalue);
Clamp(&ref);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_ALPHAREF, (DWORD)(ref * 255.f));
}
void APIENTRY glArrayElement (GLint i)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glArrayElement: 0x%X", i );
#endif
if(g_OpenGLValues->m_usetexcoordary[0])
{
g_OpenGLValues->m_tu = *((FLOAT*)((BYTE*)g_OpenGLValues->m_texcoordary[0] + i * g_OpenGLValues->m_texcoordarystride[0]));
g_OpenGLValues->m_tv = *((FLOAT*)((BYTE*)g_OpenGLValues->m_texcoordary[0] + i * g_OpenGLValues->m_texcoordarystride[0]) + 1);
}
if(g_OpenGLValues->m_usetexcoordary[1])
{
g_OpenGLValues->m_tu2 = *((FLOAT*)((BYTE*)g_OpenGLValues->m_texcoordary[1] + i * g_OpenGLValues->m_texcoordarystride[1]));
g_OpenGLValues->m_tv2 = *((FLOAT*)((BYTE*)g_OpenGLValues->m_texcoordary[1] + i * g_OpenGLValues->m_texcoordarystride[1]) + 1);
}
if(g_OpenGLValues->m_usecolorary)
{
#ifdef _X86_
const void * colorary = g_OpenGLValues->m_colorary;
DWORD colorarystride = g_OpenGLValues->m_colorarystride;
D3DCOLOR color;
_asm
{
mov eax, i;
mov ebx, colorary;
mul colorarystride;
mov edx, 0x00FF00FF;
add eax, ebx;
mov ecx, eax;
and eax, edx;
not edx;
rol eax, 16;
and ecx, edx;
or eax, ecx;
mov color, eax;
}
g_OpenGLValues->m_color = color;
#else
BYTE *glcolor = (BYTE*)g_OpenGLValues->m_colorary + i * g_OpenGLValues->m_colorarystride;
g_OpenGLValues->m_color = RGBA_MAKE(glcolor[0], glcolor[1], glcolor[2], glcolor[3]);
#endif
}
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = *((FLOAT*)((BYTE*)g_OpenGLValues->m_vertexary + i * g_OpenGLValues->m_vertexarystride));
*(d3dv++) = *((FLOAT*)((BYTE*)g_OpenGLValues->m_vertexary + i * g_OpenGLValues->m_vertexarystride) + 1);
*(d3dv++) = *((FLOAT*)((BYTE*)g_OpenGLValues->m_vertexary + i * g_OpenGLValues->m_vertexarystride) + 2);
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glBegin (GLenum mode)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glBegin: 0x%X", mode );
#endif
g_OpenGLValues->m_prim = mode;
g_OpenGLValues->m_withinprim = TRUE;
g_OpenGLValues->m_vcnt = 0;
QuakeSetTexturingState();
if(g_OpenGLValues->m_nfv > (VBUFSIZE - MAXVERTSPERPRIM)) // check if space available
{
g_OpenGLValues->m_vbuf->Lock(0, 0, (BYTE**)&g_OpenGLValues->m_verts, D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK);
g_OpenGLValues->m_nfv = 0;
}
else
{
g_OpenGLValues->m_vbuf->Lock(0, 0, (BYTE**)&g_OpenGLValues->m_verts, D3DLOCK_NOOVERWRITE | D3DLOCK_NOSYSLOCK);
g_OpenGLValues->m_verts = &g_OpenGLValues->m_verts[g_OpenGLValues->m_nfv];
}
}
void APIENTRY glBindTexture (GLenum target, GLuint texture)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glBindTexture: 0x%X 0x%X", target, texture );
#endif
g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt] = texture;
g_OpenGLValues->m_texHandleValid = FALSE;
}
void APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glBlendFunc: 0x%X 0x%X", sfactor, dfactor );
#endif
int svalue = -1, dvalue = -1;
switch(sfactor) {
case GL_ZERO:
svalue=D3DBLEND_ZERO;
break;
case GL_ONE:
svalue=D3DBLEND_ONE;
break;
case GL_DST_COLOR:
svalue=D3DBLEND_DESTCOLOR;
break;
case GL_ONE_MINUS_DST_COLOR:
svalue=D3DBLEND_INVDESTCOLOR;
break;
case GL_SRC_ALPHA:
svalue=D3DBLEND_SRCALPHA;
break;
case GL_ONE_MINUS_SRC_ALPHA:
svalue=D3DBLEND_INVSRCALPHA;
break;
case GL_DST_ALPHA:
svalue=D3DBLEND_DESTALPHA;
break;
case GL_ONE_MINUS_DST_ALPHA:
svalue=D3DBLEND_INVDESTALPHA;
break;
case GL_SRC_ALPHA_SATURATE:
svalue=D3DBLEND_SRCALPHASAT;
break;
}
switch(dfactor) {
case GL_ZERO:
dvalue=D3DBLEND_ZERO;
break;
case GL_ONE:
dvalue=D3DBLEND_ONE;
break;
case GL_SRC_COLOR:
dvalue=D3DBLEND_SRCCOLOR;
break;
case GL_ONE_MINUS_SRC_COLOR:
dvalue=D3DBLEND_INVSRCCOLOR;
break;
case GL_SRC_ALPHA:
dvalue=D3DBLEND_SRCALPHA;
break;
case GL_ONE_MINUS_SRC_ALPHA:
dvalue=D3DBLEND_INVSRCALPHA;
break;
case GL_DST_ALPHA:
dvalue=D3DBLEND_DESTALPHA;
break;
case GL_ONE_MINUS_DST_ALPHA:
dvalue=D3DBLEND_INVDESTALPHA;
break;
}
if (svalue >= 0) g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_SRCBLEND, (DWORD)svalue);
if (dvalue >= 0) g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_DESTBLEND, (DWORD)dvalue);
}
void APIENTRY glClearStencil (GLint s)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glClearStencil: 0x%X", s );
#endif
g_OpenGLValues->m_clearStencil = (DWORD)s;
}
void APIENTRY glClear (GLbitfield mask)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glClear: 0x%X", mask );
#endif
DWORD flags = 0;
if(mask & GL_COLOR_BUFFER_BIT) {
flags |= D3DCLEAR_TARGET;
}
if(mask & GL_DEPTH_BUFFER_BIT) {
flags |= D3DCLEAR_ZBUFFER;
}
if(mask & GL_STENCIL_BUFFER_BIT) {
flags |= D3DCLEAR_STENCIL;
}
if(g_OpenGLValues->m_updvwp)
QuakeUpdateViewport();
g_OpenGLValues->m_d3ddev->Clear(0, NULL, flags, g_OpenGLValues->m_clearColor, (FLOAT)g_OpenGLValues->m_clearDepth, g_OpenGLValues->m_clearStencil);
}
void APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
#if GETPARMSFORDEBUG
char log[256];
char r[40];
char g[40];
char b[40];
char a[40];
ftoa( (double)red, r );
ftoa( (double)green, g );
ftoa( (double)blue, b );
ftoa( (double)alpha, a );
sprintf( log, "glClearColor: %s %s %s %s", r, g, b, a );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
Clamp(&red);
Clamp(&green);
Clamp(&blue);
Clamp(&alpha);
unsigned int R, G, B, A;
R = (unsigned int)(red * 255.f);
G = (unsigned int)(green * 255.f);
B = (unsigned int)(blue * 255.f);
A = (unsigned int)(alpha * 255.f);
g_OpenGLValues->m_clearColor = RGBA_MAKE(R, G, B, A);
}
void APIENTRY glClearDepth (GLclampd depth)
{
#if GETPARMSFORDEBUG
char log[256];
char d[40];
ftoa( (double)depth, d );
sprintf( log, "glClearDepth: %s", d );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
Clamp(&depth);
g_OpenGLValues->m_clearDepth = depth;
}
void APIENTRY glClientActiveTextureARB(GLenum texture)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glClientActiveTextureARB: 0x%X", texture );
#endif
g_OpenGLValues->m_client_active_texture_arb = texture == GL_TEXTURE0_ARB ? 0 : 1;
}
void APIENTRY glClipPlane (GLenum plane, const GLdouble *equation)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glClipPlane: 0x%X 0x%X", plane, equation );
#endif
D3DMATRIX &m = g_OpenGLValues->m_xfrm[D3DTS_WORLD];
m.m[0][3] = -(m.m[0][0] * m.m[3][0] + m.m[0][1] * m.m[3][1] + m.m[0][2] * m.m[3][2]);
m.m[1][3] = -(m.m[1][0] * m.m[3][0] + m.m[1][1] * m.m[3][1] + m.m[1][2] * m.m[3][2]);
m.m[2][3] = -(m.m[2][0] * m.m[3][0] + m.m[2][1] * m.m[3][1] + m.m[2][2] * m.m[3][2]);
m.m[3][0] = 0.f; m.m[3][1] = 0.f; m.m[3][2] = 0.f;
FLOAT eqn[4];
eqn[0] = FLOAT(m.m[0][0] * equation[0] + m.m[1][0] * equation[1] + m.m[2][0] * equation[2] + m.m[3][0] * equation[3]);
eqn[1] = FLOAT(m.m[0][1] * equation[0] + m.m[1][1] * equation[1] + m.m[2][1] * equation[2] + m.m[3][1] * equation[3]);
eqn[2] = FLOAT(m.m[0][2] * equation[0] + m.m[1][2] * equation[1] + m.m[2][2] * equation[2] + m.m[3][2] * equation[3]);
eqn[3] = FLOAT(m.m[0][3] * equation[0] + m.m[1][3] * equation[1] + m.m[2][3] * equation[2] + m.m[3][3] * equation[3]);
g_OpenGLValues->m_d3ddev->SetClipPlane(plane - GL_CLIP_PLANE0, eqn);
}
void APIENTRY glColor3f (GLfloat red, GLfloat green, GLfloat blue)
{
#if GETPARMSFORDEBUG
char log[256];
char r[40];
char g[40];
char b[40];
ftoa( (double)red, r );
ftoa( (double)green, g );
ftoa( (double)blue, b );
sprintf( log, "glColor3f: %s %s %s", r, g, b );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
static float two55 = 255.f;
unsigned int R, G, B;
#ifdef _X86_
D3DCOLOR color;
_asm {
fld red;
fld green;
fld blue;
fld two55;
fmul st(1), st(0);
fmul st(2), st(0);
fmulp st(3), st(0);
fistp B;
fistp G;
fistp R;
mov eax, B;
cmp eax, 255;
jle pt1;
mov eax, 255;
pt1: mov ebx, G;
cmp ebx, 255;
jle pt2;
mov ebx, 255;
pt2: mov ecx, R;
cmp ecx, 255;
jle pt3;
mov ecx, 255;
pt3: shl ebx, 8;
shl ecx, 16;
or eax, ebx;
or ecx, 0xFF000000;
or eax, ecx;
mov color, eax;
}
g_OpenGLValues->m_color = color;
#else
R = (unsigned int)(red * two55);
G = (unsigned int)(green * two55);
B = (unsigned int)(blue * two55);
if(R > 255)
R = 255;
if(G > 255)
G = 255;
if(B > 255)
B = 255;
g_OpenGLValues->m_color = RGBA_MAKE(R, G, B, 255);
#endif
}
void APIENTRY glColor3fv (const GLfloat *v)
{
#if GETPARMSFORDEBUG
char log[256];
char v0[40];
char v1[40];
char v2[40];
ftoa( (double)v[0], v0 );
ftoa( (double)v[1], v1 );
ftoa( (double)v[2], v2 );
sprintf( log, "glColor3fv: %s %s %s", v0, v1, v2 );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
static float two55 = 255.f;
unsigned int R, G, B;
#ifdef _X86_
D3DCOLOR color;
_asm {
mov ebx, v;
fld [ebx];
fld [ebx + 4];
fld [ebx + 8];
fld two55;
fmul st(1), st(0);
fmul st(2), st(0);
fmulp st(3), st(0);
fistp B;
fistp G;
fistp R;
mov eax, B;
cmp eax, 255;
jle pt1;
mov eax, 255;
pt1: mov ebx, G;
cmp ebx, 255;
jle pt2;
mov ebx, 255;
pt2: mov ecx, R;
cmp ecx, 255;
jle pt3;
mov ecx, 255;
pt3: shl ebx, 8;
shl ecx, 16;
or eax, ebx;
or ecx, 0xFF000000;
or eax, ecx;
mov color, eax;
}
g_OpenGLValues->m_color = color;
#else
R = (unsigned int)(v[0] * two55);
G = (unsigned int)(v[1] * two55);
B = (unsigned int)(v[2] * two55);
if(R > 255)
R = 255;
if(G > 255)
G = 255;
if(B > 255)
B = 255;
g_OpenGLValues->m_color = RGBA_MAKE(R, G, B, 255);
#endif
}
void APIENTRY glColor3ubv (const GLubyte *v)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glColor3ubv: 0x%X 0x%X 0x%X", v[0], v[1], v[2] );
#endif
g_OpenGLValues->m_color = RGBA_MAKE(v[0], v[1], v[2], 255);
}
void APIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glColor4ub: 0x%X 0x%X 0x%X 0x%X", red, green, blue, alpha );
#endif
g_OpenGLValues->m_color = RGBA_MAKE(red, green, blue, alpha);
}
void APIENTRY glColor4ubv (const GLubyte *v)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glColor4ubv: 0x%X 0x%X 0x%X 0x%X", v[0], v[1], v[2], v[3] );
#endif
#ifdef _X86_
D3DCOLOR color;
_asm
{
mov ebx, v;
mov edx, 0x00FF00FF;
mov eax, [ebx];
mov ecx, eax;
and eax, edx;
not edx;
rol eax, 16;
and ecx, edx;
or eax, ecx;
mov color, eax;
}
g_OpenGLValues->m_color = color;
#else
g_OpenGLValues->m_color = RGBA_MAKE(v[0], v[1], v[2], v[3]);
#endif
}
void APIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
{
#if GETPARMSFORDEBUG
char log[256];
char r[40];
char g[40];
char b[40];
char a[40];
ftoa( (double)red, r );
ftoa( (double)green, g );
ftoa( (double)blue, b );
ftoa( (double)alpha, a );
sprintf( log, "glColor4f: %s %s %s %s", r, g, b, a );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
static float two55 = 255.f;
unsigned int R, G, B, A;
#ifdef _X86_
D3DCOLOR color;
__asm {
fld red;
fld green;
fld blue;
fld alpha;
fld two55;
fmul st(1), st(0);
fmul st(2), st(0);
fmul st(3), st(0);
fmulp st(4), st(0);
fistp A;
fistp B;
fistp G;
fistp R;
mov edx, A;
cmp edx, 255;
jle pt1;
mov edx, 255;
pt1: mov eax, B;
cmp eax, 255;
jle pt2;
mov eax, 255;
pt2: mov ebx, G;
cmp ebx, 255;
jle pt3;
mov ebx, 255;
pt3: mov ecx, R;
cmp ecx, 255;
jle pt4;
mov ecx, 255;
pt4: shl ebx, 8;
shl ecx, 16;
shl edx, 24;
or eax, ebx;
or ecx, edx;
or eax, ecx;
mov color, eax;
}
g_OpenGLValues->m_color = color;
#else
R = (unsigned int)(red * two55);
G = (unsigned int)(green * two55);
B = (unsigned int)(blue * two55);
A = (unsigned int)(alpha * two55);
if(R > 255)
R = 255;
if(G > 255)
G = 255;
if(B > 255)
B = 255;
if(A > 255)
A = 255;
g_OpenGLValues->m_color = RGBA_MAKE(R, G, B, A);
#endif
}
void APIENTRY glColor4fv (const GLfloat *v)
{
#if GETPARMSFORDEBUG
char log[256];
char v0[40];
char v1[40];
char v2[40];
char v3[40];
ftoa( (double)v[0], v0 );
ftoa( (double)v[1], v1 );
ftoa( (double)v[2], v2 );
ftoa( (double)v[3], v3 );
sprintf( log, "glColor4fv: %s %s %s %s", v0, v1, v2, v3 );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
static float two55 = 255.f;
unsigned int R, G, B, A;
#ifdef _X86_
D3DCOLOR color;
_asm {
mov ebx, v;
fld [ebx];
fld [ebx + 4];
fld [ebx + 8];
fld [ebx + 12];
fld two55;
fmul st(1), st(0);
fmul st(2), st(0);
fmul st(3), st(0);
fmulp st(4), st(0);
fistp A;
fistp B;
fistp G;
fistp R;
mov edx, A;
cmp edx, 255;
jle pt1;
mov edx, 255;
pt1: mov eax, B;
cmp eax, 255;
jle pt2;
mov eax, 255;
pt2: mov ebx, G;
cmp ebx, 255;
jle pt3;
mov ebx, 255;
pt3: mov ecx, R;
cmp ecx, 255;
jle pt4;
mov ecx, 255;
pt4: shl ebx, 8;
shl ecx, 16;
shl edx, 24;
or eax, ebx;
or ecx, edx;
or eax, ecx;
mov color, eax;
}
g_OpenGLValues->m_color = color;
#else
R = (unsigned int)(v[0] * two55);
G = (unsigned int)(v[1] * two55);
B = (unsigned int)(v[2] * two55);
A = (unsigned int)(v[3] * two55);
if(R > 255)
R = 255;
if(G > 255)
G = 255;
if(B > 255)
B = 255;
if(A > 255)
A = 255;
g_OpenGLValues->m_color = RGBA_MAKE(R, G, B, A);
#endif
}
void APIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glColorPointer: 0x%X 0x%X 0x%X 0x%X", size, type, stride, pointer );
#endif
if(size == 4 && (type == GL_BYTE || type == GL_UNSIGNED_BYTE))
g_OpenGLValues->m_colorary = (GLubyte*)pointer;
#if DODPFS
else
{
char junk[256];
sprintf( junk, "Color array not supported (size:0x%X type:0x%X)\n", size, type );
OutputDebugStringA( junk );
}
#endif
if(stride == 0)
{
stride = 4;
}
g_OpenGLValues->m_colorarystride = stride;
}
void APIENTRY glCullFace (GLenum mode)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glCullFace: 0x%X", mode );
#endif
g_OpenGLValues->m_cullMode = mode;
if(g_OpenGLValues->m_cullEnabled == TRUE){
DWORD statevalue;
if(mode == GL_BACK)
statevalue = g_OpenGLValues->m_FrontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW;
else
statevalue = g_OpenGLValues->m_FrontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CULLMODE, statevalue);
}
}
void APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glDeleteTextures: 0x%X 0x%X", n, textures );
#endif
for(int i = 0; i < n; ++i) {
TexInfo &ti = g_OpenGLValues->m_tex[textures[i]];
if(ti.m_ddsurf != 0) {
ti.m_ddsurf->Release();
ti.m_ddsurf = 0;
}
if(ti.m_block != 0)
{
g_OpenGLValues->m_d3ddev->DeleteStateBlock(ti.m_block);
ti.m_block = 0;
}
ti.m_capture = FALSE;
ti.m_dwStage = 0;
ti.m_minmode = D3DTEXF_POINT;
ti.m_magmode = D3DTEXF_LINEAR;
ti.m_mipmode = D3DTEXF_LINEAR;
ti.m_addu = D3DTADDRESS_WRAP;
ti.m_addv = D3DTADDRESS_WRAP;
ti.m_next = g_OpenGLValues->m_free;
ti.m_prev = -1;
g_OpenGLValues->m_tex[g_OpenGLValues->m_free].m_prev = textures[i];
g_OpenGLValues->m_free = textures[i];
}
}
void APIENTRY glDepthFunc (GLenum func)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glDepthFunc: 0x%X", func );
#endif
int state = -1;
switch(func) {
case GL_NEVER:
state=D3DCMP_NEVER;
break;
case GL_LESS:
state=D3DCMP_LESS;
break;
case GL_EQUAL:
state=D3DCMP_EQUAL;
break;
case GL_LEQUAL:
state=D3DCMP_LESSEQUAL;
break;
case GL_GREATER:
state=D3DCMP_GREATER;
break;
case GL_NOTEQUAL:
state=D3DCMP_NOTEQUAL;
break;
case GL_GEQUAL:
state=D3DCMP_GREATEREQUAL;
break;
case GL_ALWAYS:
state=D3DCMP_ALWAYS;
break;
}
if(state >= 0)
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_ZFUNC, state);
}
void APIENTRY glDepthMask (GLboolean flag)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glDepthMask: 0x%X", flag );
#endif
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_ZWRITEENABLE, flag);
}
void APIENTRY glDepthRange (GLclampd zNear, GLclampd zFar)
{
#if GETPARMSFORDEBUG
char log[256];
char zn[40];
char zf[40];
ftoa( (double)zNear, zn );
ftoa( (double)zFar, zf );
sprintf( log, "glDepthRange: %s %s", zn, zf );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
Clamp(&zNear);
Clamp(&zFar);
g_OpenGLValues->m_vport.MinZ = (FLOAT)zNear;
g_OpenGLValues->m_vport.MaxZ = (FLOAT)zFar;
if(g_OpenGLValues->m_polyoffset && g_OpenGLValues->m_vport.MaxZ != 0.f)
{
D3DVIEWPORT8 vport(g_OpenGLValues->m_vport);
vport.MaxZ -= .001f;
g_OpenGLValues->m_d3ddev->SetViewport(&vport);
}
else
{
g_OpenGLValues->m_d3ddev->SetViewport(&g_OpenGLValues->m_vport);
}
}
void APIENTRY glEnd (void)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glEnd" );
#endif
if(!g_OpenGLValues->m_withinprim)
return;
g_OpenGLValues->m_vbuf->Unlock();
QuakeSetVertexShader(QUAKEVFMT);
QuakeSetStreamSource(0, g_OpenGLValues->m_vbuf, sizeof(QuakeVertex));
unsigned vcnt;
vcnt = g_OpenGLValues->m_vcnt;
switch(g_OpenGLValues->m_prim)
{
case GL_TRIANGLES:
if(vcnt >= 3)
{
g_OpenGLValues->m_d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, g_OpenGLValues->m_nfv, vcnt / 3);
}
#if DODPFS
else
{
char junk[256];
sprintf( junk, "Wrapper: glEnd: GL_TRIANGLES cnt=%d NOT STORED\n", vcnt );
OutputDebugStringA( junk );
}
#endif
g_OpenGLValues->m_nfv += vcnt;
break;
case GL_QUADS:
if(vcnt >= 4)
{
unsigned i;
for(i = 0; i < vcnt; i += 4)
{
g_OpenGLValues->m_d3ddev->DrawPrimitive(D3DPT_TRIANGLEFAN, g_OpenGLValues->m_nfv, 2);
g_OpenGLValues->m_nfv += 4;
}
}
#if DODPFS
else
{
char junk[256];
sprintf( junk, "Wrapper: glEnd: GL_QUADS cnt=%d NOT STORED\n", vcnt );
OutputDebugStringA( junk );
}
#endif
break;
case GL_LINES:
if(vcnt >= 2)
{
g_OpenGLValues->m_d3ddev->DrawPrimitive(D3DPT_LINELIST, g_OpenGLValues->m_nfv, vcnt / 2);
}
#if DODPFS
else
{
char junk[256];
sprintf( junk, "Wrapper: glEnd: GL_LINES cnt=%d NOT STORED\n", vcnt );
OutputDebugStringA( junk );
}
#endif
g_OpenGLValues->m_nfv += vcnt;
break;
case GL_TRIANGLE_STRIP:
case GL_QUAD_STRIP:
if(vcnt > 2)
{
g_OpenGLValues->m_d3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP, g_OpenGLValues->m_nfv, vcnt-2 );
}
#if DODPFS
else
{
char junk[256];
sprintf( junk, "Wrapper: glEnd: GL_TRIANGLE_STRIP or GL_QUAD_STRIP cnt=%d NOT STORED\n", vcnt );
OutputDebugStringA( junk );
}
#endif
g_OpenGLValues->m_nfv += vcnt;
break;
case GL_POLYGON:
case GL_TRIANGLE_FAN:
if(vcnt > 2)
{
g_OpenGLValues->m_d3ddev->DrawPrimitive(D3DPT_TRIANGLEFAN, g_OpenGLValues->m_nfv, vcnt-2);
}
#if DODPFS
else
{
char junk[256];
sprintf( junk, "Wrapper: glEnd: GL_POLYGON or GL_TRIANGLE_FAN cnt=%d NOT STORED\n", vcnt );
OutputDebugStringA( junk );
}
#endif
g_OpenGLValues->m_nfv += vcnt;
break;
case GL_POINTS:
if(vcnt > 0)
{
g_OpenGLValues->m_d3ddev->DrawPrimitive(D3DPT_POINTLIST, g_OpenGLValues->m_nfv, vcnt);
}
#if DODPFS
else
{
char junk[256];
sprintf( junk, "Wrapper: glEnd: GL_POINTS cnt=%d NOT STORED\n", vcnt );
OutputDebugStringA( junk );
}
#endif
g_OpenGLValues->m_nfv += vcnt;
break;
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper: unimplemented primitive type=0x%X cnt=%d\n", g_OpenGLValues->m_prim, vcnt );
OutputDebugStringA( junk );
#endif
}
g_OpenGLValues->m_withinprim = FALSE;
}
void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glDrawElements: 0x%X 0x%X 0x%X 0x%X", mode, count, type, indices );
#endif
QuakeSetTexturingState();
if((DWORD)count > g_OpenGLValues->m_ibufsz)
{
GrowIB(count);
}
unsigned min, max, LockFlags;
GLsizei i;
if(g_OpenGLValues->m_lckcount != 0)
{
WORD *pIndices;
min = g_OpenGLValues->m_lckfirst;
max = g_OpenGLValues->m_lckfirst + g_OpenGLValues->m_lckcount - 1;
if(max - min + 1 > g_OpenGLValues->m_vbufsz)
{
GrowVB(max - min + 1);
}
if(g_OpenGLValues->m_vbufoff + max - min + 1 > g_OpenGLValues->m_vbufsz)
{
LockFlags = D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK;
g_OpenGLValues->m_vbufoff = 0;
}
else
{
LockFlags = D3DLOCK_NOOVERWRITE | D3DLOCK_NOSYSLOCK;
}
if(g_OpenGLValues->m_ibufoff + count > g_OpenGLValues->m_ibufsz)
{
g_OpenGLValues->m_ibufoff = 0;
g_OpenGLValues->m_ibuf->Lock(g_OpenGLValues->m_ibufoff * 2, count * 2, (BYTE**)&pIndices, D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK);
}
else
{
g_OpenGLValues->m_ibuf->Lock(g_OpenGLValues->m_ibufoff * 2, count * 2, (BYTE**)&pIndices, D3DLOCK_NOOVERWRITE | D3DLOCK_NOSYSLOCK);
}
switch(type)
{
case GL_UNSIGNED_BYTE:
for(i = 0; i < count; ++i)
pIndices[i] = (WORD)(((unsigned char*)indices)[i] - min + g_OpenGLValues->m_vbufoff);
break;
case GL_UNSIGNED_SHORT:
for(i = 0; i < count; ++i)
pIndices[i] = (WORD)(((unsigned short*)indices)[i] - min + g_OpenGLValues->m_vbufoff);
break;
case GL_UNSIGNED_INT:
for(i = 0; i < count; ++i)
pIndices[i] = (WORD)(((unsigned int*)indices)[i] - min + g_OpenGLValues->m_vbufoff);
break;
}
g_OpenGLValues->m_ibuf->Unlock();
}
else
{
WORD *pIndices;
min = 65535;
max = 0;
switch(type)
{
case GL_UNSIGNED_BYTE:
for(i = 0; i < count; ++i)
{
unsigned t = ((unsigned char*)indices)[i];
if(t < min)
min = t;
if(t > max)
max = t;
}
break;
case GL_UNSIGNED_SHORT:
for(i = 0; i < count; ++i)
{
unsigned t = ((unsigned short*)indices)[i];
if(t < min)
min = t;
if(t > max)
max = t;
}
break;
case GL_UNSIGNED_INT:
for(i = 0; i < count; ++i)
{
unsigned t = ((unsigned int*)indices)[i];
if(t < min)
min = t;
if(t > max)
max = t;
}
break;
}
if(max - min + 1 > g_OpenGLValues->m_vbufsz)
{
GrowVB(max - min + 1);
}
if(g_OpenGLValues->m_vbufoff + max - min + 1 > g_OpenGLValues->m_vbufsz)
{
LockFlags = D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK;
g_OpenGLValues->m_vbufoff = 0;
}
else
{
LockFlags = D3DLOCK_NOOVERWRITE | D3DLOCK_NOSYSLOCK;
}
if(g_OpenGLValues->m_ibufoff + count > g_OpenGLValues->m_ibufsz)
{
g_OpenGLValues->m_ibufoff = 0;
g_OpenGLValues->m_ibuf->Lock(g_OpenGLValues->m_ibufoff * 2, count * 2, (BYTE**)&pIndices, D3DLOCK_DISCARD | D3DLOCK_NOSYSLOCK);
}
else
{
g_OpenGLValues->m_ibuf->Lock(g_OpenGLValues->m_ibufoff * 2, count * 2, (BYTE**)&pIndices, D3DLOCK_NOOVERWRITE | D3DLOCK_NOSYSLOCK);
}
switch(type)
{
case GL_UNSIGNED_BYTE:
for(i = 0; i < count; ++i)
{
pIndices[i] = (WORD)(((unsigned char*)indices)[i] - min + g_OpenGLValues->m_vbufoff);
}
break;
case GL_UNSIGNED_SHORT:
for(i = 0; i < count; ++i)
{
pIndices[i] = (WORD)(((unsigned short*)indices)[i] - min + g_OpenGLValues->m_vbufoff);
}
break;
case GL_UNSIGNED_INT:
for(i = 0; i < count; ++i)
{
pIndices[i] = (WORD)(((unsigned int*)indices)[i] - min + g_OpenGLValues->m_vbufoff);
}
break;
}
g_OpenGLValues->m_ibuf->Unlock();
}
if(g_OpenGLValues->m_usetexcoordary[1])
{
BYTE *pTex, *pSrcTex;
g_OpenGLValues->m_texbuf->Lock(g_OpenGLValues->m_vbufoff * 8, 8 * (max - min + 1), &pTex, LockFlags);
pSrcTex = (BYTE*)g_OpenGLValues->m_texcoordary[0] + min * g_OpenGLValues->m_texcoordarystride[0];
for(unsigned i = min; i <= max; ++i)
{
MEMCPY(pTex, pSrcTex, 8);
pTex += 8;
pSrcTex += g_OpenGLValues->m_texcoordarystride[0];
}
g_OpenGLValues->m_texbuf->Unlock();
BYTE *pTex2, *pSrcTex2;
g_OpenGLValues->m_tex2buf->Lock(g_OpenGLValues->m_vbufoff * 8, 8 * (max - min + 1), &pTex2, LockFlags);
pSrcTex2 = (BYTE*)g_OpenGLValues->m_texcoordary[1] + min * g_OpenGLValues->m_texcoordarystride[1];
for(unsigned i = min; i <= max; ++i)
{
MEMCPY(pTex2, pSrcTex2, 8);
pTex2 += 8;
pSrcTex2 += g_OpenGLValues->m_texcoordarystride[1];
}
g_OpenGLValues->m_tex2buf->Unlock();
}
else if(g_OpenGLValues->m_usetexcoordary[0])
{
BYTE *pTex, *pSrcTex;
g_OpenGLValues->m_texbuf->Lock(g_OpenGLValues->m_vbufoff * 8, 8 * (max - min + 1), &pTex, LockFlags);
pSrcTex = (BYTE*)g_OpenGLValues->m_texcoordary[0] + min * g_OpenGLValues->m_texcoordarystride[0];
for(unsigned i = min; i <= max; ++i)
{
MEMCPY(pTex, pSrcTex, 8);
pTex += 8;
pSrcTex += g_OpenGLValues->m_texcoordarystride[0];
}
g_OpenGLValues->m_texbuf->Unlock();
}
if(g_OpenGLValues->m_usecolorary)
{
if(max - min + 1 > VBUFSIZE)
{
#if DODPFS
char junk[256];
sprintf( junk, "Insufficient color buffer (amnt:0x%X size:0x%X)\n", (max-min+1), VBUFSIZE );
OutputDebugStringA( junk );
#endif
return;
}
DWORD *pColor;
BYTE *pSrcColor;
g_OpenGLValues->m_colbuf->Lock(g_OpenGLValues->m_vbufoff * 4, 4 * (max - min + 1), (BYTE**)&pColor, LockFlags);
#ifdef _X86_
const void *colorary = g_OpenGLValues->m_colorary;
DWORD colorarystride = g_OpenGLValues->m_colorarystride;
_asm
{
mov esi, min;
mov ecx, colorarystride;
mov ebx, colorary;
mov edi, pColor;
mov eax, esi;
mul ecx;
mov edx, max;
sub edx, esi;
lea esi, [ebx + eax];
inc edx;
lp1: mov eax, [esi];
add esi, ecx;
mov ebx, eax;
and eax, 0x00FF00FF;
rol eax, 16;
and ebx, 0xFF00FF00;
or eax, ebx;
mov [edi], eax;
add edi, 4;
dec edx;
jnz lp1;
}
#else
pSrcColor = (BYTE*)g_OpenGLValues->m_colorary + min * g_OpenGLValues->m_colorarystride;
for(unsigned i = min; i <= max; ++i)
{
*(pColor++) = RGBA_MAKE(pSrcColor[0], pSrcColor[1], pSrcColor[2], pSrcColor[3]);
pSrcColor += g_OpenGLValues->m_colorarystride;
}
#endif
g_OpenGLValues->m_colbuf->Unlock();
}
if(g_OpenGLValues->m_usevertexary)
{
BYTE *pXYZ, *pSrcXYZ;
g_OpenGLValues->m_xyzbuf->Lock(g_OpenGLValues->m_vbufoff * 12, 12 * (max - min + 1), &pXYZ, LockFlags);
pSrcXYZ = (BYTE*)g_OpenGLValues->m_vertexary + min * g_OpenGLValues->m_vertexarystride;
for(unsigned i = min; i <= max; ++i)
{
MEMCPY(pXYZ, pSrcXYZ, 12);
pXYZ += 12;
pSrcXYZ += g_OpenGLValues->m_vertexarystride;
}
g_OpenGLValues->m_xyzbuf->Unlock();
}
QuakeSetStreamSource(0, g_OpenGLValues->m_xyzbuf, 12);
if(g_OpenGLValues->m_usecolorary)
{
QuakeSetStreamSource(1, g_OpenGLValues->m_colbuf, 4);
if(g_OpenGLValues->m_usetexcoordary[1])
{
QuakeSetStreamSource(2, g_OpenGLValues->m_texbuf, 8);
QuakeSetStreamSource(3, g_OpenGLValues->m_tex2buf, 8);
QuakeSetVertexShader(g_OpenGLValues->m_vshader[5]);
}
else if(g_OpenGLValues->m_usetexcoordary[0])
{
QuakeSetStreamSource(2, g_OpenGLValues->m_texbuf, 8);
QuakeSetVertexShader(g_OpenGLValues->m_vshader[4]);
}
else
{
QuakeSetVertexShader(g_OpenGLValues->m_vshader[1]);
}
}
else if(g_OpenGLValues->m_usetexcoordary[1])
{
QuakeSetStreamSource(1, g_OpenGLValues->m_texbuf, 8);
QuakeSetStreamSource(2, g_OpenGLValues->m_tex2buf, 8);
QuakeSetVertexShader(g_OpenGLValues->m_vshader[3]);
}
else if(g_OpenGLValues->m_usetexcoordary[0])
{
QuakeSetStreamSource(2, g_OpenGLValues->m_texbuf, 8);
QuakeSetVertexShader(g_OpenGLValues->m_vshader[2]);
}
else
{
QuakeSetVertexShader(g_OpenGLValues->m_vshader[0]);
}
switch(mode)
{
case GL_LINES:
if(count >= 2)
{
g_OpenGLValues->m_d3ddev->DrawIndexedPrimitive(D3DPT_LINELIST, g_OpenGLValues->m_vbufoff, max - min + 1, g_OpenGLValues->m_ibufoff, count / 2);
}
break;
case GL_TRIANGLES:
if(count >= 3)
{
g_OpenGLValues->m_d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, g_OpenGLValues->m_vbufoff, max - min + 1, g_OpenGLValues->m_ibufoff, count / 3);
}
break;
case GL_TRIANGLE_STRIP:
case GL_QUAD_STRIP:
if(count > 2)
{
g_OpenGLValues->m_d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, g_OpenGLValues->m_vbufoff, max - min + 1, g_OpenGLValues->m_ibufoff, count - 2);
}
break;
case GL_POLYGON:
case GL_TRIANGLE_FAN:
if(count > 2)
{
g_OpenGLValues->m_d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN, g_OpenGLValues->m_vbufoff, max - min + 1, g_OpenGLValues->m_ibufoff, count - 2);
}
break;
case GL_QUADS:
if(count >= 4)
{
for(i = 0; i < count; i += 4)
g_OpenGLValues->m_d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN, g_OpenGLValues->m_vbufoff, max - min + 1, g_OpenGLValues->m_ibufoff, 2);
}
break;
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper (4): unimplemented primitive type (0x%X)\n", mode );
OutputDebugStringA( junk );
#endif
}
g_OpenGLValues->m_vbufoff += (max - min + 1);
g_OpenGLValues->m_ibufoff += count;
}
void APIENTRY glFrontFace (GLenum mode)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glFrontFace: 0x%X", mode );
#endif
g_OpenGLValues->m_FrontFace = mode;
}
void APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glViewport: 0x%X 0x%X 0x%X 0x%X", x, y, width, height );
#endif
g_OpenGLValues->m_vwx = x;
g_OpenGLValues->m_vwy = y;
g_OpenGLValues->m_vww = width;
g_OpenGLValues->m_vwh = height;
g_OpenGLValues->m_updvwp = TRUE;
}
void APIENTRY glLineWidth (GLfloat width)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glLineWidth: 0x%X", width );
#endif
}
void APIENTRY glLoadIdentity (void)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glLoadIdentity" );
#endif
D3DMATRIX unity;
unity._11 = 1.0f; unity._12 = 0.0f; unity._13 = 0.0f; unity._14 = 0.0f;
unity._21 = 0.0f; unity._22 = 1.0f; unity._23 = 0.0f; unity._24 = 0.0f;
unity._31 = 0.0f; unity._32 = 0.0f; unity._33 = 1.0f; unity._34 = 0.0f;
unity._41 = 0.0f; unity._42 = 0.0f; unity._43 = 0.0f; unity._44 = 1.0f;
if(g_OpenGLValues->m_matrixMode == D3DTS_TEXTURE0)
{
g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt] = unity;
QuakeSetTransform((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), &unity);
}
else
{
g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode] = unity;
QuakeSetTransform(g_OpenGLValues->m_matrixMode, &unity);
}
}
void APIENTRY glMatrixMode (GLenum mode)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glMatrixMode: 0x%X", mode );
#endif
switch(mode)
{
case GL_MODELVIEW:
g_OpenGLValues->m_matrixMode = D3DTS_WORLD;
break;
case GL_PROJECTION:
g_OpenGLValues->m_matrixMode = D3DTS_PROJECTION;
break;
case GL_TEXTURE:
g_OpenGLValues->m_matrixMode = D3DTS_TEXTURE0;
break;
}
}
void APIENTRY glColorMaterial (GLenum face, GLenum mode)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glColorMaterial: 0x%X 0x%X", face, mode );
#endif
if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
{
switch(mode)
{
case GL_EMISSION:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
break;
case GL_AMBIENT:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
break;
case GL_DIFFUSE:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
break;
case GL_SPECULAR:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR1);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
break;
case GL_AMBIENT_AND_DIFFUSE:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
break;
}
}
#if DODPFS
else
{
OutputDebugStringA("Wrapper: Back face ColorMaterial ignored\n");
}
#endif
}
void APIENTRY glDisable (GLenum cap)
{
switch(cap) {
case GL_LIGHTING:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE);
break;
case GL_COLOR_MATERIAL:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_COLORVERTEX, FALSE);
break;
case GL_DEPTH_TEST:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_ZENABLE, FALSE);
break;
case GL_CULL_FACE:
g_OpenGLValues->m_cullEnabled = FALSE;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
break;
case GL_FOG:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_NONE);
break;
case GL_BLEND:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
break;
case GL_CLIP_PLANE0:
g_OpenGLValues->m_clippstate &= ~0x01;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CLIPPLANEENABLE, g_OpenGLValues->m_clippstate);
break;
case GL_CLIP_PLANE1:
g_OpenGLValues->m_clippstate &= ~0x02;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CLIPPLANEENABLE, g_OpenGLValues->m_clippstate);
break;
case GL_CLIP_PLANE2:
g_OpenGLValues->m_clippstate &= ~0x04;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CLIPPLANEENABLE, g_OpenGLValues->m_clippstate);
break;
case GL_CLIP_PLANE3:
g_OpenGLValues->m_clippstate &= ~0x08;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CLIPPLANEENABLE, g_OpenGLValues->m_clippstate);
break;
case GL_CLIP_PLANE4:
g_OpenGLValues->m_clippstate &= ~0x10;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CLIPPLANEENABLE, g_OpenGLValues->m_clippstate);
break;
case GL_CLIP_PLANE5:
g_OpenGLValues->m_clippstate &= ~0x20;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CLIPPLANEENABLE, g_OpenGLValues->m_clippstate);
break;
case GL_POLYGON_OFFSET_FILL:
g_OpenGLValues->m_polyoffset = FALSE;
glDepthRange(g_OpenGLValues->m_vport.MinZ, g_OpenGLValues->m_vport.MaxZ);
break;
case GL_STENCIL_TEST:
break;
case GL_SCISSOR_TEST:
g_OpenGLValues->m_scissoring = FALSE;
glViewport(g_OpenGLValues->m_vwx, g_OpenGLValues->m_vwy, g_OpenGLValues->m_vww, g_OpenGLValues->m_vwh);
QuakeSetTransform(D3DTS_PROJECTION, &g_OpenGLValues->m_xfrm[D3DTS_PROJECTION]);
break;
case GL_TEXTURE_2D:
if(g_OpenGLValues->m_curtgt == 0) {
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_DISABLE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
g_OpenGLValues->m_texturing = FALSE;
}
else {
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLOROP, D3DTOP_DISABLE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
g_OpenGLValues->m_mtex = FALSE;
}
g_OpenGLValues->m_texHandleValid = FALSE;
break;
case GL_ALPHA_TEST:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
break;
case GL_LIGHT0:
g_OpenGLValues->m_d3ddev->LightEnable(0, FALSE);
break;
case GL_LIGHT1:
g_OpenGLValues->m_d3ddev->LightEnable(1, FALSE);
break;
case GL_LIGHT2:
g_OpenGLValues->m_d3ddev->LightEnable(2, FALSE);
break;
case GL_LIGHT3:
g_OpenGLValues->m_d3ddev->LightEnable(3, FALSE);
break;
case GL_LIGHT4:
g_OpenGLValues->m_d3ddev->LightEnable(4, FALSE);
break;
case GL_LIGHT5:
g_OpenGLValues->m_d3ddev->LightEnable(5, FALSE);
break;
case GL_LIGHT6:
g_OpenGLValues->m_d3ddev->LightEnable(6, FALSE);
break;
case GL_LIGHT7:
g_OpenGLValues->m_d3ddev->LightEnable(7, FALSE);
break;
case GL_TEXTURE_GEN_S:
g_OpenGLValues->m_texgen = FALSE;
g_OpenGLValues->m_d3ddev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
if(g_OpenGLValues->m_usemtex == TRUE)
{
g_OpenGLValues->m_d3ddev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);
}
break;
case GL_TEXTURE_GEN_T:
break;
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper: glDisable on this cap not supported (0x%X)\n", cap );
OutputDebugStringA( junk );
#endif
}
}
void APIENTRY glDisableClientState (GLenum array)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glDisableClientState: 0x%X", array );
#endif
switch(array)
{
case GL_COLOR_ARRAY:
g_OpenGLValues->m_usecolorary = FALSE;
break;
case GL_TEXTURE_COORD_ARRAY:
g_OpenGLValues->m_usetexcoordary[g_OpenGLValues->m_client_active_texture_arb] = FALSE;
break;
case GL_VERTEX_ARRAY:
g_OpenGLValues->m_usevertexary = FALSE;
break;
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper: Array not supported (0x%X)\n", array );
OutputDebugStringA( junk );
#endif
}
}
void APIENTRY glDrawBuffer (GLenum mode)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glDrawBuffer: 0x%X", mode );
#endif
}
void APIENTRY glEnable (GLenum cap)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glEnable: 0x%X", cap );
#endif
switch(cap) {
case GL_LIGHTING:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE);
break;
case GL_COLOR_MATERIAL:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_COLORVERTEX, TRUE);
break;
case GL_DEPTH_TEST:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);
break;
case GL_CULL_FACE:
g_OpenGLValues->m_cullEnabled = TRUE;
glCullFace(g_OpenGLValues->m_cullMode);
break;
case GL_FOG:
break;
case GL_BLEND:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
break;
case GL_CLIP_PLANE0:
g_OpenGLValues->m_clippstate |= 0x01;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CLIPPLANEENABLE, g_OpenGLValues->m_clippstate);
break;
case GL_CLIP_PLANE1:
g_OpenGLValues->m_clippstate |= 0x02;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CLIPPLANEENABLE, g_OpenGLValues->m_clippstate);
break;
case GL_CLIP_PLANE2:
g_OpenGLValues->m_clippstate |= 0x04;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CLIPPLANEENABLE, g_OpenGLValues->m_clippstate);
break;
case GL_CLIP_PLANE3:
g_OpenGLValues->m_clippstate |= 0x08;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CLIPPLANEENABLE, g_OpenGLValues->m_clippstate);
break;
case GL_CLIP_PLANE4:
g_OpenGLValues->m_clippstate |= 0x10;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CLIPPLANEENABLE, g_OpenGLValues->m_clippstate);
break;
case GL_CLIP_PLANE5:
g_OpenGLValues->m_clippstate |= 0x20;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CLIPPLANEENABLE, g_OpenGLValues->m_clippstate);
break;
case GL_POLYGON_OFFSET_FILL:
g_OpenGLValues->m_polyoffset = TRUE;
glDepthRange(g_OpenGLValues->m_vport.MinZ, g_OpenGLValues->m_vport.MaxZ);
break;
case GL_SCISSOR_TEST:
g_OpenGLValues->m_scissoring = TRUE;
g_OpenGLValues->m_updvwp = TRUE;
break;
case GL_TEXTURE_2D:
if(g_OpenGLValues->m_curtgt == 0)
g_OpenGLValues->m_texturing = TRUE;
else
g_OpenGLValues->m_mtex = TRUE;
g_OpenGLValues->m_texHandleValid = FALSE;
break;
case GL_ALPHA_TEST:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
break;
case GL_LIGHT0:
g_OpenGLValues->m_d3ddev->LightEnable(0, TRUE);
break;
case GL_LIGHT1:
g_OpenGLValues->m_d3ddev->LightEnable(1, TRUE);
break;
case GL_LIGHT2:
g_OpenGLValues->m_d3ddev->LightEnable(2, TRUE);
break;
case GL_LIGHT3:
g_OpenGLValues->m_d3ddev->LightEnable(3, TRUE);
break;
case GL_LIGHT4:
g_OpenGLValues->m_d3ddev->LightEnable(4, TRUE);
break;
case GL_LIGHT5:
g_OpenGLValues->m_d3ddev->LightEnable(5, TRUE);
break;
case GL_LIGHT6:
g_OpenGLValues->m_d3ddev->LightEnable(6, TRUE);
break;
case GL_LIGHT7:
g_OpenGLValues->m_d3ddev->LightEnable(7, TRUE);
break;
case GL_TEXTURE_GEN_S:
g_OpenGLValues->m_texgen = TRUE;
g_OpenGLValues->m_d3ddev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0 | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
if(g_OpenGLValues->m_usemtex == TRUE)
{
g_OpenGLValues->m_d3ddev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1 | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
}
break;
case GL_TEXTURE_GEN_T:
break;
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper: glEnable on this cap not supported (0x%X)\n", cap );
OutputDebugStringA( junk );
#endif
}
}
void APIENTRY glEnableClientState (GLenum array)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glEnableClientState: 0x%X", array );
#endif
switch(array)
{
case GL_COLOR_ARRAY:
g_OpenGLValues->m_usecolorary = TRUE;
break;
case GL_TEXTURE_COORD_ARRAY:
g_OpenGLValues->m_usetexcoordary[g_OpenGLValues->m_client_active_texture_arb] = TRUE;
break;
case GL_VERTEX_ARRAY:
g_OpenGLValues->m_usevertexary = TRUE;
break;
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper: Array not supported (0x%X)\n", array );
OutputDebugStringA( junk );
#endif
}
}
void APIENTRY glFogf (GLenum pname, GLfloat param)
{
#if GETPARMSFORDEBUG
char log[256];
char p[40];
ftoa( (double)param, p );
sprintf( log, "glFogf: 0x%X %s", pname, p );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
FLOAT start, end;
switch(pname)
{
case GL_FOG_MODE:
switch((int)param)
{
case GL_LINEAR:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
break;
case GL_EXP:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_EXP);
break;
case GL_EXP2:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_EXP2);
break;
}
break;
case GL_FOG_START:
start = param;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_FOGSTART, *(DWORD*)(&start));
break;
case GL_FOG_END:
end = param;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_FOGEND, *(DWORD*)(&end));
break;
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper: Fog pname not supported (0x%X)\n", pname );
OutputDebugStringA( junk );
#endif
}
}
void APIENTRY glFogi (GLenum pname, GLint param)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glFogi: 0x%X 0x%X", pname, param );
#endif
glFogf(pname, (GLfloat)param);
}
void APIENTRY glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
{
#if GETPARMSFORDEBUG
char log[256];
char l[40];
char r[40];
char b[40];
char t[40];
char zn[40];
char zf[40];
ftoa( (double)left, l );
ftoa( (double)right, r );
ftoa( (double)bottom, b );
ftoa( (double)top, t );
ftoa( (double)zNear, zn );
ftoa( (double)zFar, zf );
sprintf( log, "glFrustum: %s %s %s %s %s %s", l, r, b, t, zn, zf );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
D3DMATRIX f;
f._11 = (FLOAT)((2.0 * zNear) / (right - left));
f._21 = 0.f;
f._31 = (FLOAT)((right + left) / (right - left));
f._41 = 0.f;
f._12 = 0.f;
f._22 = (FLOAT)((2.0 * zNear) / (top - bottom));
f._32 = (FLOAT)((top + bottom) / (top - bottom));
f._42 = 0.f;
f._13 = 0.f;
f._23 = 0.f;
f._33 = (FLOAT)(-(zFar + zNear) / (zFar - zNear));
f._43 = (FLOAT)(-(2.0 * zFar * zNear) / (zFar - zNear));
f._14 = 0.f;
f._24 = 0.f;
f._34 = -1.f;
f._44 = 0.f;
if(g_OpenGLValues->m_matrixMode == D3DTS_TEXTURE0)
{
MultiplyMatrix((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), f);
QuakeSetTransform((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), &g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt]);
}
else
{
MultiplyMatrix(g_OpenGLValues->m_matrixMode, f);
QuakeSetTransform(g_OpenGLValues->m_matrixMode, &g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode]);
}
}
void APIENTRY glGenTextures (GLsizei n, GLuint *textures)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glGenTextures: 0x%X 0x%X", n, textures );
#endif
for(GLsizei i = 0; i < n; ++i)
{
textures[i] = g_OpenGLValues->m_free;
int t = g_OpenGLValues->m_free;
g_OpenGLValues->m_free = g_OpenGLValues->m_tex[g_OpenGLValues->m_free].m_next;
g_OpenGLValues->m_tex[g_OpenGLValues->m_free].m_prev = -1;
g_OpenGLValues->m_tex[t].m_next = g_OpenGLValues->m_tex[t].m_prev = -1;
}
}
GLenum APIENTRY glGetError (void)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glGetError" );
#endif
return GL_NO_ERROR;
}
void APIENTRY glGetFloatv (GLenum pname, GLfloat *params)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glGetFloatv: 0x%X 0x%X", pname, params );
#endif
switch (pname) {
case GL_MODELVIEW_MATRIX:
*((D3DMATRIX*)params) = g_OpenGLValues->m_xfrm[D3DTS_WORLD];
break;
case GL_PROJECTION_MATRIX:
*((D3DMATRIX*)params) = g_OpenGLValues->m_xfrm[D3DTS_PROJECTION];
break;
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper: Unimplemented GetFloatv query (0x%X)\n", pname );
OutputDebugStringA( junk );
#endif
}
}
void APIENTRY glGetIntegerv (GLenum pname, GLint *params)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glGetIntegerv: 0x%X 0x%X", pname, params );
#endif
switch(pname)
{
case GL_MAX_TEXTURE_SIZE:
*params = max(g_OpenGLValues->m_dd.MaxTextureWidth, g_OpenGLValues->m_dd.MaxTextureHeight);
break;
case GL_MAX_ACTIVE_TEXTURES_ARB:
*params = g_OpenGLValues->m_usemtex ? 2 : 1;
break;
case GL_PACK_LSB_FIRST:
case GL_PACK_SWAP_BYTES:
case GL_UNPACK_SWAP_BYTES:
case GL_UNPACK_LSB_FIRST:
*params = GL_FALSE;
break;
case GL_PACK_ROW_LENGTH:
case GL_UNPACK_ROW_LENGTH:
case GL_PACK_SKIP_ROWS:
case GL_PACK_SKIP_PIXELS:
case GL_UNPACK_SKIP_ROWS:
case GL_UNPACK_SKIP_PIXELS:
*params = 0;
break;
case GL_PACK_ALIGNMENT:
case GL_UNPACK_ALIGNMENT:
*params = 4;
break;
case GL_TEXTURE_1D:
*params = FALSE;
break;
case GL_TEXTURE_2D:
*params = TRUE;
break;
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper: Unimplemented GetIntegerv query (0x%X)\n", pname );
OutputDebugStringA( junk );
#endif
}
}
const GLubyte* APIENTRY glGetString (GLenum name)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glGetString: 0x%X", name );
#endif
if (!g_OpenGLValues->m_d3ddev)
return NULL; // No current RC!
switch(name) {
case GL_VENDOR:
return (const GLubyte*)"Microsoft Corp.";
case GL_RENDERER:
return (const GLubyte*)"Direct3D";
case GL_VERSION:
return (const GLubyte*)"1.1";
case GL_EXTENSIONS:
if(g_OpenGLValues->m_usemtex != FALSE)
return (const GLubyte*)"GL_ARB_multitexture GL_EXT_compiled_vertex_array GL_SGIS_multitexture";
else
return (const GLubyte*)"GL_EXT_compiled_vertex_array";
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper: Unimplemented GetString query (0x%X)\n", name );
OutputDebugStringA( junk );
#endif
}
return (const GLubyte*)"";
}
GLboolean APIENTRY glIsTexture (GLuint texture)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glIsTexture: 0x%X", texture );
#endif
if(texture != 0 && texture < MAXGLTEXHANDLES && g_OpenGLValues->m_tex[texture].m_block != 0)
{
return TRUE;
}
return FALSE;
}
void APIENTRY glLightf (GLenum light, GLenum pname, GLfloat param)
{
#if GETPARMSFORDEBUG
char log[256];
char p[40];
ftoa( (double)param, p );
sprintf( log, "glLightf: 0x%X 0x%X %s", light, pname, p );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
unsigned i = (DWORD)light - GL_LIGHT0;
switch(pname)
{
case GL_SPOT_EXPONENT:
g_OpenGLValues->m_light[i].Falloff = param;
break;
case GL_SPOT_CUTOFF:
g_OpenGLValues->m_light[i].Phi = param;
break;
case GL_CONSTANT_ATTENUATION:
g_OpenGLValues->m_light[i].Attenuation0 = param;
break;
case GL_LINEAR_ATTENUATION:
g_OpenGLValues->m_light[i].Attenuation1 = param;
break;
case GL_QUADRATIC_ATTENUATION:
g_OpenGLValues->m_light[i].Attenuation2 = param;
break;
}
g_OpenGLValues->m_lightdirty |= (1 << i);
}
void APIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params)
{
#if GETPARMSFORDEBUG
char log[256];
char p[40];
ftoa( (double)*params, p );
sprintf( log, "glLightfv: 0x%X 0x%X %s", light, pname, p );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
unsigned i = (DWORD)light - GL_LIGHT0;
switch(pname)
{
case GL_AMBIENT:
MEMCPY(&g_OpenGLValues->m_light[i].Ambient, params, sizeof(D3DCOLORVALUE));
break;
case GL_DIFFUSE:
MEMCPY(&g_OpenGLValues->m_light[i].Diffuse, params, sizeof(D3DCOLORVALUE));
break;
case GL_SPECULAR:
MEMCPY(&g_OpenGLValues->m_light[i].Specular, params, sizeof(D3DCOLORVALUE));
break;
case GL_POSITION:
MEMCPY(&g_OpenGLValues->m_light[i].Position, params, sizeof(D3DVECTOR));
g_OpenGLValues->m_lightPositionW[i] = params[3];
break;
case GL_SPOT_DIRECTION:
MEMCPY(&g_OpenGLValues->m_light[i].Direction, params, sizeof(D3DVECTOR));
break;
case GL_SPOT_EXPONENT:
g_OpenGLValues->m_light[i].Falloff = *params;
break;
case GL_SPOT_CUTOFF:
g_OpenGLValues->m_light[i].Phi = *params;
break;
case GL_CONSTANT_ATTENUATION:
g_OpenGLValues->m_light[i].Attenuation0 = *params;
break;
case GL_LINEAR_ATTENUATION:
g_OpenGLValues->m_light[i].Attenuation1 = *params;
break;
case GL_QUADRATIC_ATTENUATION:
g_OpenGLValues->m_light[i].Attenuation2 = *params;
break;
}
g_OpenGLValues->m_lightdirty |= (1 << i);
}
void APIENTRY glLightModelfv (GLenum pname, const GLfloat *params)
{
#if GETPARMSFORDEBUG
char log[256];
char p[40];
ftoa( (double)*params, p );
sprintf( log, "glLightModelfv: 0x%X %s", pname, p );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
static float two55 = 255.f;
unsigned int R, G, B, A;
switch(pname)
{
case GL_LIGHT_MODEL_AMBIENT:
R = (unsigned int)(params[0] * two55);
G = (unsigned int)(params[1] * two55);
B = (unsigned int)(params[2] * two55);
A = (unsigned int)(params[3] * two55);
if(R > 255)
R = 255;
if(G > 255)
G = 255;
if(B > 255)
B = 255;
if(A > 255)
A = 255;
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_AMBIENT, RGBA_MAKE(R, G, B, A));
break;
case GL_LIGHT_MODEL_TWO_SIDE:
#if DODPFS
if(*params != 0.f)
{
OutputDebugStringA("Wrapper: Two sided lighting not supported\n");
}
#endif
break;
case GL_LIGHT_MODEL_LOCAL_VIEWER:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_LOCALVIEWER, (DWORD)(*params));
break;
#if DODPFS
default:
OutputDebugStringA("Wrapper: LIGHT_MODEL_COLOR_CONTROL not supported\n" );
#endif
}
}
void APIENTRY glLightModeli (GLenum pname, GLint param)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glLightModeli: 0x%X 0x%X", pname, param );
#endif
switch(pname)
{
case GL_LIGHT_MODEL_TWO_SIDE:
#if DODPFS
if(param != 0)
{
OutputDebugStringA("Wrapper: Two sided lighting not supported\n" );
}
#endif
break;
case GL_LIGHT_MODEL_LOCAL_VIEWER:
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_LOCALVIEWER, param);
break;
#if DODPFS
default:
OutputDebugStringA("Wrapper: LIGHT_MODEL_COLOR_CONTROL not supported\n");
#endif
}
}
void APIENTRY glLoadMatrixf (const GLfloat *m)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glLoadMatrixf: 0x%X", m );
#endif
if(g_OpenGLValues->m_matrixMode == D3DTS_TEXTURE0)
{
g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt] = *((const D3DMATRIX*)m);
QuakeSetTransform((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), (const D3DMATRIX*)m);
}
else
{
g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode] = *((const D3DMATRIX*)m);
QuakeSetTransform(g_OpenGLValues->m_matrixMode, (const D3DMATRIX*)m);
}
}
void APIENTRY glLockArraysEXT(GLint first, GLsizei count)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glLockArraysEXT: 0x%X 0x%X", first, count );
#endif
g_OpenGLValues->m_lckfirst = first;
g_OpenGLValues->m_lckcount = count;
}
void APIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param)
{
#if GETPARMSFORDEBUG
char log[256];
char p[40];
ftoa( (double)param, p );
sprintf( log, "glMaterialf: 0x%X 0x%X %s", face, pname, p );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
{
switch(pname)
{
case GL_SHININESS:
g_OpenGLValues->m_material.Power = param;
break;
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper: Unimplemented Material (0x%X)\n", pname );
OutputDebugStringA( junk );
#endif
}
g_OpenGLValues->m_d3ddev->SetMaterial(&g_OpenGLValues->m_material);
}
#if DODPFS
else
{
OutputDebugStringA("Wrapper: Back face material properties ignored\n");
}
#endif
}
void APIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params)
{
#if GETPARMSFORDEBUG
char log[256];
char p[40];
ftoa( (double)*params, p );
sprintf( log, "glMaterialfv: 0x%X 0x%X %s", face, pname, p );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
{
switch(pname)
{
case GL_AMBIENT:
MEMCPY(&g_OpenGLValues->m_material.Ambient, params, sizeof(D3DCOLORVALUE));
break;
case GL_DIFFUSE:
MEMCPY(&g_OpenGLValues->m_material.Diffuse, params, sizeof(D3DCOLORVALUE));
break;
case GL_SPECULAR:
MEMCPY(&g_OpenGLValues->m_material.Specular, params, sizeof(D3DCOLORVALUE));
break;
case GL_EMISSION:
MEMCPY(&g_OpenGLValues->m_material.Emissive, params, sizeof(D3DCOLORVALUE));
break;
case GL_SHININESS:
g_OpenGLValues->m_material.Power = *params;
break;
case GL_AMBIENT_AND_DIFFUSE:
MEMCPY(&g_OpenGLValues->m_material.Ambient, params, sizeof(D3DCOLORVALUE));
MEMCPY(&g_OpenGLValues->m_material.Diffuse, params, sizeof(D3DCOLORVALUE));
break;
#if DODPFS
default:
char junk[256];
sprintf( junk, "Wrapper: Unimplemented Material (0x%X)\n", pname );
OutputDebugStringA( junk );
#endif
}
g_OpenGLValues->m_d3ddev->SetMaterial(&g_OpenGLValues->m_material);
}
#if DODPFS
else
{
OutputDebugStringA("Wrapper: Back face material properties ignored\n");
}
#endif
}
void APIENTRY glMTexCoord2fSGIS(GLenum target, GLfloat s, GLfloat t)
{
#if GETPARMSFORDEBUG
char log[256];
char ps[40];
char pt[40];
ftoa( (double)s, ps );
ftoa( (double)t, pt );
sprintf( log, "glMTexCoord2fSGIS: 0x%X %s %s", target, ps, pt );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
if(target == GL_TEXTURE0_SGIS) {
g_OpenGLValues->m_tu = s;
g_OpenGLValues->m_tv = t;
}
else {
g_OpenGLValues->m_tu2 = s;
g_OpenGLValues->m_tv2 = t;
}
}
void APIENTRY glMultiTexCoord2fARB (GLenum texture, GLfloat s, GLfloat t)
{
#if GETPARMSFORDEBUG
char log[256];
char ps[40];
char pt[40];
ftoa( (double)s, ps );
ftoa( (double)t, pt );
sprintf( log, "glMultiTexCoord2fARB: 0x%X %s %s", texture, ps, pt );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
if(texture == GL_TEXTURE0_ARB)
{
g_OpenGLValues->m_tu = s;
g_OpenGLValues->m_tv = t;
}
else
{
g_OpenGLValues->m_tu2 = s;
g_OpenGLValues->m_tv2 = t;
}
}
void APIENTRY glMultiTexCoord2fvARB (GLenum texture, const GLfloat *t)
{
#if GETPARMSFORDEBUG
char log[256];
char ps[40];
char pt[40];
ftoa( (double)t[0], ps );
ftoa( (double)t[1], pt );
sprintf( log, "glMultiTexCoord2fvARB: 0x%X %s %s", texture, ps, pt );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
if(texture == GL_TEXTURE0_ARB)
{
g_OpenGLValues->m_tu = t[0];
g_OpenGLValues->m_tv = t[1];
}
else
{
g_OpenGLValues->m_tu2 = t[0];
g_OpenGLValues->m_tv2 = t[1];
}
}
void APIENTRY glMultMatrixd (const GLdouble *m)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glMultMatrixd: 0x%X", m );
#endif
D3DMATRIX f;
for(unsigned i = 0; i < 16; ++i)
{
((FLOAT*)&f)[i] = (FLOAT)m[i];
}
if(g_OpenGLValues->m_matrixMode == D3DTS_TEXTURE0)
{
MultiplyMatrix((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), f);
QuakeSetTransform((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), &g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt]);
}
else
{
MultiplyMatrix(g_OpenGLValues->m_matrixMode, f);
QuakeSetTransform(g_OpenGLValues->m_matrixMode, &g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode]);
}
}
void APIENTRY glMultMatrixf (const GLfloat *m)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glMultMatrixf: 0x%X", m );
#endif
if(g_OpenGLValues->m_matrixMode == D3DTS_TEXTURE0)
{
MultiplyMatrix((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), *((const D3DMATRIX*)m));
QuakeSetTransform((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), &g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt]);
}
else
{
MultiplyMatrix(g_OpenGLValues->m_matrixMode, *((const D3DMATRIX*)m));
QuakeSetTransform(g_OpenGLValues->m_matrixMode, &g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode]);
}
}
void APIENTRY glNormal3bv (const GLbyte *v)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glNormal3bv: 0x%X 0x%X 0x%X", v[0], v[1], v[2] );
#endif
g_OpenGLValues->m_nx = v[0];
g_OpenGLValues->m_ny = v[1];
g_OpenGLValues->m_nz = v[2];
}
void APIENTRY glNormal3fv (const GLfloat *v)
{
#if GETPARMSFORDEBUG
char log[256];
char v0[40];
char v1[40];
char v2[40];
ftoa( (double)v[0], v0 );
ftoa( (double)v[1], v1 );
ftoa( (double)v[2], v2 );
sprintf( log, "glNormal3fv: %s %s %s", v0, v1, v2 );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
g_OpenGLValues->m_nx = v[0];
g_OpenGLValues->m_ny = v[1];
g_OpenGLValues->m_nz = v[2];
}
void APIENTRY glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
{
#if GETPARMSFORDEBUG
char log[256];
char l[40], r[40], b[40], t[40], zn[40], zf[40];
ftoa( (double)left, l );
ftoa( (double)right, r );
ftoa( (double)bottom, b );
ftoa( (double)top, t );
ftoa( (double)zNear, zn );
ftoa( (double)zFar, zf );
sprintf( log, "glOrtho: %s %s %s %s %s %s", l, r, b, t, zn, zf );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
D3DMATRIX f;
f._11 = (FLOAT)(2.0 / (right - left));
f._21 = 0.f;
f._31 = 0.f;
f._41 = (FLOAT)(-(right + left) / (right - left));
f._12 = 0.f;
f._22 = (FLOAT)(2.0 / (top - bottom));
f._32 = 0.f;
f._42 = (FLOAT)(-(top + bottom) / (top - bottom));
f._13 = 0.f;
f._23 = 0.f;
f._33 = (FLOAT)(-2.0 / (zFar - zNear));
f._43 = (FLOAT)(-(zFar + zNear) / (zFar - zNear));
f._14 = 0.f;
f._24 = 0.f;
f._34 = 0.f;
f._44 = 1.f;
if(g_OpenGLValues->m_matrixMode == D3DTS_TEXTURE0)
{
MultiplyMatrix((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), f);
QuakeSetTransform((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), &g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt]);
}
else
{
MultiplyMatrix(g_OpenGLValues->m_matrixMode, f);
QuakeSetTransform(g_OpenGLValues->m_matrixMode, &g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode]);
}
}
void APIENTRY glPolygonMode (GLenum face, GLenum mode)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glPolygonMode: 0x%X 0x%X", face, mode );
#endif
int statevalue=-1;
switch(mode) {
case GL_POINT:
statevalue=D3DFILL_POINT;
break;
case GL_LINE:
statevalue=D3DFILL_WIREFRAME;
break;
case GL_FILL:
statevalue=D3DFILL_SOLID;
break;
}
if(statevalue >= 0) {
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_FILLMODE, (DWORD)statevalue);
}
}
void APIENTRY glPolygonOffset (GLfloat factor, GLfloat units)
{
#if GETPARMSFORDEBUG
char log[256];
char f[40];
char u[40];
ftoa( (double)factor, f );
ftoa( (double)units, u );
sprintf( log, "glPolygonOffset: %s %s", f, u );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
}
void APIENTRY glPopAttrib (void)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glPopAttrib" );
#endif
g_OpenGLValues->m_d3ddev->ApplyStateBlock(g_OpenGLValues->m_cbufbit);
}
void APIENTRY glPopMatrix (void)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glPopMatrix" );
#endif
if(g_OpenGLValues->m_matrixMode == D3DTS_WORLD) {
if(g_OpenGLValues->m_matrixStack[0].length() == 0)
return;
LListManip<D3DMATRIX> m(&g_OpenGLValues->m_matrixStack[0]);
g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode] = m();
QuakeSetTransform(g_OpenGLValues->m_matrixMode, &(m()));
m.remove();
}
else if(g_OpenGLValues->m_matrixMode == D3DTS_PROJECTION) {
if(g_OpenGLValues->m_matrixStack[1].length() == 0)
return;
LListManip<D3DMATRIX> m(&g_OpenGLValues->m_matrixStack[1]);
g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode] = m();
QuakeSetTransform(g_OpenGLValues->m_matrixMode, &(m()));
m.remove();
}
else {
if(g_OpenGLValues->m_matrixStack[2 + g_OpenGLValues->m_curtgt].length() == 0)
return;
LListManip<D3DMATRIX> m(&g_OpenGLValues->m_matrixStack[2 + g_OpenGLValues->m_curtgt]);
g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt] = m();
QuakeSetTransform((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), &(m()));
m.remove();
}
}
void APIENTRY glPushAttrib (GLbitfield mask)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glPushAttrib: 0x%X", mask );
#endif
if(mask & GL_COLOR_BUFFER_BIT)
{
g_OpenGLValues->m_d3ddev->CaptureStateBlock(g_OpenGLValues->m_cbufbit);
}
#if DODPFS
else
{
char junk[256];
sprintf( junk, "Wrapper: Attrib push not implemented (0x%X)\n", mask );
OutputDebugStringA( junk );
}
#endif
}
void APIENTRY glPushMatrix (void)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glPushMatrix" );
#endif
if(g_OpenGLValues->m_matrixMode == D3DTS_WORLD)
{
g_OpenGLValues->m_matrixStack[0].prepend(g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode]);
}
else if(g_OpenGLValues->m_matrixMode == D3DTS_PROJECTION)
{
g_OpenGLValues->m_matrixStack[1].prepend(g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode]);
}
else
{
g_OpenGLValues->m_matrixStack[2 + g_OpenGLValues->m_curtgt].prepend(g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt]);
}
}
void APIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
{
#if GETPARMSFORDEBUG
char log[256];
char va[40];
char vx[40];
char vy[40];
char vz[40];
ftoa( (double)angle, va );
ftoa( (double)x, vx );
ftoa( (double)y, vy );
ftoa( (double)z, vz );
sprintf( log, "glRotatef: %s %s %s %s", va, vx, vy, vz );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
if(angle == 0.f)
{
// Early out for Quake II engine since angle = 0 does not prevent the matrix from getting bad when x, y & z are 0.
return;
}
float u[3];
double norm = sqrt(x * x + y * y + z * z);
u[0] = (float)(x / norm);
u[1] = (float)(y / norm);
u[2] = (float)(z / norm);
double ra = angle * PI / 180.f;
float ca = (float)cos(ra);
float sa = (float)sin(ra);
D3DMATRIX s;
s._11 = 0.f; s._21 = -u[2]; s._31 = u[1];
s._12 = u[2]; s._22 = 0.f; s._32 = -u[0];
s._13 = -u[1]; s._23 = u[0]; s._33 = 0.f;
D3DMATRIX uu;
uu._11 = u[0] * u[0]; uu._21 = u[0] * u[1]; uu._31 = u[0] * u[2];
uu._12 = u[1] * u[0]; uu._22 = u[1] * u[1]; uu._32 = u[1] * u[2];
uu._13 = u[2] * u[0]; uu._23 = u[2] * u[1]; uu._33 = u[2] * u[2];
D3DMATRIX r;
r._11 = uu._11 + ca * (1.f - uu._11) + sa * s._11;
r._21 = uu._21 + ca * (0.f - uu._21) + sa * s._21;
r._31 = uu._31 + ca * (0.f - uu._31) + sa * s._31;
r._41 = 0.f;
r._12 = uu._12 + ca * (0.f - uu._12) + sa * s._12;
r._22 = uu._22 + ca * (1.f - uu._22) + sa * s._22;
r._32 = uu._32 + ca * (0.f - uu._32) + sa * s._32;
r._42 = 0.f;
r._13 = uu._13 + ca * (0.f - uu._13) + sa * s._13;
r._23 = uu._23 + ca * (0.f - uu._23) + sa * s._23;
r._33 = uu._33 + ca * (1.f - uu._33) + sa * s._33;
r._43 = 0.f;
r._14 = 0.f;
r._24 = 0.f;
r._34 = 0.f;
r._44 = 1.f;
if(g_OpenGLValues->m_matrixMode == D3DTS_TEXTURE0)
{
MultiplyMatrix((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), r);
QuakeSetTransform((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), &g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt]);
}
else
{
MultiplyMatrix(g_OpenGLValues->m_matrixMode, r);
QuakeSetTransform(g_OpenGLValues->m_matrixMode, &g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode]);
}
}
void APIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z)
{
#if GETPARMSFORDEBUG
char log[256];
char vx[40];
char vy[40];
char vz[40];
ftoa( (double)x, vx );
ftoa( (double)y, vy );
ftoa( (double)z, vz );
sprintf( log, "glScalef: %s %s %s", vx, vy, vz );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
D3DMATRIX f;
f._11 = x; f._21 = 0.f; f._31 = 0.f; f._41 = 0.f;
f._12 = 0.f; f._22 = y; f._32 = 0.f; f._42 = 0.f;
f._13 = 0.f; f._23 = 0.f; f._33 = z; f._43 = 0.f;
f._14 = 0.f; f._24 = 0.f; f._34 = 0.f; f._44 = 1.f;
if(g_OpenGLValues->m_matrixMode == D3DTS_TEXTURE0)
{
MultiplyMatrix((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), f);
QuakeSetTransform((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), &g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt]);
}
else
{
MultiplyMatrix(g_OpenGLValues->m_matrixMode, f);
QuakeSetTransform(g_OpenGLValues->m_matrixMode, &g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode]);
}
}
void APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glScissor: 0x%X 0x%X 0x%X 0x%X", x, y, width, height );
#endif
RECT wrect, screct, xrect;
wrect.left = 0;
wrect.top = 0;
wrect.right = g_OpenGLValues->m_winWidth;
wrect.bottom = g_OpenGLValues->m_winHeight;
screct.left = x;
screct.top = y;
screct.right = x + width;
screct.bottom = y + height;
IntersectRect(&xrect, &wrect, &screct);
// LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glScissor: %d %d %d %d WRECT: %d %d %d %d SCRECT: %d %d %d %d XRECT %d %d %d %d", x, y, width, height, wrect.left, wrect.top, wrect.right, wrect.bottom, screct.left, screct.top, screct.right, screct.bottom, xrect.left, xrect.top, xrect.right, xrect.bottom );
g_OpenGLValues->m_scix = xrect.left;
g_OpenGLValues->m_sciy = xrect.top;
g_OpenGLValues->m_sciw = xrect.right - xrect.left;
g_OpenGLValues->m_scih = xrect.bottom - xrect.top;
g_OpenGLValues->m_updvwp = TRUE;
}
void APIENTRY glSelectTextureSGIS(GLenum target)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glSelectTextureSGIS: 0x%X", target );
#endif
g_OpenGLValues->m_curtgt = target == GL_TEXTURE0_SGIS ? 0 : 1;
}
void APIENTRY glShadeModel (GLenum mode)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glShadeModel: 0x%X", mode );
#endif
if(mode == GL_SMOOTH)
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
else
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
}
void APIENTRY glTexCoord2f (GLfloat s, GLfloat t)
{
#if GETPARMSFORDEBUG
char log[256];
char ps[40];
char pt[40];
ftoa( (double)s, ps );
ftoa( (double)t, pt );
sprintf( log, "glTexCoord2f: %s %s", ps, pt );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
g_OpenGLValues->m_tu = s;
g_OpenGLValues->m_tv = t;
}
void APIENTRY glTexCoord2fv (const GLfloat *t)
{
#if GETPARMSFORDEBUG
char log[256];
char ps[40];
char pt[40];
ftoa( (double)t[0], ps );
ftoa( (double)t[1], pt );
sprintf( log, "glTexCoord2fv: %s %s", ps, pt );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
g_OpenGLValues->m_tu = t[0];
g_OpenGLValues->m_tv = t[1];
}
void APIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glTexCoordPointer: 0x%X 0x%X 0x%X 0x%X", size, type, stride, pointer );
#endif
if(size == 2 && type == GL_FLOAT)
g_OpenGLValues->m_texcoordary[g_OpenGLValues->m_client_active_texture_arb] = (GLfloat*)pointer;
#if DODPFS
else
{
char junk[256];
sprintf( junk, "TexCoord array not supported (size:0x%X type:0x%X)\n", size, type );
OutputDebugStringA( junk );
}
#endif
if(stride == 0)
{
stride = 8;
}
g_OpenGLValues->m_texcoordarystride[g_OpenGLValues->m_client_active_texture_arb] = stride;
}
void APIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param)
{
#if GETPARMSFORDEBUG
char log[256];
sprintf( log, "glTexEnvf: 0x%X 0x%X 0x%X", target, pname, (int)param );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
if(pname == GL_TEXTURE_ENV_MODE) {
g_OpenGLValues->m_blendmode[g_OpenGLValues->m_curtgt] = (int)param;
g_OpenGLValues->m_texHandleValid = FALSE;
}
#if DODPFS
else
{
char junk[256];
sprintf( junk, "Wrapper: GL_TEXTURE_ENV_COLOR not implemented (0x%X)\n", pname );
OutputDebugStringA( junk );
}
#endif
}
void APIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glTexEnvi: 0x%X 0x%X 0x%X", target, pname, param );
#endif
if(pname == GL_TEXTURE_ENV_MODE) {
g_OpenGLValues->m_blendmode[g_OpenGLValues->m_curtgt] = param;
g_OpenGLValues->m_texHandleValid = FALSE;
}
#if DODPFS
else
{
char junk[256];
sprintf( junk, "Wrapper: GL_TEXTURE_ENV_COLOR not implemented (0x%X)\n", pname );
OutputDebugStringA( junk );
}
#endif
}
void APIENTRY glTexGeni (GLenum coord, GLenum pname, GLint param)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glTexGeni: 0x%X 0x%X 0x%X", coord, pname, param );
#endif
if(coord == GL_S)
{
if(pname == GL_TEXTURE_GEN_MODE)
{
if(param == GL_SPHERE_MAP)
{
g_OpenGLValues->m_d3ddev->SetTextureStageState(g_OpenGLValues->m_curtgt, D3DTSS_TEXCOORDINDEX, g_OpenGLValues->m_curtgt | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
}
#if DODPFS
else
{
char junk[256];
sprintf( junk, "Wrapper: TexGen param not implemented (0x%X)\n", param );
OutputDebugStringA( junk );
}
#endif
}
#if DODPFS
else
{
char junk[256];
sprintf( junk, "Wrapper: TexGen pname not implemented (0x%X)\n", pname );
OutputDebugStringA( junk );
}
#endif
}
}
void APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei glwidth, GLsizei glheight, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glTexImage2D: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X", target, level, internalformat, glwidth, glheight, border, format, type, pixels );
#endif
DWORD width, height;
TexInfo &ti = g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]];
if(ti.m_next >= 0)
{
if(ti.m_prev < 0)
{
g_OpenGLValues->m_free = ti.m_next;
g_OpenGLValues->m_tex[ti.m_next].m_prev = ti.m_prev;
ti.m_next = ti.m_prev = -1;
}
else
{
g_OpenGLValues->m_tex[ti.m_prev].m_next = ti.m_next;
g_OpenGLValues->m_tex[ti.m_next].m_prev = ti.m_prev;
ti.m_next = ti.m_prev = -1;
}
}
/* See if texture needs to be subsampled */
if(g_OpenGLValues->m_subsample) {
if(glwidth > 256 || glheight > 256) {
if(glwidth > glheight) {
width = 256;
height = (glheight * 256) / glwidth;
}
else {
height = 256;
width = (glwidth * 256) / glheight;
}
}
else {
width = glwidth;
height = glheight;
}
}
else {
width = glwidth;
height = glheight;
}
/* See if texture needs to be square */
if(g_OpenGLValues->m_makeSquare) {
if(height > width) {
width = height;
}
else {
height = width;
}
}
if(level == 0) {
IDirect3DTexture8 *ddsurf;
D3DFORMAT fmt;
switch(internalformat) {
case 1:
case GL_LUMINANCE:
case GL_LUMINANCE8:
fmt = g_OpenGLValues->m_ddLuminanceSurfFormat;
break;
case 3:
case GL_RGB:
case GL_RGB5:
fmt = g_OpenGLValues->m_ddFiveBitSurfFormat;
break;
case 4:
case GL_RGBA:
case GL_RGBA4:
fmt = g_OpenGLValues->m_ddFourBitAlphaSurfFormat;
break;
case GL_RGB8:
fmt = g_OpenGLValues->m_ddEightBitSurfFormat;
break;
case GL_RGBA8:
fmt = g_OpenGLValues->m_ddEightBitAlphaSurfFormat;
break;
case GL_ALPHA:
case GL_ALPHA8:
fmt = g_OpenGLValues->m_ddEightBitAlphaOnlySurfFormat;
break;
default:
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: Unimplemented internalformat (0x%X)\n", internalformat );
OutputDebugStringA( junk );
#endif
return;
}
HRESULT ddrval = g_OpenGLValues->m_d3ddev->CreateTexture(width,
height,
1, // levels
0,
fmt,
D3DPOOL_MANAGED,
&ddsurf);
if (FAILED(ddrval))
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: CreateTexture failed (0x%X)\n", ddrval );
OutputDebugStringA( junk );
#endif
return;
}
LPDIRECT3DSURFACE8 pLevel;
ddrval = ddsurf->GetSurfaceLevel(0, &pLevel);
if (FAILED(ddrval))
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: Failed to retrieve surface (0x%X)\n", ddrval );
OutputDebugStringA( junk );
#endif
return;
}
LoadSurface(pLevel, format, internalformat, glwidth, glheight, width, height, (const DWORD*)pixels);
pLevel->Release();
if(ti.m_ddsurf != 0) {
ti.m_ddsurf->Release();
}
ti.m_dwStage = g_OpenGLValues->m_curtgt;
ti.m_fmt = fmt;
ti.m_internalformat = internalformat;
ti.m_width = width;
ti.m_height = height;
ti.m_ddsurf = ddsurf;
ti.m_oldwidth = glwidth;
ti.m_oldheight = glheight;
if(ti.m_block == 0)
{
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (g_OpenGLValues->m_curtgt, D3DTSS_ADDRESSU,ti.m_addu);
g_OpenGLValues->m_d3ddev->SetTextureStageState (g_OpenGLValues->m_curtgt, D3DTSS_ADDRESSV,ti.m_addv);
g_OpenGLValues->m_d3ddev->SetTextureStageState (g_OpenGLValues->m_curtgt, D3DTSS_MAGFILTER,ti.m_magmode);
g_OpenGLValues->m_d3ddev->SetTextureStageState (g_OpenGLValues->m_curtgt, D3DTSS_MINFILTER,ti.m_minmode);
g_OpenGLValues->m_d3ddev->SetTextureStageState (g_OpenGLValues->m_curtgt, D3DTSS_MIPFILTER,ti.m_mipmode);
g_OpenGLValues->m_d3ddev->SetTexture(g_OpenGLValues->m_curtgt, ti.m_ddsurf);
g_OpenGLValues->m_d3ddev->EndStateBlock(&ti.m_block);
ti.m_capture = FALSE;
}
else
{
ti.m_capture = TRUE;
}
}
else if(level == 1 && g_OpenGLValues->m_usemipmap) { // oops, a mipmap
IDirect3DTexture8 *ddsurf;
LPDIRECT3DSURFACE8 pLevel, pSrcLevel;
HRESULT ddrval = g_OpenGLValues->m_d3ddev->CreateTexture(ti.m_width,
ti.m_height,
miplevels(ti.m_width, ti.m_height),
0,
ti.m_fmt,
D3DPOOL_MANAGED,
&ddsurf);
if (FAILED(ddrval)) {
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: CreateTexture failed (0x%X)\n", ddrval );
OutputDebugStringA( junk );
#endif
return;
}
ddsurf->GetSurfaceLevel(0, &pLevel);
ti.m_ddsurf->GetSurfaceLevel(0, &pSrcLevel);
ddrval = g_OpenGLValues->m_d3ddev->CopyRects(pSrcLevel, NULL, 0, pLevel, NULL);
if(FAILED(ddrval))
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: CopyRects failed (0x%X)\n", ddrval );
OutputDebugStringA( junk );
#endif
return;
}
pLevel->Release();
pSrcLevel->Release();
ti.m_ddsurf->Release();
ti.m_ddsurf = ddsurf;
ti.m_ddsurf->GetSurfaceLevel(1, &pLevel);
LoadSurface(pLevel, format, internalformat, glwidth, glheight, width, height, (const DWORD*)pixels);
pLevel->Release();
ti.m_capture = TRUE;
}
else if(g_OpenGLValues->m_usemipmap) {
if (ti.m_ddsurf!=NULL)
{
LPDIRECT3DSURFACE8 pLevel;
ti.m_ddsurf->GetSurfaceLevel(level, &pLevel);
LoadSurface(pLevel, format, internalformat, glwidth, glheight, width, height, (const DWORD*)pixels);
pLevel->Release();
}
#if DODPFS
else
{
char junk[256];
sprintf( junk, "NULL surface pointer %d %d %d %d %d %d %d\n", level, ti.m_width, ti.m_height, glwidth, glheight, width, height );
OutputDebugStringA( junk );
}
#endif
}
g_OpenGLValues->m_texHandleValid = FALSE;
}
void APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glTexSubImage2D: 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X 0x%X", target, level, xoffset, yoffset, width, height, format, type, pixels );
#endif
if(level > 1 && !g_OpenGLValues->m_usemipmap)
return;
TexInfo &ti = g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]];
RECT subimage;
LPDIRECT3DSURFACE8 pLevel;
HRESULT ddrval = ti.m_ddsurf->GetSurfaceLevel(level, &pLevel);
if (FAILED(ddrval))
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: Failed to retrieve surface (0x%X)\n", ddrval );
OutputDebugStringA( junk );
#endif
return;
}
xoffset = (xoffset * ti.m_width) / ti.m_oldwidth;
yoffset = (yoffset * ti.m_height) / ti.m_oldheight;
SetRect(&subimage, xoffset, yoffset,
(width * ti.m_width) / ti.m_oldwidth + xoffset,
(height * ti.m_height) / ti.m_oldheight + yoffset);
ddrval = LoadSubSurface( pLevel, format, ti.m_internalformat, width, height, (const DWORD*)pixels, &subimage );
if (FAILED(ddrval)) {
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: LoadSubSurface Failure (0x%X)\n", ddrval );
OutputDebugStringA( junk );
#endif
// return;
}
pLevel->Release();
}
void APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param)
{
#if GETPARMSFORDEBUG
char log[256];
sprintf( log, "glTexParameterf: 0x%X 0x%X 0x%X", target, pname, (int)param );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
switch(pname) {
case GL_TEXTURE_MIN_FILTER:
switch((int)param) {
case GL_NEAREST:
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_minmode = D3DTEXF_POINT;
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_mipmode = D3DTEXF_NONE;
break;
case GL_LINEAR:
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_minmode = D3DTEXF_LINEAR;
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_mipmode = D3DTEXF_NONE;
break;
case GL_NEAREST_MIPMAP_NEAREST:
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_minmode = D3DTEXF_POINT;
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_mipmode = D3DTEXF_POINT;
break;
case GL_NEAREST_MIPMAP_LINEAR:
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_minmode = D3DTEXF_POINT;
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_mipmode = D3DTEXF_LINEAR;
break;
case GL_LINEAR_MIPMAP_NEAREST:
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_minmode = D3DTEXF_LINEAR;
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_mipmode = D3DTEXF_POINT;
break;
case GL_LINEAR_MIPMAP_LINEAR:
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_minmode = D3DTEXF_LINEAR;
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_mipmode = D3DTEXF_LINEAR;
break;
}
break;
case GL_TEXTURE_MAG_FILTER:
if((int)param == GL_NEAREST)
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_magmode = D3DTEXF_POINT;
else
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_magmode = D3DTEXF_LINEAR;
break;
case GL_TEXTURE_WRAP_S:
if((int)param == GL_CLAMP)
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_addu = D3DTADDRESS_CLAMP;
else
//GL_REPEAT falls here
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_addu = D3DTADDRESS_WRAP;
break;
case GL_TEXTURE_WRAP_T:
if((int)param == GL_CLAMP)
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_addv = D3DTADDRESS_CLAMP;
else
//GL_REPEAT falls here
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_addv = D3DTADDRESS_WRAP;
break;
}
g_OpenGLValues->m_tex[g_OpenGLValues->m_curstagebinding[g_OpenGLValues->m_curtgt]].m_capture = TRUE;
g_OpenGLValues->m_texHandleValid = FALSE;
}
void APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glTexParameteri: 0x%X 0x%X 0x%X", target, pname, param );
#endif
glTexParameterf(target, pname, (GLfloat)param);
}
void APIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z)
{
#if GETPARMSFORDEBUG
char log[256];
char vx[40];
char vy[40];
char vz[40];
ftoa( (double)x, vx );
ftoa( (double)y, vy );
ftoa( (double)z, vz );
sprintf( log, "glTranslatef: %s %s %s", vx, vy, vz );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
D3DMATRIX f;
f._11 = 1.f; f._21 = 0.f; f._31 = 0.f; f._41 = x;
f._12 = 0.f; f._22 = 1.f; f._32 = 0.f; f._42 = y;
f._13 = 0.f; f._23 = 0.f; f._33 = 1.f; f._43 = z;
f._14 = 0.f; f._24 = 0.f; f._34 = 0.f; f._44 = 1.f;
if(g_OpenGLValues->m_matrixMode == D3DTS_TEXTURE0)
{
MultiplyMatrix((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), f);
QuakeSetTransform((D3DTRANSFORMSTATETYPE)(g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt), &g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode + g_OpenGLValues->m_curtgt]);
}
else
{
MultiplyMatrix(g_OpenGLValues->m_matrixMode, f);
QuakeSetTransform(g_OpenGLValues->m_matrixMode, &g_OpenGLValues->m_xfrm[g_OpenGLValues->m_matrixMode]);
}
}
void APIENTRY glUnlockArraysEXT()
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glUnlockArraysEXT" );
#endif
g_OpenGLValues->m_lckfirst = 0;
g_OpenGLValues->m_lckcount = 0;
}
void APIENTRY glVertex2d (GLdouble x, GLdouble y)
{
#if GETPARMSFORDEBUG
char log[256];
char vx[40];
char vy[40];
ftoa( (double)x, vx );
ftoa( (double)y, vy );
sprintf( log, "glVertex2d: %s %s", vx, vy );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat)x;
*(d3dv++) = (GLfloat)y;
*(d3dv++) = 0.f;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex2dv (const GLdouble *v)
{
#if GETPARMSFORDEBUG
char log[256];
char vx[40];
char vy[40];
ftoa( (double)v[0], vx );
ftoa( (double)v[1], vy );
sprintf( log, "glVertex2dv: %s %s", vx, vy );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat)*(v++);
*(d3dv++) = (GLfloat)*(v++);
*(d3dv++) = 0.f;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex2f (GLfloat x, GLfloat y)
{
#if GETPARMSFORDEBUG
char log[256];
char vx[40];
char vy[40];
ftoa( (double)x, vx );
ftoa( (double)y, vy );
sprintf( log, "glVertex2f: %s %s", vx, vy );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = x;
*(d3dv++) = y;
*(d3dv++) = 0.f;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex2fv (const GLfloat *v)
{
#if GETPARMSFORDEBUG
char log[256];
char vx[40];
char vy[40];
ftoa( (double)v[0], vx );
ftoa( (double)v[1], vy );
sprintf( log, "glVertex2fv: %s %s", vx, vy );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = *(v++);
*(d3dv++) = *(v++);
*(d3dv++) = 0.f;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex2i (GLint x, GLint y)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glVertex2i: %d %d", x, y );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat)x;
*(d3dv++) = (GLfloat)y;
*(d3dv++) = 0.f;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex2iv (const GLint *v)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glVertex2iv: %d %d", v[0], v[1] );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = 0.f;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex2s (GLshort x, GLshort y)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glVertex2s: %d %d", x, y );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat)x;
*(d3dv++) = (GLfloat)y;
*(d3dv++) = 0.f;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex2sv (const GLshort *v)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glVertex2sv: %s %s", v[0], v[1] );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = 0.f;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z)
{
#if GETPARMSFORDEBUG
char log[256];
char vx[40];
char vy[40];
char vz[40];
ftoa( (double)x, vx );
ftoa( (double)y, vy );
ftoa( (double)z, vz );
sprintf( log, "glVertex3d: %s %s %s", vx, vy, vz );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat) x;
*(d3dv++) = (GLfloat) y;
*(d3dv++) = (GLfloat) z;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex3dv (const GLdouble *v)
{
#if GETPARMSFORDEBUG
char log[256];
char vx[40];
char vy[40];
char vz[40];
ftoa( (double)v[0], vx );
ftoa( (double)v[1], vy );
ftoa( (double)v[2], vz );
sprintf( log, "glVertex3dv: %s %s %s", vx, vy, vz );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = (GLfloat) *(v++);
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z)
{
#if GETPARMSFORDEBUG
char log[256];
char vx[40];
char vy[40];
char vz[40];
ftoa( (double)x, vx );
ftoa( (double)y, vy );
ftoa( (double)z, vz );
sprintf( log, "glVertex3f: %s %s %s", vx, vy, vz );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = x;
*(d3dv++) = y;
*(d3dv++) = z;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex3fv (const GLfloat *v)
{
#if GETPARMSFORDEBUG
char log[256];
char vx[40];
char vy[40];
char vz[40];
ftoa( (double)v[0], vx );
ftoa( (double)v[1], vy );
ftoa( (double)v[2], vz );
sprintf( log, "glVertex3fv: %s %s %s", vx, vy, vz );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = *(v++);
*(d3dv++) = *(v++);
*(d3dv++) = *(v++);
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex3i (GLint x, GLint y, GLint z)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glVertex3i: %d %d %d", x, y, z );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat)x;
*(d3dv++) = (GLfloat)y;
*(d3dv++) = (GLfloat)z;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex3iv (const GLint *v)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glVertex3iv: %d %d %d", v[0], v[1], v[2] );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = (GLfloat) *(v++);
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex3s (GLshort x, GLshort y, GLshort z)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glVertex3s: %d %d %d", x, y, z );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat)x;
*(d3dv++) = (GLfloat)y;
*(d3dv++) = (GLfloat)z;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex3sv (const GLshort *v)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glVertex3sv: %d %d %d", v[0], v[1], v[2] );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = (GLfloat) *(v++);
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w)
{
#if GETPARMSFORDEBUG
char log[256];
char vx[40];
char vy[40];
char vz[40];
char vw[40];
ftoa( (double)x, vx );
ftoa( (double)y, vy );
ftoa( (double)z, vz );
ftoa( (double)w, vw );
sprintf( log, "glVertex4d: %s %s %s %s", vx, vy, vz, vw );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat)x;
*(d3dv++) = (GLfloat)y;
*(d3dv++) = (GLfloat)z;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex4dv (const GLdouble *v)
{
#if GETPARMSFORDEBUG
char log[256];
char vx[40];
char vy[40];
char vz[40];
char vw[40];
ftoa( (double)v[0], vx );
ftoa( (double)v[1], vy );
ftoa( (double)v[2], vz );
ftoa( (double)v[3], vw );
sprintf( log, "glVertex4dv: %s %s %s %s", vx, vy, vz, vw );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = (GLfloat) *(v++);
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
#if GETPARMSFORDEBUG
char log[256];
char vx[40];
char vy[40];
char vz[40];
char vw[40];
ftoa( (double)x, vx );
ftoa( (double)x, vy );
ftoa( (double)y, vz );
ftoa( (double)w, vw );
sprintf( log, "glVertex4f: %s %s %s %s", vx, vy, vz, vw );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = x;
*(d3dv++) = y;
*(d3dv++) = z;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex4fv (const GLfloat *v)
{
#if GETPARMSFORDEBUG
char log[256];
char vx[40];
char vy[40];
char vz[40];
char vw[40];
ftoa( (double)v[0], vx );
ftoa( (double)v[1], vy );
ftoa( (double)v[2], vz );
ftoa( (double)v[3], vw );
sprintf( log, "glVertex4fv: %s %s %s %s", vx, vy, vz, vw );
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, log );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = *(v++);
*(d3dv++) = *(v++);
*(d3dv++) = *(v++);
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glVertex4i: %d %d %d %d", x, y, z, w );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat)x;
*(d3dv++) = (GLfloat)y;
*(d3dv++) = (GLfloat)z;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex4iv (const GLint *v)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glVertex4iv: %d %d %d %d", v[0], v[1], v[2], v[3] );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = (GLfloat) *(v++);
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glVertex4s: %d %d %d %d", x, y, z, w );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat)x;
*(d3dv++) = (GLfloat)y;
*(d3dv++) = (GLfloat)z;
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertex4sv (const GLshort *v)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glVertex4sv: %d %d %d %d", v[0], v[1], v[2], v[3] );
#endif
VertexBufferFilled();
FLOAT *d3dv = (FLOAT*)&g_OpenGLValues->m_verts[g_OpenGLValues->m_vcnt++];
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = (GLfloat) *(v++);
*(d3dv++) = (GLfloat) *(v++);
MEMCPY(d3dv, &g_OpenGLValues->m_nx, sizeof(FLOAT) * 7 + sizeof(D3DCOLOR));
}
void APIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "glVertexPointer: 0x%X 0x%X 0x%X 0x%X", size, type, stride, pointer );
#endif
if(size == 3 && type == GL_FLOAT)
g_OpenGLValues->m_vertexary = (GLfloat*)pointer;
#if DODPFS
else
{
char junk[256];
sprintf( junk, "Vertex array not supported (size:0x%X type:0x%X)\n", size, type );
OutputDebugStringA( junk );
}
#endif
if(stride == 0)
{
stride = 12;
}
g_OpenGLValues->m_vertexarystride = stride;
}
int WINAPI wglChoosePixelFormat(HDC hdc, CONST PIXELFORMATDESCRIPTOR *ppfd)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "wglChoosePixelFormat: 0x%X 0x%X", hdc, ppfd );
#endif
return 1;
}
#if HOOK_WINDOW_PROC // Custom message loop to test SetLOD
LRESULT CALLBACK MyMsgHandler(
HWND hwnd, // handle to window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
{
if(uMsg == WM_CHAR)
{
if(wParam == 0x2F)
{
++g_OpenGLValues->m_lod;
if(g_OpenGLValues->m_lod == 8)
g_OpenGLValues->m_lod = 0;
int changedLOD = 0;
static char str[256];
for(int i = 0; i < MAXGLTEXHANDLES; ++i)
{
if(g_OpenGLValues->m_tex[i].m_ddsurf != 0)
{
DWORD mipcount = g_OpenGLValues->m_tex[i].m_ddsurf->GetLevelCount();
if(mipcount > 1)
{
if(g_OpenGLValues->m_lod >= mipcount)
g_OpenGLValues->m_tex[i].m_ddsurf->SetLOD(mipcount - 1);
else
{
g_OpenGLValues->m_tex[i].m_ddsurf->SetLOD(g_OpenGLValues->m_lod);
++changedLOD;
}
}
}
}
_itoa(changedLOD, str, 10);
#if DODPFS
char junk[256];
sprintf( junk, "MyMsgHandler:%s", str );
OutputDebugStringA( junk );
#endif
return 0;
}
}
return CallWindowProc(g_OpenGLValues->m_wndproc, hwnd, uMsg, wParam, lParam);
}
#endif
HGLRC WINAPI wglCreateContext(HDC hdc)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "wglCreateContext: 0x%X", hdc );
#endif
/*
This IF/ELSE block is necessary in order to allow apps to delete a
context and then create a new one (as in changing screen resolution
or changing from a software renderer to using OpenGL32.DLL). We need
to make sure that the pre-existing DirectX8Device is freed and that
the g_OpenGLValues data structure is cleared as it would be when
created. If we do not the results can range from rendering the screen
inaccurately or not at all to crashing the app. (a-brienw 03/07/2001)
*/
if (g_OpenGLValues != NULL)
{
if (g_OpenGLValues->m_d3ddev != NULL)
{
g_OpenGLValues->m_d3ddev->Release();
g_OpenGLValues->m_d3ddev = 0;
}
}
else
{
g_OpenGLValues = new Globals;
}
if (g_OpenGLValues == NULL)
return 0;
memset( g_OpenGLValues, 0, sizeof(Globals) );
g_OpenGLValues->m_hdc = hdc;
g_OpenGLValues->m_hwnd = WindowFromDC(g_OpenGLValues->m_hdc);
RECT rect;
GetClientRect(g_OpenGLValues->m_hwnd, &rect);
g_OpenGLValues->m_winWidth = (USHORT)rect.right;
g_OpenGLValues->m_winHeight = (USHORT)rect.bottom;
g_OpenGLValues->m_vwx = rect.left;
g_OpenGLValues->m_vwy = rect.top;
g_OpenGLValues->m_vww = rect.right - rect.left;
g_OpenGLValues->m_vwh = rect.bottom - rect.top;
g_OpenGLValues->m_vport.X = g_OpenGLValues->m_vwx;
g_OpenGLValues->m_vport.Y = g_OpenGLValues->m_winHeight - (g_OpenGLValues->m_vwy + g_OpenGLValues->m_vwh);
g_OpenGLValues->m_vport.Width = g_OpenGLValues->m_vww;
g_OpenGLValues->m_vport.Height = g_OpenGLValues->m_vwh;
g_OpenGLValues->m_vport.MinZ = 0.f;
g_OpenGLValues->m_vport.MaxZ = 1.f;
D3DDEVTYPE DeviceType = D3DDEVTYPE_HAL;
// Check registry key to see if we need to do software emulation
HKEY hKey;
if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, RESPATH_QUAKE, &hKey)) {
DWORD dwType;
DWORD dwValue;
DWORD dwSize = 4;
if (ERROR_SUCCESS == RegQueryValueEx( hKey, L"Emulation", NULL, &dwType, (LPBYTE) &dwValue, &dwSize) &&
dwType == REG_DWORD &&
dwValue != 0) {
DeviceType = D3DDEVTYPE_REF;
}
RegCloseKey( hKey );
}
//
// get the current display settings so they can be restored
// after the call to Direct3DCreate8.
//
DEVMODEW dm;
dm.dmSize = sizeof(DEVMODEW);
dm.dmDriverExtra = 0;
if (!EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, &dm))
{
return 0;
}
IDirect3D8 *pEnum = Direct3DCreate8(D3D_SDK_VERSION);
if (pEnum == NULL)
{
#if DODPFS
OutputDebugStringA("Wrapper: Direct3DCreate8 failed\n");
#endif
return 0;
}
D3DPRESENT_PARAMETERS d3dpp;
memset(&d3dpp, 0, sizeof(D3DPRESENT_PARAMETERS));
// See if the window is full screen
if( rect.right == GetDeviceCaps(hdc, HORZRES) && rect.bottom == GetDeviceCaps(hdc, VERTRES) )
{
// We are full screen
d3dpp.Windowed = FALSE;
}
else
{
d3dpp.Windowed = TRUE;
}
int bpp = GetDeviceCaps(hdc, BITSPIXEL);
/*
If this device is a 3dfx Voodoo then make sure we don't allow the
display to be set to more than 16bpp because of the bug in the drivers
that the 3dfx team is (hopefully) going to get to at a later date.
*/
if (wcsstr(dm.dmDeviceName,L"3dfx"))
{
if (bpp > 16)
{
bpp = 16;
dm.dmBitsPerPel = 16;
}
}
d3dpp.hDeviceWindow = g_OpenGLValues->m_hwnd;
d3dpp.BackBufferWidth = rect.right;
d3dpp.BackBufferHeight = rect.bottom;
d3dpp.BackBufferFormat = bpp == 16 ? D3DFMT_R5G6B5 : D3DFMT_X8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
// check to see if the current format is supported
// if not and we are in 32 bpp change to 16 bpp
HRESULT hr = pEnum->CheckDeviceType( D3DADAPTER_DEFAULT, DeviceType, d3dpp.BackBufferFormat, d3dpp.BackBufferFormat, d3dpp.Windowed );
if(FAILED(hr))
{
if( bpp == 32 )
{
d3dpp.BackBufferFormat = D3DFMT_R5G6B5;
dm.dmBitsPerPel = 16;
}
}
// restore to the saved display settings.
ChangeDisplaySettingsExW(0, &dm, 0, CDS_FULLSCREEN, 0);
hr = pEnum->GetDeviceCaps( D3DADAPTER_DEFAULT, DeviceType, &g_OpenGLValues->m_dd );
if(FAILED(hr))
{
pEnum->Release();
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: GetDeviceCaps failed (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
return 0;
}
DWORD Behaviour;
#if 1
if(g_OpenGLValues->m_dd.MaxStreams >= 4 &&
(g_OpenGLValues->m_dd.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0 &&
g_OpenGLValues->m_dd.MaxActiveLights >= 8 &&
(g_OpenGLValues->m_dd.TextureCaps & D3DPTEXTURECAPS_PROJECTED) != 0)
{
Behaviour = D3DCREATE_HARDWARE_VERTEXPROCESSING | ((g_OpenGLValues->m_dd.DevCaps & D3DDEVCAPS_PUREDEVICE) != 0 ? D3DCREATE_PUREDEVICE : 0);
#if DODPFS
OutputDebugStringA("Wrapper: Using T&L hardware\n");
#endif
}
else
#endif
{
Behaviour = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
#if DODPFS
OutputDebugStringA("Wrapper: Using software pipeline\n");
#endif
}
hr = pEnum->CreateDevice(D3DADAPTER_DEFAULT, DeviceType, g_OpenGLValues->m_hwnd, Behaviour, &d3dpp, &g_OpenGLValues->m_d3ddev);
if(FAILED(hr))
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: CreateDevice failed (hr:0x%X windowed:%d)\n", hr, d3dpp.Windowed );
OutputDebugStringA( junk );
#endif
pEnum->Release();
return 0;
}
// Check registry key to see if we need to turn off mipmapping
if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, RESPATH_QUAKE, &hKey)) {
DWORD dwType;
DWORD dwValue;
DWORD dwSize = 4;
if (ERROR_SUCCESS == RegQueryValueEx( hKey, L"DisableMipMap", NULL, &dwType, (LPBYTE) &dwValue, &dwSize) &&
dwType == REG_DWORD &&
dwValue != 0) {
g_OpenGLValues->m_usemipmap = FALSE;
#if DODPFS
OutputDebugStringA("Wrapper: Mipmapping disabled\n");
#endif
}
else {
g_OpenGLValues->m_usemipmap = TRUE;
}
RegCloseKey( hKey );
}
else {
g_OpenGLValues->m_usemipmap = TRUE;
}
// Enumerate texture formats and find the right ones to use
// Look for a four bit alpha surface
hr = pEnum->CheckDeviceFormat(D3DADAPTER_DEFAULT, DeviceType, d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_A4R4G4B4);
if ( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: Unable to find 4444 texture (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
g_OpenGLValues->m_d3ddev->Release();
pEnum->Release();
return 0;
}
g_OpenGLValues->m_ddFourBitAlphaSurfFormat = D3DFMT_A4R4G4B4;
// Look for an eight bit alpha surface
hr = pEnum->CheckDeviceFormat(D3DADAPTER_DEFAULT, DeviceType, d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8);
if ( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: Not using 8888 texture (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
g_OpenGLValues->m_ddEightBitAlphaSurfFormat = g_OpenGLValues->m_ddFourBitAlphaSurfFormat;
}
else
{
g_OpenGLValues->m_ddEightBitAlphaSurfFormat = D3DFMT_A8R8G8B8;
}
// Look for a surface
hr = pEnum->CheckDeviceFormat(D3DADAPTER_DEFAULT, DeviceType, d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_R5G6B5);
if ( FAILED(hr) )
{
hr = pEnum->CheckDeviceFormat(D3DADAPTER_DEFAULT, DeviceType, d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_X1R5G5B5);
if ( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: Unable to find 555 or 565 texture (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
g_OpenGLValues->m_d3ddev->Release();
pEnum->Release();
return 0;
}
g_OpenGLValues->m_ddFiveBitSurfFormat = D3DFMT_X1R5G5B5;
}
else
{
g_OpenGLValues->m_ddFiveBitSurfFormat = D3DFMT_R5G6B5;
}
// Look for an 8-bit surface
hr = pEnum->CheckDeviceFormat(D3DADAPTER_DEFAULT, DeviceType, d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8);
if ( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: Not using 888 texture (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
g_OpenGLValues->m_ddEightBitSurfFormat = g_OpenGLValues->m_ddFiveBitSurfFormat;
}
else
{
g_OpenGLValues->m_ddEightBitSurfFormat = D3DFMT_X8R8G8B8;
}
// Look for a luminance surface
hr = pEnum->CheckDeviceFormat(D3DADAPTER_DEFAULT, DeviceType, d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_L8);
if ( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: Not using luminance texture (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
g_OpenGLValues->m_ddLuminanceSurfFormat = g_OpenGLValues->m_ddEightBitSurfFormat;
}
else
{
g_OpenGLValues->m_ddLuminanceSurfFormat = D3DFMT_L8;
}
// Look for a alpha surface
hr = pEnum->CheckDeviceFormat(D3DADAPTER_DEFAULT, DeviceType, d3dpp.BackBufferFormat, 0, D3DRTYPE_TEXTURE, D3DFMT_A8);
if ( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: Not using alpha-only texture (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
g_OpenGLValues->m_ddEightBitAlphaOnlySurfFormat = g_OpenGLValues->m_ddEightBitAlphaSurfFormat;
}
else
{
g_OpenGLValues->m_ddEightBitAlphaOnlySurfFormat = D3DFMT_A8;
}
// Done with enumerator
pEnum->Release();
// Do misc init stuff
if(g_OpenGLValues->m_dd.MaxTextureWidth < 512 || g_OpenGLValues->m_dd.MaxTextureHeight < 512) {
g_OpenGLValues->m_subsample = TRUE;
#if DODPFS
OutputDebugStringA("Wrapper: Subsampling textures to 256 x 256\n");
#endif
}
else
g_OpenGLValues->m_subsample = FALSE;
if(g_OpenGLValues->m_dd.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) {
g_OpenGLValues->m_makeSquare = TRUE;
#if DODPFS
OutputDebugStringA("Wrapper: Forcing all textures to be square\n");
#endif
}
else
g_OpenGLValues->m_makeSquare = FALSE;
if(g_OpenGLValues->m_dd.MaxSimultaneousTextures > 1) {
g_OpenGLValues->m_usemtex = TRUE;
#if DODPFS
OutputDebugStringA("Wrapper: Multitexturing enabled\n");
#endif
}
else {
g_OpenGLValues->m_usemtex = FALSE;
#if DODPFS
OutputDebugStringA("Wrapper: Multitexturing not available with this driver\n");
#endif
}
if(!(g_OpenGLValues->m_dd.TextureFilterCaps & D3DPTFILTERCAPS_MIPFPOINT) &&
!(g_OpenGLValues->m_dd.TextureFilterCaps & D3DPTFILTERCAPS_MIPFLINEAR)) {
g_OpenGLValues->m_usemipmap = FALSE;
#if DODPFS
OutputDebugStringA("Wrapper: Mipmapping disabled\n");
#endif
}
if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, RESPATH_QUAKE, &hKey)) {
DWORD dwType;
DWORD dwValue;
DWORD dwSize = 4;
if (ERROR_SUCCESS == RegQueryValueEx( hKey, L"DoFlip", NULL, &dwType, (LPBYTE) &dwValue, &dwSize) &&
dwType == REG_DWORD &&
dwValue != 0) {
g_OpenGLValues->m_doFlip = TRUE;
}
else {
g_OpenGLValues->m_doFlip = FALSE;
}
RegCloseKey( hKey );
}
else {
g_OpenGLValues->m_doFlip = FALSE;
}
// Create shaders
DWORD decl0[] =
{
D3DVSD_STREAM(0),
D3DVSD_REG( D3DVSDE_POSITION, D3DVSDT_FLOAT3),
D3DVSD_END()
};
hr = g_OpenGLValues->m_d3ddev->CreateVertexShader( decl0, NULL, &g_OpenGLValues->m_vshader[0], 0 );
if( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: CreateVertexShader(1) failed (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
g_OpenGLValues->m_d3ddev->Release();
return 0;
}
DWORD decl1[] =
{
D3DVSD_STREAM(0),
D3DVSD_REG( D3DVSDE_POSITION, D3DVSDT_FLOAT3),
D3DVSD_STREAM(1),
D3DVSD_REG( D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
D3DVSD_END()
};
hr = g_OpenGLValues->m_d3ddev->CreateVertexShader( decl1, NULL, &g_OpenGLValues->m_vshader[1], 0 );
if( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: CreateVertexShader(2) failed (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
g_OpenGLValues->m_d3ddev->Release();
return 0;
}
DWORD decl2[] =
{
D3DVSD_STREAM(0),
D3DVSD_REG( D3DVSDE_POSITION, D3DVSDT_FLOAT3),
D3DVSD_STREAM(1),
D3DVSD_REG( D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
D3DVSD_END()
};
hr = g_OpenGLValues->m_d3ddev->CreateVertexShader( decl2, NULL, &g_OpenGLValues->m_vshader[2], 0 );
if( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: CreateVertexShader(3) failed (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
g_OpenGLValues->m_d3ddev->Release();
return 0;
}
DWORD decl3[] =
{
D3DVSD_STREAM(0),
D3DVSD_REG( D3DVSDE_POSITION, D3DVSDT_FLOAT3),
D3DVSD_STREAM(1),
D3DVSD_REG( D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
D3DVSD_STREAM(2),
D3DVSD_REG( D3DVSDE_TEXCOORD1, D3DVSDT_FLOAT2),
D3DVSD_END()
};
hr = g_OpenGLValues->m_d3ddev->CreateVertexShader( decl3, NULL, &g_OpenGLValues->m_vshader[3], 0 );
if( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: CreateVertexShader(4) failed (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
g_OpenGLValues->m_d3ddev->Release();
return 0;
}
DWORD decl4[] =
{
D3DVSD_STREAM(0),
D3DVSD_REG( D3DVSDE_POSITION, D3DVSDT_FLOAT3),
D3DVSD_STREAM(1),
D3DVSD_REG( D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
D3DVSD_STREAM(2),
D3DVSD_REG( D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
D3DVSD_END()
};
hr = g_OpenGLValues->m_d3ddev->CreateVertexShader( decl4, NULL, &g_OpenGLValues->m_vshader[4], 0 );
if( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: CreateVertexShader(5) failed (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
g_OpenGLValues->m_d3ddev->Release();
return 0;
}
DWORD decl5[] =
{
D3DVSD_STREAM(0),
D3DVSD_REG( D3DVSDE_POSITION, D3DVSDT_FLOAT3),
D3DVSD_STREAM(1),
D3DVSD_REG( D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR),
D3DVSD_STREAM(2),
D3DVSD_REG( D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2),
D3DVSD_STREAM(3),
D3DVSD_REG( D3DVSDE_TEXCOORD1, D3DVSDT_FLOAT2),
D3DVSD_END()
};
hr = g_OpenGLValues->m_d3ddev->CreateVertexShader( decl5, NULL, &g_OpenGLValues->m_vshader[5], 0 );
if( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: CreateVertexShader(6) failed (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
g_OpenGLValues->m_d3ddev->Release();
return 0;
}
// Create vertex buffers
hr = g_OpenGLValues->m_d3ddev->CreateVertexBuffer(sizeof(QuakeVertex) * VBUFSIZE, D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, QUAKEVFMT, D3DPOOL_DEFAULT, &g_OpenGLValues->m_vbuf);
if( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: CreateVertexBuffer failed (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
g_OpenGLValues->m_d3ddev->Release();
return 0;
}
g_OpenGLValues->m_vertexarystride = 12;
g_OpenGLValues->m_colorarystride = 4;
g_OpenGLValues->m_texcoordarystride[0] = 8;
g_OpenGLValues->m_texcoordarystride[1] = 8;
g_OpenGLValues->m_xyzbuf = 0;
g_OpenGLValues->m_colbuf = 0;
g_OpenGLValues->m_texbuf = 0;
g_OpenGLValues->m_tex2buf = 0;
g_OpenGLValues->m_vbufsz = 0;
hr = GrowVB(VBUFSIZE);
if( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: GrowVB failed (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
g_OpenGLValues->m_vbuf->Release();
g_OpenGLValues->m_d3ddev->Release();
return 0;
}
g_OpenGLValues->m_ibuf = 0;
g_OpenGLValues->m_ibufsz = 0;
hr = GrowIB(VBUFSIZE);
if( FAILED(hr) )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: GrowIB failed (0x%X)\n", hr );
OutputDebugStringA( junk );
#endif
g_OpenGLValues->m_vbuf->Release();
g_OpenGLValues->m_d3ddev->Release();
return 0;
}
// Some more init stuff
g_OpenGLValues->m_cullMode = GL_BACK;
g_OpenGLValues->m_FrontFace = GL_CCW;
g_OpenGLValues->m_cullEnabled = FALSE;
g_OpenGLValues->m_texHandleValid = FALSE;
g_OpenGLValues->m_texturing = FALSE;
g_OpenGLValues->m_updvwp = TRUE;
g_OpenGLValues->m_blendmode[0] = GL_MODULATE;
g_OpenGLValues->m_blendmode[1] = GL_MODULATE;
g_OpenGLValues->m_nfv = 0;
g_OpenGLValues->m_curtgt = 0;
g_OpenGLValues->m_client_active_texture_arb = 0;
g_OpenGLValues->m_tu = g_OpenGLValues->m_tv = g_OpenGLValues->m_tu2 = g_OpenGLValues->m_tv2 = 0.f;
g_OpenGLValues->m_color = 0xFFFFFFFF;
g_OpenGLValues->m_material.Ambient.r = 0.2f;
g_OpenGLValues->m_material.Ambient.g = 0.2f;
g_OpenGLValues->m_material.Ambient.b = 0.2f;
g_OpenGLValues->m_material.Ambient.a = 1.0f;
g_OpenGLValues->m_material.Diffuse.r = 0.8f;
g_OpenGLValues->m_material.Diffuse.g = 0.8f;
g_OpenGLValues->m_material.Diffuse.b = 0.8f;
g_OpenGLValues->m_material.Diffuse.a = 1.0f;
g_OpenGLValues->m_material.Specular.r = 0.0f;
g_OpenGLValues->m_material.Specular.g = 0.0f;
g_OpenGLValues->m_material.Specular.b = 0.0f;
g_OpenGLValues->m_material.Specular.a = 1.0f;
g_OpenGLValues->m_material.Emissive.r = 0.0f;
g_OpenGLValues->m_material.Emissive.g = 0.0f;
g_OpenGLValues->m_material.Emissive.b = 0.0f;
g_OpenGLValues->m_material.Emissive.a = 1.0f;
g_OpenGLValues->m_material.Power = 0.f;
g_OpenGLValues->m_clearColor = 0;
g_OpenGLValues->m_clearDepth = 1.f;
g_OpenGLValues->m_usecolorary = FALSE;
g_OpenGLValues->m_usetexcoordary[0] = FALSE;
g_OpenGLValues->m_usetexcoordary[1] = FALSE;
g_OpenGLValues->m_usevertexary = FALSE;
g_OpenGLValues->m_polyoffset = FALSE;
g_OpenGLValues->m_withinprim = FALSE;
g_OpenGLValues->m_scix = 0;
g_OpenGLValues->m_sciy = 0;
g_OpenGLValues->m_sciw = g_OpenGLValues->m_winWidth;
g_OpenGLValues->m_scih = g_OpenGLValues->m_winHeight;
g_OpenGLValues->m_lckfirst = 0;
g_OpenGLValues->m_lckcount = 0;
g_OpenGLValues->m_clippstate = 0;
g_OpenGLValues->m_ibufoff = 0;
g_OpenGLValues->m_vbufoff = 0;
g_OpenGLValues->m_lightdirty = 0;
g_OpenGLValues->m_pStreams[0] = 0;
g_OpenGLValues->m_pStreams[1] = 0;
g_OpenGLValues->m_pStreams[2] = 0;
g_OpenGLValues->m_pStreams[3] = 0;
g_OpenGLValues->m_pStrides[0] = 0;
g_OpenGLValues->m_pStrides[1] = 0;
g_OpenGLValues->m_pStrides[2] = 0;
g_OpenGLValues->m_pStrides[3] = 0;
for(unsigned i = 0; i < MAXGLTEXHANDLES; ++i) {
g_OpenGLValues->m_tex[i].m_ddsurf = 0;
g_OpenGLValues->m_tex[i].m_block = 0;
g_OpenGLValues->m_tex[i].m_capture = FALSE;
g_OpenGLValues->m_tex[i].m_dwStage = 0;
g_OpenGLValues->m_tex[i].m_minmode = D3DTEXF_POINT;
g_OpenGLValues->m_tex[i].m_magmode = D3DTEXF_LINEAR;
g_OpenGLValues->m_tex[i].m_mipmode = D3DTEXF_LINEAR;
g_OpenGLValues->m_tex[i].m_addu = D3DTADDRESS_WRAP;
g_OpenGLValues->m_tex[i].m_addv = D3DTADDRESS_WRAP;
g_OpenGLValues->m_tex[i].m_prev = (int)i - 1;
g_OpenGLValues->m_tex[i].m_next = (int)i + 1;
}
for(i = 0; i < 8; ++i)
{
g_OpenGLValues->m_light[i].Ambient.r = 0.0f;
g_OpenGLValues->m_light[i].Ambient.g = 0.0f;
g_OpenGLValues->m_light[i].Ambient.b = 0.0f;
g_OpenGLValues->m_light[i].Ambient.a = 1.0f;
if(i == 0)
{
g_OpenGLValues->m_light[i].Diffuse.r = 1.0f;
g_OpenGLValues->m_light[i].Diffuse.g = 1.0f;
g_OpenGLValues->m_light[i].Diffuse.b = 1.0f;
g_OpenGLValues->m_light[i].Diffuse.a = 1.0f;
g_OpenGLValues->m_light[i].Specular.r = 1.0f;
g_OpenGLValues->m_light[i].Specular.g = 1.0f;
g_OpenGLValues->m_light[i].Specular.b = 1.0f;
g_OpenGLValues->m_light[i].Specular.a = 1.0f;
}
else
{
g_OpenGLValues->m_light[i].Diffuse.r = 0.0f;
g_OpenGLValues->m_light[i].Diffuse.g = 0.0f;
g_OpenGLValues->m_light[i].Diffuse.b = 0.0f;
g_OpenGLValues->m_light[i].Diffuse.a = 1.0f;
g_OpenGLValues->m_light[i].Specular.r = 0.0f;
g_OpenGLValues->m_light[i].Specular.g = 0.0f;
g_OpenGLValues->m_light[i].Specular.b = 0.0f;
g_OpenGLValues->m_light[i].Specular.a = 1.0f;
}
g_OpenGLValues->m_light[i].Position.x = 0.f;
g_OpenGLValues->m_light[i].Position.y = 0.f;
g_OpenGLValues->m_light[i].Position.z = 1.f;
g_OpenGLValues->m_lightPositionW[i] = 0.f;
g_OpenGLValues->m_light[i].Direction.x = 0.f;
g_OpenGLValues->m_light[i].Direction.y = 0.f;
g_OpenGLValues->m_light[i].Direction.z = -1.f;
g_OpenGLValues->m_light[i].Range = (float)sqrt(FLT_MAX);
g_OpenGLValues->m_light[i].Falloff = 0.f;
g_OpenGLValues->m_light[i].Attenuation0 = 1.f;
g_OpenGLValues->m_light[i].Attenuation1 = 0.f;
g_OpenGLValues->m_light[i].Attenuation2 = 0.f;
g_OpenGLValues->m_light[i].Theta = 0.f;
g_OpenGLValues->m_light[i].Phi = 180.f;
g_OpenGLValues->m_lightdirty |= (1 << i);
}
g_OpenGLValues->m_free = 0;
D3DMATRIX unity;
unity._11 = 1.0f; unity._12 = 0.0f; unity._13 = 0.0f; unity._14 = 0.0f;
unity._21 = 0.0f; unity._22 = 1.0f; unity._23 = 0.0f; unity._24 = 0.0f;
unity._31 = 0.0f; unity._32 = 0.0f; unity._33 = 1.0f; unity._34 = 0.0f;
unity._41 = 0.0f; unity._42 = 0.0f; unity._43 = 0.0f; unity._44 = 1.0f;
g_OpenGLValues->m_xfrm[D3DTS_WORLD] = unity;
QuakeSetTransform(D3DTS_WORLD, &unity);
g_OpenGLValues->m_xfrm[D3DTS_PROJECTION] = unity;
QuakeSetTransform(D3DTS_PROJECTION, &unity);
g_OpenGLValues->m_xfrm[D3DTS_TEXTURE0] = unity;
QuakeSetTransform(D3DTS_TEXTURE0, &unity);
if(g_OpenGLValues->m_usemtex == TRUE)
{
g_OpenGLValues->m_xfrm[D3DTS_TEXTURE1] = unity;
QuakeSetTransform(D3DTS_TEXTURE1, &unity);
}
g_OpenGLValues->m_matrixMode = D3DTS_WORLD;
g_OpenGLValues->m_d3ddev->SetViewport(&g_OpenGLValues->m_vport);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_SPECULARENABLE, TRUE);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_DITHERENABLE, TRUE);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CLIPPING, TRUE);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_TEXCOORDINDEX,0);
if(g_OpenGLValues->m_usemtex == TRUE)
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_TEXCOORDINDEX,1);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_AMBIENT, RGBA_MAKE(51, 51, 51, 255));
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_MATERIAL);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_NORMALIZENORMALS, FALSE);
g_OpenGLValues->m_d3ddev->SetMaterial(&g_OpenGLValues->m_material);
// State block for capturing color buffer bit
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_ALPHAREF, 0);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
g_OpenGLValues->m_d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_cbufbit);
// Create shaders
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[0][0]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[0][1]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[0][2]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[0][3]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[0][4]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[0][5]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE | D3DTA_COMPLEMENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[0][6]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE | D3DTA_COMPLEMENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_MODULATE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[0][7]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[0][8]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[0][9]);
if(g_OpenGLValues->m_usemtex)
{
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[1][0]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[1][1]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLOROP, D3DTOP_MODULATE);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[1][2]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLOROP, D3DTOP_MODULATE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[1][3]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[1][4]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[1][5]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG1, D3DTA_TEXTURE | D3DTA_COMPLEMENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLOROP, D3DTOP_MODULATE);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[1][6]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG1, D3DTA_TEXTURE | D3DTA_COMPLEMENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLOROP, D3DTOP_MODULATE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[1][7]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[1][8]);
g_OpenGLValues->m_d3ddev->BeginStateBlock();
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLORARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_COLOROP, D3DTOP_SELECTARG2);
// following stage state to speedup software rasterizer
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAARG2, D3DTA_CURRENT);
g_OpenGLValues->m_d3ddev->SetTextureStageState (1, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
g_OpenGLValues->m_d3ddev->EndStateBlock(&g_OpenGLValues->m_shaders[1][9]);
}
#if HOOK_WINDOW_PROC
// Hook into message loop
g_OpenGLValues->m_wndproc = (WNDPROC)SetWindowLong(g_OpenGLValues->m_hwnd, GWL_WNDPROC, (LONG)MyMsgHandler);
g_OpenGLValues->m_lod = 0;
#endif
// Start a scene
g_OpenGLValues->m_d3ddev->BeginScene();
return (HGLRC)1;
}
BOOL WINAPI wglDeleteContext(HGLRC hglrc)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "wglDeleteContext: 0x%X", hglrc );
#endif
if (g_OpenGLValues != NULL)
{
g_OpenGLValues->m_d3ddev->EndScene();
#if HOOK_WINDOW_PROC
SetWindowLong(g_OpenGLValues->m_hwnd, GWL_WNDPROC, (LONG)g_OpenGLValues->m_wndproc);
#endif
for(int i = 0; i < MAXGLTEXHANDLES; ++i){
if(g_OpenGLValues->m_tex[i].m_ddsurf != 0) {
g_OpenGLValues->m_tex[i].m_ddsurf->Release();
g_OpenGLValues->m_tex[i].m_ddsurf = 0;
if(g_OpenGLValues->m_tex[i].m_block != 0)
{
g_OpenGLValues->m_d3ddev->DeleteStateBlock(g_OpenGLValues->m_tex[i].m_block);
g_OpenGLValues->m_tex[i].m_block = 0;
}
g_OpenGLValues->m_tex[i].m_capture = FALSE;
}
}
for(i = 0; i < 8; ++i)
g_OpenGLValues->m_d3ddev->DeleteStateBlock(g_OpenGLValues->m_shaders[0][i]);
if(g_OpenGLValues->m_usemtex)
{
for(i = 0; i < 8; ++i)
g_OpenGLValues->m_d3ddev->DeleteStateBlock(g_OpenGLValues->m_shaders[1][i]);
}
g_OpenGLValues->m_ibuf->Release();
g_OpenGLValues->m_ibuf = 0;
g_OpenGLValues->m_tex2buf->Release();
g_OpenGLValues->m_tex2buf = 0;
g_OpenGLValues->m_texbuf->Release();
g_OpenGLValues->m_texbuf = 0;
g_OpenGLValues->m_colbuf->Release();
g_OpenGLValues->m_colbuf = 0;
g_OpenGLValues->m_xyzbuf->Release();
g_OpenGLValues->m_xyzbuf = 0;
g_OpenGLValues->m_vbuf->Release();
g_OpenGLValues->m_vbuf = 0;
/*
Although this is the correct location to release the m_d3ddev object
we aren't going to do it here and instead we will do it in the
NOTIFY_FUNCTION when the DLL is detached from the process. I am
doing this to prevent apps (such as MDK2) from crashing on exit due
to the fact that they continue to call GL functions after deleting
the context which causes an access violation. (a-brienw 03/02/2001)
g_OpenGLValues->m_d3ddev->Release();
g_OpenGLValues->m_d3ddev = 0;
*/
}
return TRUE;
}
int WINAPI wglDescribePixelFormat(HDC hdc, INT iPixelFormat, UINT nBytes, PIXELFORMATDESCRIPTOR *ppfd)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "wglDescribePixelFormat: 0x%X 0x%X 0x%X 0x%X", hdc, iPixelFormat, nBytes, ppfd );
#endif
if (ppfd != NULL)
{
ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
ppfd->nVersion = 1;
ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_GENERIC_ACCELERATED | PFD_DOUBLEBUFFER;
ppfd->iPixelType = PFD_TYPE_RGBA;
ppfd->cColorBits = (unsigned char)GetDeviceCaps(hdc, BITSPIXEL);
ppfd->cAccumBits = 0;
ppfd->cAccumRedBits = 0;
ppfd->cAccumGreenBits = 0;
ppfd->cAccumBlueBits = 0;
ppfd->cAccumAlphaBits = 0;
ppfd->cStencilBits = 0;
ppfd->cAuxBuffers = 0;
ppfd->iLayerType = 0;
ppfd->bReserved = 0;
ppfd->dwLayerMask = 0;
ppfd->dwVisibleMask = 0;
ppfd->dwDamageMask = 0;
if(GetDeviceCaps(hdc, BITSPIXEL) == 16)
{
ppfd->cRedBits = 5;
ppfd->cRedShift = 11;
ppfd->cGreenBits = 6;
ppfd->cGreenShift = 5;
ppfd->cBlueBits = 5;
ppfd->cBlueShift = 0;
ppfd->cAlphaBits = 0;
ppfd->cAlphaShift = 0;
ppfd->cDepthBits = 16;
}
else if(GetDeviceCaps(hdc, BITSPIXEL) == 24 || GetDeviceCaps(hdc, BITSPIXEL) == 32)
{
ppfd->cRedBits = 8;
ppfd->cRedShift = 16;
ppfd->cGreenBits = 8;
ppfd->cGreenShift = 8;
ppfd->cBlueBits = 8;
ppfd->cBlueShift = 0;
ppfd->cAlphaBits = 0;
ppfd->cAlphaShift = 0;
ppfd->cDepthBits = 16;
}
else
{
return 0;
}
}
return 1;
}
HGLRC WINAPI wglGetCurrentContext(VOID)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "wglGetCurrentContext" );
#endif
return (HGLRC)1;
}
HDC WINAPI wglGetCurrentDC(VOID)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "wglGetCurrentDC" );
#endif
return g_OpenGLValues->m_hdc;
}
int WINAPI wglGetPixelFormat(HDC hdc)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "wglGetPixelFormat: 0x%X", hdc );
#endif
return 1;
}
PROC WINAPI wglGetProcAddress(LPCSTR str)
{
if(strcmp(str, "glMTexCoord2fSGIS") == 0)
return (PROC)glMTexCoord2fSGIS;
else if(strcmp(str, "glSelectTextureSGIS") == 0)
return (PROC)glSelectTextureSGIS;
else if(strcmp(str, "glActiveTextureARB") == 0)
return (PROC)glActiveTextureARB;
else if(strcmp(str, "glClientActiveTextureARB") == 0)
return (PROC)glClientActiveTextureARB;
else if(strcmp(str, "glMultiTexCoord2fARB") == 0)
return (PROC)glMultiTexCoord2fARB;
else if(strcmp(str, "glMultiTexCoord2fvARB") == 0)
return (PROC)glMultiTexCoord2fvARB;
else if(strcmp(str, "glLockArraysEXT") == 0)
return (PROC)glLockArraysEXT;
else if(strcmp(str, "glUnlockArraysEXT") == 0)
return (PROC)glUnlockArraysEXT;
else if(strcmp(str, "wglSwapIntervalEXT") == 0)
return (PROC)wglSwapIntervalEXT;
#if DODPFS
else
{
char junk[256];
sprintf( junk, "Wrapper: Unimplemented function (%s)\n", str );
OutputDebugStringA( junk );
}
#endif
return NULL;
}
BOOL wglMakeCurrent(HDC hdc, HGLRC hglrc)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "wglMakeCurrent: 0x%X 0x%X", hdc, hglrc );
#endif
return g_OpenGLValues->m_d3ddev != NULL; // Fail if no device
}
BOOL WINAPI wglSetPixelFormat(HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "wglSetPixelFormat: 0x%X 0x%X 0x%X", hdc, iPixelFormat, ppfd );
#endif
return TRUE;
}
BOOL WINAPI wglSwapBuffers(HDC hdc)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "wglSwapBuffers: 0x%X", hdc );
#endif
if( g_OpenGLValues->m_withinprim == TRUE )
{
#if DODPFS
char junk[256];
sprintf( junk, "Wrapper: wglSwapBuffers primitive=%d cnt=%d\n", g_OpenGLValues->m_prim, g_OpenGLValues->m_vcnt );
OutputDebugStringA( junk );
#endif
glEnd();
}
g_OpenGLValues->m_d3ddev->EndScene();
g_OpenGLValues->m_d3ddev->Present(NULL, NULL, NULL, NULL);
g_OpenGLValues->m_d3ddev->BeginScene();
return TRUE;
}
BOOL WINAPI wglSwapIntervalEXT(GLint interval)
{
#if GETPARMSFORDEBUG
LOG("EmulateOpenGL - PARMS", eDbgLevelInfo, "wglSwapIntervalEXT: 0x%X", interval );
#endif
return TRUE;
}