mirror of
https://github.com/ioquake/jedi-academy.git
synced 2024-11-22 12:22:23 +00:00
6680 lines
184 KiB
C++
6680 lines
184 KiB
C++
|
|
/*
|
|
* UNPUBLISHED -- Rights reserved under the copyright laws of the
|
|
* United States. Use of a copyright notice is precautionary only and
|
|
* does not imply publication or disclosure.
|
|
*
|
|
* THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION
|
|
* OF VICARIOUS VISIONS, INC. ANY DUPLICATION, MODIFICATION,
|
|
* DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR
|
|
* EXPRESS WRITTEN PERMISSION OF VICARIOUS VISIONS, INC.
|
|
*/
|
|
|
|
// leave this as first line for PCH reasons...
|
|
//
|
|
#include "../server/exe_headers.h"
|
|
|
|
|
|
/*
|
|
** QGL_WIN.C
|
|
**
|
|
** This file implements the operating system binding of GL to QGL function
|
|
** pointers. When doing a port of Quake3 you must implement the following
|
|
** two functions:
|
|
**
|
|
** QGL_Init() - loads libraries, assigns function pointers, etc.
|
|
** QGL_Shutdown() - unloads libraries, NULLs function pointers
|
|
*/
|
|
#include <float.h>
|
|
#include "../renderer/tr_local.h"
|
|
#include "glw_win_dx8.h"
|
|
#include "win_local.h"
|
|
|
|
#ifdef _XBOX
|
|
#include <xgraphics.h>
|
|
//#include "win_flareeffect.h"
|
|
#include "win_lighteffects.h"
|
|
#include "win_highdynamicrange.h"
|
|
|
|
#ifndef FINAL_BUILD
|
|
#include <d3d8perf.h>
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#include <vector>
|
|
|
|
extern void Z_SetNewDeleteTemporary(bool);
|
|
|
|
#define GLW_USE_TRI_STRIPS 1
|
|
|
|
#ifdef _XBOX
|
|
#define GLW_MAX_DRAW_PACKET_SIZE 2040
|
|
#else
|
|
#define GLW_MAX_DRAW_PACKET_SIZE (SHADER_MAX_VERTEXES*12)
|
|
#endif
|
|
|
|
#define MEMORY_PROFILE 1
|
|
|
|
int texMemSize = 0;
|
|
|
|
#if MEMORY_PROFILE
|
|
|
|
static int getTexMemSize(IDirect3DTexture8* mipmap)
|
|
{
|
|
int levels = mipmap->GetLevelCount();
|
|
int size = 0;
|
|
while (levels--)
|
|
{
|
|
D3DSURFACE_DESC desc;
|
|
mipmap->GetLevelDesc(levels, &desc);
|
|
size += desc.Size;
|
|
}
|
|
return size;
|
|
}
|
|
#endif
|
|
|
|
void QGL_EnableLogging( qboolean enable );
|
|
|
|
void ( * qglAccum )(GLenum op, GLfloat value);
|
|
void ( * qglAlphaFunc )(GLenum func, GLclampf ref);
|
|
GLboolean ( * qglAreTexturesResident )(GLsizei n, const GLuint *textures, GLboolean *residences);
|
|
void ( * qglArrayElement )(GLint i);
|
|
void ( * qglBegin )(GLenum mode);
|
|
void ( * qglBeginEXT )(GLenum mode, GLint verts, GLint colors, GLint normals, GLint tex0, GLint tex1);//, GLint tex2, GLint tex3);
|
|
GLboolean ( * qglBeginFrame )(void);
|
|
void ( * qglBeginShadow )(void);
|
|
void ( * qglBindTexture )(GLenum target, GLuint texture);
|
|
void ( * qglBitmap )(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap);
|
|
void ( * qglBlendFunc )(GLenum sfactor, GLenum dfactor);
|
|
void ( * qglCallList )(GLuint lnum);
|
|
void ( * qglCallLists )(GLsizei n, GLenum type, const GLvoid *lists);
|
|
void ( * qglClear )(GLbitfield mask);
|
|
void ( * qglClearAccum )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
|
void ( * qglClearColor )(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
|
|
void ( * qglClearDepth )(GLclampd depth);
|
|
void ( * qglClearIndex )(GLfloat c);
|
|
void ( * qglClearStencil )(GLint s);
|
|
void ( * qglClipPlane )(GLenum plane, const GLdouble *equation);
|
|
void ( * qglColor3b )(GLbyte red, GLbyte green, GLbyte blue);
|
|
void ( * qglColor3bv )(const GLbyte *v);
|
|
void ( * qglColor3d )(GLdouble red, GLdouble green, GLdouble blue);
|
|
void ( * qglColor3dv )(const GLdouble *v);
|
|
void ( * qglColor3f )(GLfloat red, GLfloat green, GLfloat blue);
|
|
void ( * qglColor3fv )(const GLfloat *v);
|
|
void ( * qglColor3i )(GLint red, GLint green, GLint blue);
|
|
void ( * qglColor3iv )(const GLint *v);
|
|
void ( * qglColor3s )(GLshort red, GLshort green, GLshort blue);
|
|
void ( * qglColor3sv )(const GLshort *v);
|
|
void ( * qglColor3ub )(GLubyte red, GLubyte green, GLubyte blue);
|
|
void ( * qglColor3ubv )(const GLubyte *v);
|
|
void ( * qglColor3ui )(GLuint red, GLuint green, GLuint blue);
|
|
void ( * qglColor3uiv )(const GLuint *v);
|
|
void ( * qglColor3us )(GLushort red, GLushort green, GLushort blue);
|
|
void ( * qglColor3usv )(const GLushort *v);
|
|
void ( * qglColor4b )(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha);
|
|
void ( * qglColor4bv )(const GLbyte *v);
|
|
void ( * qglColor4d )(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha);
|
|
void ( * qglColor4dv )(const GLdouble *v);
|
|
void ( * qglColor4f )(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
|
void ( * qglColor4fv )(const GLfloat *v);
|
|
void ( * qglColor4i )(GLint red, GLint green, GLint blue, GLint alpha);
|
|
void ( * qglColor4iv )(const GLint *v);
|
|
void ( * qglColor4s )(GLshort red, GLshort green, GLshort blue, GLshort alpha);
|
|
void ( * qglColor4sv )(const GLshort *v);
|
|
void ( * qglColor4ub )(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha);
|
|
void ( * qglColor4ubv )(const GLubyte *v);
|
|
void ( * qglColor4ui )(GLuint red, GLuint green, GLuint blue, GLuint alpha);
|
|
void ( * qglColor4uiv )(const GLuint *v);
|
|
void ( * qglColor4us )(GLushort red, GLushort green, GLushort blue, GLushort alpha);
|
|
void ( * qglColor4usv )(const GLushort *v);
|
|
void ( * qglColorMask )(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
|
|
void ( * qglColorMaterial )(GLenum face, GLenum mode);
|
|
void ( * qglColorPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
|
void ( * qglCopyPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);
|
|
void ( * qglCopyTexImage1D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border);
|
|
void ( * qglCopyTexImage2D )(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
|
void ( * qglCopyTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
|
|
void ( * qglCopyTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
|
|
void ( * qglCullFace )(GLenum mode);
|
|
void ( * qglDeleteLists )(GLuint lnum, GLsizei range);
|
|
void ( * qglDeleteTextures )(GLsizei n, const GLuint *textures);
|
|
void ( * qglDepthFunc )(GLenum func);
|
|
void ( * qglDepthMask )(GLboolean flag);
|
|
void ( * qglDepthRange )(GLclampd zNear, GLclampd zFar);
|
|
void ( * qglDisable )(GLenum cap);
|
|
void ( * qglDisableClientState )(GLenum array);
|
|
void ( * qglDrawArrays )(GLenum mode, GLint first, GLsizei count);
|
|
void ( * qglDrawBuffer )(GLenum mode);
|
|
void ( * qglDrawElements )(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
|
|
void ( * qglDrawPixels )(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
|
|
void ( * qglEdgeFlag )(GLboolean flag);
|
|
void ( * qglEdgeFlagPointer )(GLsizei stride, const GLvoid *pointer);
|
|
void ( * qglEdgeFlagv )(const GLboolean *flag);
|
|
void ( * qglEnable )(GLenum cap);
|
|
void ( * qglEnableClientState )(GLenum array);
|
|
void ( * qglEnd )(void);
|
|
void ( * qglEndFrame )(void);
|
|
void ( * qglEndShadow )(void);
|
|
void ( * qglEndList )(void);
|
|
void ( * qglEvalCoord1d )(GLdouble u);
|
|
void ( * qglEvalCoord1dv )(const GLdouble *u);
|
|
void ( * qglEvalCoord1f )(GLfloat u);
|
|
void ( * qglEvalCoord1fv )(const GLfloat *u);
|
|
void ( * qglEvalCoord2d )(GLdouble u, GLdouble v);
|
|
void ( * qglEvalCoord2dv )(const GLdouble *u);
|
|
void ( * qglEvalCoord2f )(GLfloat u, GLfloat v);
|
|
void ( * qglEvalCoord2fv )(const GLfloat *u);
|
|
void ( * qglEvalMesh1 )(GLenum mode, GLint i1, GLint i2);
|
|
void ( * qglEvalMesh2 )(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2);
|
|
void ( * qglEvalPoint1 )(GLint i);
|
|
void ( * qglEvalPoint2 )(GLint i, GLint j);
|
|
void ( * qglFeedbackBuffer )(GLsizei size, GLenum type, GLfloat *buffer);
|
|
void ( * qglFinish )(void);
|
|
void ( * qglFlush )(void);
|
|
void ( * qglFlushShadow )(void);
|
|
void ( * qglFogf )(GLenum pname, GLfloat param);
|
|
void ( * qglFogfv )(GLenum pname, const GLfloat *params);
|
|
void ( * qglFogi )(GLenum pname, GLint param);
|
|
void ( * qglFogiv )(GLenum pname, const GLint *params);
|
|
void ( * qglFrontFace )(GLenum mode);
|
|
void ( * qglFrustum )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
|
GLuint ( * qglGenLists )(GLsizei range);
|
|
void ( * qglGenTextures )(GLsizei n, GLuint *textures);
|
|
void ( * qglGetBooleanv )(GLenum pname, GLboolean *params);
|
|
void ( * qglGetClipPlane )(GLenum plane, GLdouble *equation);
|
|
void ( * qglGetDoublev )(GLenum pname, GLdouble *params);
|
|
GLenum ( * qglGetError )(void);
|
|
void ( * qglGetFloatv )(GLenum pname, GLfloat *params);
|
|
void ( * qglGetIntegerv )(GLenum pname, GLint *params);
|
|
void ( * qglGetLightfv )(GLenum light, GLenum pname, GLfloat *params);
|
|
void ( * qglGetLightiv )(GLenum light, GLenum pname, GLint *params);
|
|
void ( * qglGetMapdv )(GLenum target, GLenum query, GLdouble *v);
|
|
void ( * qglGetMapfv )(GLenum target, GLenum query, GLfloat *v);
|
|
void ( * qglGetMapiv )(GLenum target, GLenum query, GLint *v);
|
|
void ( * qglGetMaterialfv )(GLenum face, GLenum pname, GLfloat *params);
|
|
void ( * qglGetMaterialiv )(GLenum face, GLenum pname, GLint *params);
|
|
void ( * qglGetPixelMapfv )(GLenum gmap, GLfloat *values);
|
|
void ( * qglGetPixelMapuiv )(GLenum gmap, GLuint *values);
|
|
void ( * qglGetPixelMapusv )(GLenum gmap, GLushort *values);
|
|
void ( * qglGetPointerv )(GLenum pname, GLvoid* *params);
|
|
void ( * qglGetPolygonStipple )(GLubyte *mask);
|
|
const GLubyte * ( * qglGetString )(GLenum name);
|
|
void ( * qglGetTexEnvfv )(GLenum target, GLenum pname, GLfloat *params);
|
|
void ( * qglGetTexEnviv )(GLenum target, GLenum pname, GLint *params);
|
|
void ( * qglGetTexGendv )(GLenum coord, GLenum pname, GLdouble *params);
|
|
void ( * qglGetTexGenfv )(GLenum coord, GLenum pname, GLfloat *params);
|
|
void ( * qglGetTexGeniv )(GLenum coord, GLenum pname, GLint *params);
|
|
void ( * qglGetTexImage )(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels);
|
|
void ( * qglGetTexLevelParameterfv )(GLenum target, GLint level, GLenum pname, GLfloat *params);
|
|
void ( * qglGetTexLevelParameteriv )(GLenum target, GLint level, GLenum pname, GLint *params);
|
|
void ( * qglGetTexParameterfv )(GLenum target, GLenum pname, GLfloat *params);
|
|
void ( * qglGetTexParameteriv )(GLenum target, GLenum pname, GLint *params);
|
|
void ( * qglHint )(GLenum target, GLenum mode);
|
|
void ( * qglIndexedTriToStrip )(GLsizei count, const GLushort *indices);
|
|
void ( * qglIndexMask )(GLuint mask);
|
|
void ( * qglIndexPointer )(GLenum type, GLsizei stride, const GLvoid *pointer);
|
|
void ( * qglIndexd )(GLdouble c);
|
|
void ( * qglIndexdv )(const GLdouble *c);
|
|
void ( * qglIndexf )(GLfloat c);
|
|
void ( * qglIndexfv )(const GLfloat *c);
|
|
void ( * qglIndexi )(GLint c);
|
|
void ( * qglIndexiv )(const GLint *c);
|
|
void ( * qglIndexs )(GLshort c);
|
|
void ( * qglIndexsv )(const GLshort *c);
|
|
void ( * qglIndexub )(GLubyte c);
|
|
void ( * qglIndexubv )(const GLubyte *c);
|
|
void ( * qglInitNames )(void);
|
|
void ( * qglInterleavedArrays )(GLenum format, GLsizei stride, const GLvoid *pointer);
|
|
GLboolean ( * qglIsEnabled )(GLenum cap);
|
|
GLboolean ( * qglIsList )(GLuint lnum);
|
|
GLboolean ( * qglIsTexture )(GLuint texture);
|
|
void ( * qglLightModelf )(GLenum pname, GLfloat param);
|
|
void ( * qglLightModelfv )(GLenum pname, const GLfloat *params);
|
|
void ( * qglLightModeli )(GLenum pname, GLint param);
|
|
void ( * qglLightModeliv )(GLenum pname, const GLint *params);
|
|
void ( * qglLightf )(GLenum light, GLenum pname, GLfloat param);
|
|
void ( * qglLightfv )(GLenum light, GLenum pname, const GLfloat *params);
|
|
void ( * qglLighti )(GLenum light, GLenum pname, GLint param);
|
|
void ( * qglLightiv )(GLenum light, GLenum pname, const GLint *params);
|
|
void ( * qglLineStipple )(GLint factor, GLushort pattern);
|
|
void ( * qglLineWidth )(GLfloat width);
|
|
void ( * qglListBase )(GLuint base);
|
|
void ( * qglLoadIdentity )(void);
|
|
void ( * qglLoadMatrixd )(const GLdouble *m);
|
|
void ( * qglLoadMatrixf )(const GLfloat *m);
|
|
void ( * qglLoadName )(GLuint name);
|
|
void ( * qglLogicOp )(GLenum opcode);
|
|
void ( * qglMap1d )(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
|
|
void ( * qglMap1f )(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
|
|
void ( * qglMap2d )(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
|
|
void ( * qglMap2f )(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
|
|
void ( * qglMapGrid1d )(GLint un, GLdouble u1, GLdouble u2);
|
|
void ( * qglMapGrid1f )(GLint un, GLfloat u1, GLfloat u2);
|
|
void ( * qglMapGrid2d )(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2);
|
|
void ( * qglMapGrid2f )(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2);
|
|
void ( * qglMaterialf )(GLenum face, GLenum pname, GLfloat param);
|
|
void ( * qglMaterialfv )(GLenum face, GLenum pname, const GLfloat *params);
|
|
void ( * qglMateriali )(GLenum face, GLenum pname, GLint param);
|
|
void ( * qglMaterialiv )(GLenum face, GLenum pname, const GLint *params);
|
|
void ( * qglMatrixMode )(GLenum mode);
|
|
void ( * qglMultMatrixd )(const GLdouble *m);
|
|
void ( * qglMultMatrixf )(const GLfloat *m);
|
|
void ( * qglNewList )(GLuint lnum, GLenum mode);
|
|
void ( * qglNormal3b )(GLbyte nx, GLbyte ny, GLbyte nz);
|
|
void ( * qglNormal3bv )(const GLbyte *v);
|
|
void ( * qglNormal3d )(GLdouble nx, GLdouble ny, GLdouble nz);
|
|
void ( * qglNormal3dv )(const GLdouble *v);
|
|
void ( * qglNormal3f )(GLfloat nx, GLfloat ny, GLfloat nz);
|
|
void ( * qglNormal3fv )(const GLfloat *v);
|
|
void ( * qglNormal3i )(GLint nx, GLint ny, GLint nz);
|
|
void ( * qglNormal3iv )(const GLint *v);
|
|
void ( * qglNormal3s )(GLshort nx, GLshort ny, GLshort nz);
|
|
void ( * qglNormal3sv )(const GLshort *v);
|
|
void ( * qglNormalPointer )(GLenum type, GLsizei stride, const GLvoid *pointer);
|
|
void ( * qglOrtho )(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
|
void ( * qglPassThrough )(GLfloat token);
|
|
void ( * qglPixelMapfv )(GLenum gmap, GLsizei mapsize, const GLfloat *values);
|
|
void ( * qglPixelMapuiv )(GLenum gmap, GLsizei mapsize, const GLuint *values);
|
|
void ( * qglPixelMapusv )(GLenum gmap, GLsizei mapsize, const GLushort *values);
|
|
void ( * qglPixelStoref )(GLenum pname, GLfloat param);
|
|
void ( * qglPixelStorei )(GLenum pname, GLint param);
|
|
void ( * qglPixelTransferf )(GLenum pname, GLfloat param);
|
|
void ( * qglPixelTransferi )(GLenum pname, GLint param);
|
|
void ( * qglPixelZoom )(GLfloat xfactor, GLfloat yfactor);
|
|
void ( * qglPointSize )(GLfloat size);
|
|
void ( * qglPolygonMode )(GLenum face, GLenum mode);
|
|
void ( * qglPolygonOffset )(GLfloat factor, GLfloat units);
|
|
void ( * qglPolygonStipple )(const GLubyte *mask);
|
|
void ( * qglPopAttrib )(void);
|
|
void ( * qglPopClientAttrib )(void);
|
|
void ( * qglPopMatrix )(void);
|
|
void ( * qglPopName )(void);
|
|
void ( * qglPrioritizeTextures )(GLsizei n, const GLuint *textures, const GLclampf *priorities);
|
|
void ( * qglPushAttrib )(GLbitfield mask);
|
|
void ( * qglPushClientAttrib )(GLbitfield mask);
|
|
void ( * qglPushMatrix )(void);
|
|
void ( * qglPushName )(GLuint name);
|
|
void ( * qglRasterPos2d )(GLdouble x, GLdouble y);
|
|
void ( * qglRasterPos2dv )(const GLdouble *v);
|
|
void ( * qglRasterPos2f )(GLfloat x, GLfloat y);
|
|
void ( * qglRasterPos2fv )(const GLfloat *v);
|
|
void ( * qglRasterPos2i )(GLint x, GLint y);
|
|
void ( * qglRasterPos2iv )(const GLint *v);
|
|
void ( * qglRasterPos2s )(GLshort x, GLshort y);
|
|
void ( * qglRasterPos2sv )(const GLshort *v);
|
|
void ( * qglRasterPos3d )(GLdouble x, GLdouble y, GLdouble z);
|
|
void ( * qglRasterPos3dv )(const GLdouble *v);
|
|
void ( * qglRasterPos3f )(GLfloat x, GLfloat y, GLfloat z);
|
|
void ( * qglRasterPos3fv )(const GLfloat *v);
|
|
void ( * qglRasterPos3i )(GLint x, GLint y, GLint z);
|
|
void ( * qglRasterPos3iv )(const GLint *v);
|
|
void ( * qglRasterPos3s )(GLshort x, GLshort y, GLshort z);
|
|
void ( * qglRasterPos3sv )(const GLshort *v);
|
|
void ( * qglRasterPos4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
|
|
void ( * qglRasterPos4dv )(const GLdouble *v);
|
|
void ( * qglRasterPos4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
|
void ( * qglRasterPos4fv )(const GLfloat *v);
|
|
void ( * qglRasterPos4i )(GLint x, GLint y, GLint z, GLint w);
|
|
void ( * qglRasterPos4iv )(const GLint *v);
|
|
void ( * qglRasterPos4s )(GLshort x, GLshort y, GLshort z, GLshort w);
|
|
void ( * qglRasterPos4sv )(const GLshort *v);
|
|
void ( * qglReadBuffer )(GLenum mode);
|
|
//void ( * qglReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei twidth, GLsizei theight, GLvoid *pixels);
|
|
void ( * qglReadPixels )(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
|
|
void ( * qglCopyBackBufferToTexEXT ) (float width, float height, float u1, float v1, float u2, float v2);
|
|
void ( * qglCopyBackBufferToTex ) (void);
|
|
void ( * qglRectd )(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
|
|
void ( * qglRectdv )(const GLdouble *v1, const GLdouble *v2);
|
|
void ( * qglRectf )(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2);
|
|
void ( * qglRectfv )(const GLfloat *v1, const GLfloat *v2);
|
|
void ( * qglRecti )(GLint x1, GLint y1, GLint x2, GLint y2);
|
|
void ( * qglRectiv )(const GLint *v1, const GLint *v2);
|
|
void ( * qglRects )(GLshort x1, GLshort y1, GLshort x2, GLshort y2);
|
|
void ( * qglRectsv )(const GLshort *v1, const GLshort *v2);
|
|
GLint ( * qglRenderMode )(GLenum mode);
|
|
void ( * qglRotated )(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
|
|
void ( * qglRotatef )(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
|
|
void ( * qglScaled )(GLdouble x, GLdouble y, GLdouble z);
|
|
void ( * qglScalef )(GLfloat x, GLfloat y, GLfloat z);
|
|
void ( * qglScissor )(GLint x, GLint y, GLsizei width, GLsizei height);
|
|
void ( * qglSelectBuffer )(GLsizei size, GLuint *buffer);
|
|
void ( * qglShadeModel )(GLenum mode);
|
|
void ( * qglStencilFunc )(GLenum func, GLint ref, GLuint mask);
|
|
void ( * qglStencilMask )(GLuint mask);
|
|
void ( * qglStencilOp )(GLenum fail, GLenum zfail, GLenum zpass);
|
|
void ( * qglTexCoord1d )(GLdouble s);
|
|
void ( * qglTexCoord1dv )(const GLdouble *v);
|
|
void ( * qglTexCoord1f )(GLfloat s);
|
|
void ( * qglTexCoord1fv )(const GLfloat *v);
|
|
void ( * qglTexCoord1i )(GLint s);
|
|
void ( * qglTexCoord1iv )(const GLint *v);
|
|
void ( * qglTexCoord1s )(GLshort s);
|
|
void ( * qglTexCoord1sv )(const GLshort *v);
|
|
void ( * qglTexCoord2d )(GLdouble s, GLdouble t);
|
|
void ( * qglTexCoord2dv )(const GLdouble *v);
|
|
void ( * qglTexCoord2f )(GLfloat s, GLfloat t);
|
|
void ( * qglTexCoord2fv )(const GLfloat *v);
|
|
void ( * qglTexCoord2i )(GLint s, GLint t);
|
|
void ( * qglTexCoord2iv )(const GLint *v);
|
|
void ( * qglTexCoord2s )(GLshort s, GLshort t);
|
|
void ( * qglTexCoord2sv )(const GLshort *v);
|
|
void ( * qglTexCoord3d )(GLdouble s, GLdouble t, GLdouble r);
|
|
void ( * qglTexCoord3dv )(const GLdouble *v);
|
|
void ( * qglTexCoord3f )(GLfloat s, GLfloat t, GLfloat r);
|
|
void ( * qglTexCoord3fv )(const GLfloat *v);
|
|
void ( * qglTexCoord3i )(GLint s, GLint t, GLint r);
|
|
void ( * qglTexCoord3iv )(const GLint *v);
|
|
void ( * qglTexCoord3s )(GLshort s, GLshort t, GLshort r);
|
|
void ( * qglTexCoord3sv )(const GLshort *v);
|
|
void ( * qglTexCoord4d )(GLdouble s, GLdouble t, GLdouble r, GLdouble q);
|
|
void ( * qglTexCoord4dv )(const GLdouble *v);
|
|
void ( * qglTexCoord4f )(GLfloat s, GLfloat t, GLfloat r, GLfloat q);
|
|
void ( * qglTexCoord4fv )(const GLfloat *v);
|
|
void ( * qglTexCoord4i )(GLint s, GLint t, GLint r, GLint q);
|
|
void ( * qglTexCoord4iv )(const GLint *v);
|
|
void ( * qglTexCoord4s )(GLshort s, GLshort t, GLshort r, GLshort q);
|
|
void ( * qglTexCoord4sv )(const GLshort *v);
|
|
void ( * qglTexCoordPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
|
void ( * qglTexEnvf )(GLenum target, GLenum pname, GLfloat param);
|
|
void ( * qglTexEnvfv )(GLenum target, GLenum pname, const GLfloat *params);
|
|
void ( * qglTexEnvi )(GLenum target, GLenum pname, GLint param);
|
|
void ( * qglTexEnviv )(GLenum target, GLenum pname, const GLint *params);
|
|
void ( * qglTexGend )(GLenum coord, GLenum pname, GLdouble param);
|
|
void ( * qglTexGendv )(GLenum coord, GLenum pname, const GLdouble *params);
|
|
void ( * qglTexGenf )(GLenum coord, GLenum pname, GLfloat param);
|
|
void ( * qglTexGenfv )(GLenum coord, GLenum pname, const GLfloat *params);
|
|
void ( * qglTexGeni )(GLenum coord, GLenum pname, GLint param);
|
|
void ( * qglTexGeniv )(GLenum coord, GLenum pname, const GLint *params);
|
|
void ( * qglTexImage1D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
|
void ( * qglTexImage2D )(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
|
void ( * qglTexImage2DEXT )(GLenum target, GLint level, GLint numlevels, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
|
void ( * qglTexParameterf )(GLenum target, GLenum pname, GLfloat param);
|
|
void ( * qglTexParameterfv )(GLenum target, GLenum pname, const GLfloat *params);
|
|
void ( * qglTexParameteri )(GLenum target, GLenum pname, GLint param);
|
|
void ( * qglTexParameteriv )(GLenum target, GLenum pname, const GLint *params);
|
|
void ( * qglTexSubImage1D )(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels);
|
|
void ( * qglTexSubImage2D )(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
|
|
void ( * qglTranslated )(GLdouble x, GLdouble y, GLdouble z);
|
|
void ( * qglTranslatef )(GLfloat x, GLfloat y, GLfloat z);
|
|
void ( * qglVertex2d )(GLdouble x, GLdouble y);
|
|
void ( * qglVertex2dv )(const GLdouble *v);
|
|
void ( * qglVertex2f )(GLfloat x, GLfloat y);
|
|
void ( * qglVertex2fv )(const GLfloat *v);
|
|
void ( * qglVertex2i )(GLint x, GLint y);
|
|
void ( * qglVertex2iv )(const GLint *v);
|
|
void ( * qglVertex2s )(GLshort x, GLshort y);
|
|
void ( * qglVertex2sv )(const GLshort *v);
|
|
void ( * qglVertex3d )(GLdouble x, GLdouble y, GLdouble z);
|
|
void ( * qglVertex3dv )(const GLdouble *v);
|
|
void ( * qglVertex3f )(GLfloat x, GLfloat y, GLfloat z);
|
|
void ( * qglVertex3fv )(const GLfloat *v);
|
|
void ( * qglVertex3i )(GLint x, GLint y, GLint z);
|
|
void ( * qglVertex3iv )(const GLint *v);
|
|
void ( * qglVertex3s )(GLshort x, GLshort y, GLshort z);
|
|
void ( * qglVertex3sv )(const GLshort *v);
|
|
void ( * qglVertex4d )(GLdouble x, GLdouble y, GLdouble z, GLdouble w);
|
|
void ( * qglVertex4dv )(const GLdouble *v);
|
|
void ( * qglVertex4f )(GLfloat x, GLfloat y, GLfloat z, GLfloat w);
|
|
void ( * qglVertex4fv )(const GLfloat *v);
|
|
void ( * qglVertex4i )(GLint x, GLint y, GLint z, GLint w);
|
|
void ( * qglVertex4iv )(const GLint *v);
|
|
void ( * qglVertex4s )(GLshort x, GLshort y, GLshort z, GLshort w);
|
|
void ( * qglVertex4sv )(const GLshort *v);
|
|
void ( * qglVertexPointer )(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
|
|
void ( * qglViewport )(GLint x, GLint y, GLsizei width, GLsizei height);
|
|
|
|
#if 0
|
|
void ( * qglMultiTexCoord2fARB )( GLenum texture, GLfloat s, GLfloat t );
|
|
void ( * qglActiveTextureARB )( GLenum texture );
|
|
void ( * qglClientActiveTextureARB )( GLenum texture );
|
|
#endif
|
|
|
|
|
|
#ifdef _WINDOWS
|
|
static bool surfaceToBMP(LPDIRECT3DDEVICE8 pd3dDevice, LPDIRECT3DSURFACE8 lpSurface, const char *fname)
|
|
{
|
|
DWORD outpixel;
|
|
BITMAPFILEHEADER fh;
|
|
BITMAPINFOHEADER bi;
|
|
int outbyte, BufferIndex, width, height, pitch;
|
|
char *WriteBuffer;
|
|
FILE *file;
|
|
HRESULT Error;
|
|
IDirect3DSurface8 *pTempSurf = NULL;
|
|
|
|
// Get the surface description first
|
|
D3DSURFACE_DESC ddsd;
|
|
D3DLOCKED_RECT lrSurf;
|
|
|
|
Error = lpSurface->GetDesc(&ddsd);
|
|
// This writes out 32 bit values, so whatever surface format we were passed in,
|
|
// copy it into a 32 bit surface
|
|
Error = pd3dDevice->CreateImageSurface(ddsd.Width, ddsd.Height, D3DFMT_A8R8G8B8, &pTempSurf);
|
|
|
|
Error = D3DXLoadSurfaceFromSurface(pTempSurf, NULL, NULL, lpSurface, NULL, NULL, D3DX_DEFAULT, 0);
|
|
|
|
file = fopen(fname, "wb");
|
|
if(!file)
|
|
return FALSE;
|
|
|
|
Error = pTempSurf->LockRect(&lrSurf, NULL, 0);
|
|
|
|
BufferIndex = 0;
|
|
width = ddsd.Width;
|
|
height = ddsd.Height;
|
|
pitch = lrSurf.Pitch;
|
|
WriteBuffer = new char[width * height * 3];
|
|
|
|
// Setup the file headers
|
|
((char*)&(fh.bfType))[0] = 'B';
|
|
((char*)&(fh.bfType))[1] = 'M';
|
|
fh.bfSize = (long)(sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER) + width * height * 3);
|
|
fh.bfReserved1 = 0;
|
|
fh.bfReserved2 = 0;
|
|
fh.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
|
|
bi.biSize = sizeof(BITMAPINFOHEADER);
|
|
bi.biWidth = width;
|
|
bi.biHeight = height;
|
|
bi.biPlanes = 1;
|
|
bi.biBitCount = 24;
|
|
bi.biCompression = BI_RGB;
|
|
bi.biSizeImage = 0;
|
|
bi.biXPelsPerMeter = 10000;
|
|
bi.biYPelsPerMeter = 10000;
|
|
bi.biClrUsed = 0;
|
|
bi.biClrImportant = 0;
|
|
|
|
fwrite(&fh, sizeof(BITMAPFILEHEADER), 1, file);
|
|
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, file);
|
|
|
|
char *Bitmap_in = (char*)lrSurf.pBits;
|
|
|
|
for(int y = height - 1; y >= 0; y--)
|
|
{
|
|
for(int x = 0; x < width; x++)
|
|
{
|
|
outpixel = *((DWORD *)(Bitmap_in + x * 4 + y * pitch)); //Load a word
|
|
|
|
//Load up the Blue component and output it
|
|
outbyte = (((outpixel)&0x000000ff));//blue
|
|
WriteBuffer [BufferIndex++] = outbyte;
|
|
|
|
//Load up the green component and output it
|
|
outbyte = (((outpixel>>8)&0x000000ff));
|
|
WriteBuffer [BufferIndex++] = outbyte;
|
|
|
|
//Load up the red component and output it
|
|
outbyte = (((outpixel>>16)&0x000000ff));
|
|
WriteBuffer [BufferIndex++] = outbyte;
|
|
}
|
|
}
|
|
|
|
//At this point the buffer should be full, so just write it out
|
|
fwrite(WriteBuffer, BufferIndex, 1, file);
|
|
|
|
//Now unlock the surface and we're done
|
|
pTempSurf->UnlockRect();
|
|
pTempSurf->Release();
|
|
|
|
fclose(file);
|
|
|
|
delete [] WriteBuffer;
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
=================
|
|
_fixupScreenCoords
|
|
|
|
Clamp coords to screen dimensions and fix Y direction.
|
|
=================
|
|
*/
|
|
static void _fixupScreenCoords(GLint& x, GLint& y, GLsizei& width, GLsizei& height)
|
|
{
|
|
if (x < 0) x = 0;
|
|
else if (x > glConfig.vidWidth) x = glConfig.vidWidth;
|
|
if (y < 0)
|
|
{
|
|
|
|
#ifdef _XBOX
|
|
height += y;
|
|
#endif
|
|
y = 0;
|
|
}
|
|
else if (y > glConfig.vidHeight) y = glConfig.vidHeight;
|
|
|
|
if (width < 0) width = 0;
|
|
#ifdef _XBOX
|
|
else if (x + width > glConfig.vidWidth) width = glConfig.vidWidth - x;
|
|
#endif
|
|
// else if (x + width > glConfig.vidWidth) width = glConfig.vidWidth - x;
|
|
if (height < 0) height = 0;
|
|
else if (y + height > glConfig.vidHeight) height = glConfig.vidHeight - y;
|
|
|
|
// GL and DX disagree on the direction of Y
|
|
y = glConfig.vidHeight - (y + height);
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
_convertCompare
|
|
|
|
Convert GL compare function to DX function.
|
|
=================
|
|
*/
|
|
static D3DCMPFUNC _convertCompare(GLenum func)
|
|
{
|
|
switch (func)
|
|
{
|
|
case GL_NEVER: return D3DCMP_NEVER;
|
|
case GL_LESS: return D3DCMP_LESS;
|
|
case GL_EQUAL: return D3DCMP_EQUAL;
|
|
case GL_LEQUAL: return D3DCMP_LESSEQUAL;
|
|
case GL_GREATER: return D3DCMP_GREATER;
|
|
case GL_NOTEQUAL: return D3DCMP_NOTEQUAL;
|
|
case GL_GEQUAL: return D3DCMP_GREATEREQUAL;
|
|
default: case GL_ALWAYS: return D3DCMP_ALWAYS;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
_convertBlendFactor
|
|
|
|
Convert GL blend mode to DX blend mode.
|
|
=================
|
|
*/
|
|
static D3DBLEND _convertBlendFactor(GLenum factor)
|
|
{
|
|
switch (factor)
|
|
{
|
|
case GL_ZERO: return D3DBLEND_ZERO;
|
|
default: case GL_ONE: return D3DBLEND_ONE;
|
|
case GL_SRC_COLOR: return D3DBLEND_SRCCOLOR;
|
|
case GL_ONE_MINUS_SRC_COLOR: return D3DBLEND_INVSRCCOLOR;
|
|
case GL_SRC_ALPHA: return D3DBLEND_SRCALPHA;
|
|
case GL_ONE_MINUS_SRC_ALPHA: return D3DBLEND_INVSRCALPHA;
|
|
case GL_DST_COLOR: return D3DBLEND_DESTCOLOR;
|
|
case GL_ONE_MINUS_DST_COLOR: return D3DBLEND_INVDESTCOLOR;
|
|
case GL_DST_ALPHA: return D3DBLEND_DESTALPHA;
|
|
case GL_ONE_MINUS_DST_ALPHA: return D3DBLEND_INVDESTALPHA;
|
|
case GL_SRC_ALPHA_SATURATE: return D3DBLEND_SRCALPHASAT;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
_convertPrimMode
|
|
|
|
Convert GL primitive mode to DX primitive mode.
|
|
=================
|
|
*/
|
|
static D3DPRIMITIVETYPE _convertPrimMode(GLenum mode)
|
|
{
|
|
switch (mode)
|
|
{
|
|
case GL_POINTS: return D3DPT_POINTLIST;
|
|
case GL_LINES: return D3DPT_LINELIST;
|
|
case GL_LINE_STRIP: return D3DPT_LINESTRIP;
|
|
case GL_TRIANGLES: return D3DPT_TRIANGLELIST;
|
|
case GL_TRIANGLE_STRIP: return D3DPT_TRIANGLESTRIP;
|
|
case GL_TRIANGLE_FAN: return D3DPT_TRIANGLEFAN;
|
|
#ifdef _XBOX
|
|
case GL_QUADS: return D3DPT_QUADLIST;
|
|
case GL_QUAD_STRIP: return D3DPT_QUADSTRIP;
|
|
#else
|
|
case GL_QUADS: return D3DPT_TRIANGLELIST;
|
|
case GL_QUAD_STRIP: return D3DPT_TRIANGLESTRIP;
|
|
#endif
|
|
case GL_POLYGON: return D3DPT_TRIANGLEFAN;
|
|
default: assert(0); return D3DPT_TRIANGLEFAN;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
_updateDrawStride
|
|
|
|
Update the stride of the draw array based on
|
|
the number of vertex attributes. The stride
|
|
is in DWORDs.
|
|
=================
|
|
*/
|
|
static void _updateDrawStride(GLint normal, GLint tex0, GLint tex1)
|
|
{
|
|
glw_state->drawStride = 4;
|
|
if (normal) glw_state->drawStride += 3;
|
|
if (tex0) glw_state->drawStride += 2;
|
|
if (tex1) glw_state->drawStride += 2;
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
_updateShader
|
|
|
|
Set the vertex shader based on the number
|
|
of texture coordinates.
|
|
=================
|
|
*/
|
|
static void _updateShader(bool normal, bool tex0, bool tex1)//, bool tex2, bool tex3)
|
|
{
|
|
DWORD mask = D3DFVF_XYZ;
|
|
if (normal) mask |= D3DFVF_NORMAL;
|
|
mask |= D3DFVF_DIFFUSE;
|
|
if (tex0 && !tex1) mask |= D3DFVF_TEX1;
|
|
else if (tex1) mask |= D3DFVF_TEX2;
|
|
|
|
// if (mask != glw_state->shaderMask)
|
|
// {
|
|
glw_state->device->SetVertexShader(mask);
|
|
glw_state->shaderMask = mask;
|
|
// }
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
_getCurrentTexture
|
|
|
|
Get the texture information for the currently
|
|
bound texture at a stage.
|
|
=================
|
|
*/
|
|
static glwstate_t::TextureInfo* _getCurrentTexture(int stage)
|
|
{
|
|
glwstate_t::texturexlat_t::iterator i = glw_state->textureXlat.find(
|
|
glw_state->currentTexture[stage]);
|
|
|
|
if (i == glw_state->textureXlat.end()) return NULL;
|
|
else return &i->second;
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
_updateTextures
|
|
|
|
Setup texture stages with color operations, filters
|
|
and wrapping modes as needed.
|
|
=================
|
|
*/
|
|
static void _updateTextures(void)
|
|
{
|
|
for (int t = 0; t < GLW_MAX_TEXTURE_STAGES; ++t)
|
|
{
|
|
if (glw_state->textureStageDirty[t])
|
|
{
|
|
glw_state->textureStageDirty[t] = false;
|
|
|
|
if (glw_state->textureStageEnable[t] && glw_state->currentTexture[t])
|
|
{
|
|
glwstate_t::TextureInfo* info = _getCurrentTexture(t);
|
|
if (!info) continue;
|
|
|
|
glw_state->device->SetTexture(t, info->mipmap);
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_COLOROP, glw_state->textureEnv[t]);
|
|
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_COLORARG1,
|
|
D3DTA_TEXTURE);
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_COLORARG2,
|
|
D3DTA_CURRENT);
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_ALPHAOP,
|
|
glw_state->textureEnv[t]);
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_ALPHAARG1,
|
|
D3DTA_TEXTURE);
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_ALPHAARG2,
|
|
D3DTA_CURRENT);
|
|
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_MAXANISOTROPY,
|
|
info->anisotropy);
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_MINFILTER,
|
|
info->minFilter);
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_MIPFILTER,
|
|
info->mipFilter);
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_MAGFILTER,
|
|
info->magFilter);
|
|
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_ADDRESSU,
|
|
info->wrapU);
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_ADDRESSV,
|
|
info->wrapV);
|
|
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_TEXCOORDINDEX, t);
|
|
|
|
glw_state->device->SetTextureStageState( t, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );
|
|
|
|
/*if(tess.shader)
|
|
{
|
|
if(tess.currentPass < tess.shader->numUnfoggedPasses)
|
|
{
|
|
if(tess.shader->stages[tess.currentPass].isEnvironment)
|
|
{
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_TEXCOORDINDEX, t | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
|
|
}
|
|
}
|
|
}*/
|
|
}
|
|
else
|
|
{
|
|
glw_state->device->SetTexture(t, NULL);
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_COLOROP, D3DTOP_DISABLE);
|
|
glw_state->device->SetTextureStageState(t, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
|
|
}
|
|
}
|
|
//else
|
|
//{
|
|
// // Hard-wired check for turning on hardware environment mapping
|
|
// if( glw_state->textureStageEnable[t] &&
|
|
// glw_state->currentTexture[t] &&
|
|
// tess.shader &&
|
|
// tess.currentPass < tess.shader->numUnfoggedPasses &&
|
|
// tess.shader->stages[tess.currentPass].isEnvironment)
|
|
// {
|
|
// glw_state->device->SetTextureStageState(t, D3DTSS_TEXCOORDINDEX, t | D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR);
|
|
// }
|
|
//}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
_updateMatrices
|
|
|
|
Set the current projection and view transforms to
|
|
the matrices at the top of the relevant stacks.
|
|
=================
|
|
*/
|
|
static void _updateMatrices(void)
|
|
{
|
|
if(glw_state->matricesDirty[glwstate_t::MatrixMode_Projection])
|
|
{
|
|
glw_state->device->SetTransform(D3DTS_PROJECTION,
|
|
glw_state->matrixStack[glwstate_t::MatrixMode_Projection]->GetTop());
|
|
|
|
glw_state->matricesDirty[glwstate_t::MatrixMode_Projection] = false;
|
|
}
|
|
|
|
if(glw_state->matricesDirty[glwstate_t::MatrixMode_Model])
|
|
{
|
|
glw_state->device->SetTransform(D3DTS_VIEW,
|
|
glw_state->matrixStack[glwstate_t::MatrixMode_Model]->GetTop());
|
|
|
|
glw_state->matricesDirty[glwstate_t::MatrixMode_Model] = false;
|
|
}
|
|
|
|
if(glw_state->matricesDirty[glwstate_t::MatrixMode_Texture0])
|
|
{
|
|
glw_state->device->SetTransform(D3DTS_TEXTURE0,
|
|
glw_state->matrixStack[glwstate_t::MatrixMode_Texture0]->GetTop());
|
|
|
|
glw_state->matricesDirty[glwstate_t::MatrixMode_Texture0] = false;
|
|
}
|
|
|
|
if(glw_state->matricesDirty[glwstate_t::MatrixMode_Texture1])
|
|
{
|
|
glw_state->device->SetTransform(D3DTS_TEXTURE1,
|
|
glw_state->matrixStack[glwstate_t::MatrixMode_Texture1]->GetTop());
|
|
|
|
glw_state->matricesDirty[glwstate_t::MatrixMode_Texture1] = false;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
_getMaxVerts
|
|
|
|
Calculate the maximum number of verts to draw
|
|
given a total number to draw, stride and max
|
|
packet size.
|
|
=================
|
|
*/
|
|
static int _getMaxVerts(void)
|
|
{
|
|
int max = glw_state->totalVertices;
|
|
if (max > GLW_MAX_DRAW_PACKET_SIZE / glw_state->drawStride)
|
|
{
|
|
max = GLW_MAX_DRAW_PACKET_SIZE / glw_state->drawStride;
|
|
}
|
|
return max;
|
|
}
|
|
|
|
static int _getMaxIndices(void)
|
|
{
|
|
int max = glw_state->totalIndices;
|
|
if(max > 1022)
|
|
max = 1022;
|
|
|
|
return max;
|
|
}
|
|
|
|
#ifdef _XBOX
|
|
/*
|
|
=================
|
|
_restartDrawPacket
|
|
|
|
Encode a new draw packet header into the draw array.
|
|
=================
|
|
*/
|
|
inline static DWORD* _restartDrawPacket(DWORD* packet, int verts)
|
|
{
|
|
packet[0] = D3DPUSH_ENCODE(D3DPUSH_SET_BEGIN_END, 1);
|
|
packet[1] = glw_state->primitiveMode;
|
|
packet[2] = D3DPUSH_ENCODE(
|
|
D3DPUSH_NOINCREMENT_FLAG|D3DPUSH_INLINE_ARRAY,
|
|
glw_state->drawStride * verts);
|
|
return packet + 3;
|
|
}
|
|
|
|
/*
|
|
=================
|
|
_terminateDrawPacket
|
|
|
|
Finish up the last draw packet.
|
|
=================
|
|
*/
|
|
inline static DWORD* _terminateDrawPacket(DWORD* packet)
|
|
{
|
|
packet[0] = D3DPUSH_ENCODE(D3DPUSH_SET_BEGIN_END, 1);
|
|
packet[1] = 0;
|
|
return packet + 2;
|
|
}
|
|
|
|
#define CMD_DRAW_INDEX_BATCH 0x1800
|
|
inline static DWORD* _restartIndexPacket(DWORD* packet, int numIndices)
|
|
{
|
|
packet[0] = D3DPUSH_ENCODE(D3DPUSH_SET_BEGIN_END, 1);
|
|
packet[1] = glw_state->primitiveMode;
|
|
packet[2] = D3DPUSH_ENCODE( D3DPUSH_NOINCREMENT_FLAG | CMD_DRAW_INDEX_BATCH, numIndices / 2 );
|
|
return packet + 3;
|
|
}
|
|
|
|
inline static DWORD* _terminateIndexPacket(DWORD* packet)
|
|
{
|
|
packet[0] = D3DPUSH_ENCODE(D3DPUSH_SET_BEGIN_END, 1);
|
|
packet[1] = 0;
|
|
return packet + 2;
|
|
}
|
|
|
|
|
|
/*
|
|
=================
|
|
_handleDrawOverflow
|
|
|
|
Prevent a draw packet from getting too
|
|
big for the hardware by restarting it as needed.
|
|
=================
|
|
*/
|
|
static void _handleDrawOverflow(void)
|
|
{
|
|
if (glw_state->numVertices >= glw_state->maxVertices)
|
|
{
|
|
glw_state->drawArray += glw_state->numVertices *
|
|
glw_state->drawStride;
|
|
|
|
glw_state->totalVertices -= glw_state->numVertices;
|
|
glw_state->maxVertices = _getMaxVerts();
|
|
glw_state->numVertices = 0;
|
|
|
|
glw_state->drawArray = _restartDrawPacket(
|
|
glw_state->drawArray, glw_state->maxVertices);
|
|
}
|
|
}
|
|
#else _XBOX
|
|
inline static DWORD* _restartDrawPacket(DWORD* packet, int verts)
|
|
{
|
|
return packet;
|
|
}
|
|
|
|
inline static DWORD* _terminateDrawPacket(DWORD* packet)
|
|
{
|
|
return packet;
|
|
}
|
|
|
|
static void _handleDrawOverflow(void)
|
|
{
|
|
}
|
|
#endif _XBOX
|
|
|
|
|
|
/*
|
|
=================
|
|
_vertexElement
|
|
|
|
Copy position information from the source vertex
|
|
array into a draw array.
|
|
=================
|
|
*/
|
|
#define _vertexElement(push, i) \
|
|
{ \
|
|
DWORD* vert = (DWORD*)((BYTE*)glw_state->vertexPointer + \
|
|
(i) * glw_state->vertexStride); \
|
|
(push)[0] = vert[0]; \
|
|
(push)[1] = vert[1]; \
|
|
(push)[2] = vert[2]; \
|
|
}
|
|
|
|
/*
|
|
=================
|
|
_colorElement
|
|
|
|
Copy color information from the source color
|
|
array into a draw array.
|
|
=================
|
|
*/
|
|
#define _colorElement(push, i) \
|
|
{ \
|
|
DWORD col = *(DWORD*)((BYTE*)glw_state->colorPointer + \
|
|
(i) * glw_state->colorStride); \
|
|
(push)[0] = \
|
|
((col & 0xFF000000) >> 0) | \
|
|
((col & 0x00FF0000) >> 16) | \
|
|
((col & 0x0000FF00) << 0) | \
|
|
((col & 0x000000FF) << 16); \
|
|
}
|
|
|
|
/*
|
|
=================
|
|
_texCoordElement
|
|
|
|
Copy tex coord information from the source tex coord
|
|
array into a draw array.
|
|
=================
|
|
*/
|
|
#define _texCoordElement(push, i, t) \
|
|
{ \
|
|
DWORD* tc = (DWORD*)((BYTE*)glw_state->texCoordPointer[t] + \
|
|
(i) * glw_state->texCoordStride[t]); \
|
|
(push)[0] = tc[0]; \
|
|
(push)[1] = tc[1]; \
|
|
}
|
|
|
|
/*
|
|
=================
|
|
_normalElement
|
|
|
|
Copy normal information from the source normal
|
|
array into a draw array
|
|
=================
|
|
*/
|
|
#define _normalElement(push, i) \
|
|
{ \
|
|
DWORD* norm = (DWORD*)((BYTE*)glw_state->normalPointer + \
|
|
(i) * glw_state->normalStride); \
|
|
(push)[0] = norm[0]; \
|
|
(push)[1] = norm[1]; \
|
|
(push)[2] = norm[2]; \
|
|
}
|
|
|
|
|
|
#define _tangentElement(push, i) \
|
|
{ \
|
|
DWORD* tang = (DWORD*)((BYTE*)&tess.tangent[i]); \
|
|
(push)[0] = tang[0]; \
|
|
(push)[1] = tang[1]; \
|
|
(push)[2] = tang[2]; \
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
=========================================================
|
|
FAST INDEXED GEOMETRY DRAW LOOPS
|
|
|
|
Used by core draw routines to quickly copy
|
|
geometry from various source arrays to main
|
|
draw array.
|
|
=========================================================
|
|
*/
|
|
static void _drawElementsV(GLsizei count, const GLushort* indices)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
_vertexElement(&push[0], indices[i]);
|
|
push[3] = glw_state->currentColor;
|
|
push += 4;
|
|
}
|
|
}
|
|
|
|
static void _drawElementsVN(GLsizei count, const GLushort* indices)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
_vertexElement(&push[0], indices[i]);
|
|
_normalElement(&push[3], indices[i]);
|
|
push[6] = glw_state->currentColor;
|
|
push += 7;
|
|
}
|
|
}
|
|
|
|
static void _drawElementsVC(GLsizei count, const GLushort* indices)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
_vertexElement(&push[0], indices[i]);
|
|
_colorElement(&push[3], indices[i]);
|
|
push += 4;
|
|
}
|
|
}
|
|
|
|
static void _drawElementsVCN(GLsizei count, const GLushort* indices)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
_vertexElement(&push[0], indices[i]);
|
|
_normalElement(&push[3], indices[i]);
|
|
_colorElement(&push[6], indices[i]);
|
|
push += 7;
|
|
}
|
|
}
|
|
|
|
static void _drawElementsVCT(GLsizei count, const GLushort* indices)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
_vertexElement(&push[0], indices[i]);
|
|
_colorElement(&push[3], indices[i]);
|
|
_texCoordElement(&push[4], indices[i], 0);
|
|
push += 6;
|
|
}
|
|
}
|
|
|
|
static void _drawElementsVCNT(GLsizei count, const GLushort* indices)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
_vertexElement(&push[0], indices[i]);
|
|
_normalElement(&push[3], indices[i]);
|
|
_colorElement(&push[6], indices[i]);
|
|
_texCoordElement(&push[7], indices[i], 0);
|
|
push += 9;
|
|
}
|
|
}
|
|
|
|
static void _drawElementsVCTT(GLsizei count, const GLushort* indices)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
_vertexElement(&push[0], indices[i]);
|
|
_colorElement(&push[3], indices[i]);
|
|
_texCoordElement(&push[4], indices[i], 0);
|
|
_texCoordElement(&push[6], indices[i], 1);
|
|
push += 8;
|
|
}
|
|
}
|
|
|
|
static void _drawElementsVCNTT(GLsizei count, const GLushort* indices)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
_vertexElement(&push[0], indices[i]);
|
|
_normalElement(&push[3], indices[i]);
|
|
_colorElement(&push[6], indices[i]);
|
|
_texCoordElement(&push[7], indices[i], 0);
|
|
_texCoordElement(&push[9], indices[i], 1);
|
|
push += 11;
|
|
}
|
|
}
|
|
|
|
static void _drawElementsVT(GLsizei count, const GLushort* indices)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
_vertexElement(&push[0], indices[i]);
|
|
push[3] = glw_state->currentColor;
|
|
_texCoordElement(&push[4], indices[i], 0);
|
|
push += 6;
|
|
}
|
|
}
|
|
|
|
static void _drawElementsVNT(GLsizei count, const GLushort* indices)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
_vertexElement(&push[0], indices[i]);
|
|
_normalElement(&push[3], indices[i]);
|
|
push[6] = glw_state->currentColor;
|
|
_texCoordElement(&push[7], indices[i], 0);
|
|
push += 9;
|
|
}
|
|
}
|
|
|
|
static void _drawElementsVTT(GLsizei count, const GLushort* indices)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
_vertexElement(&push[0], indices[i]);
|
|
push[3] = glw_state->currentColor;
|
|
_texCoordElement(&push[4], indices[i], 0);
|
|
_texCoordElement(&push[6], indices[i], 1);
|
|
push += 8;
|
|
}
|
|
}
|
|
|
|
static void _drawElementsVNTT(GLsizei count, const GLushort* indices)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = 0; i < count; ++i)
|
|
{
|
|
_vertexElement(&push[0], indices[i]);
|
|
_normalElement(&push[3], indices[i]);
|
|
push[6] = glw_state->currentColor;
|
|
_texCoordElement(&push[7], indices[i], 0);
|
|
_texCoordElement(&push[9], indices[i], 1);
|
|
push += 11;
|
|
}
|
|
}
|
|
|
|
|
|
static void _drawElementsLightShader(GLsizei count, const GLushort* indices)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for(int i = 0; i < count; ++i)
|
|
{
|
|
_vertexElement(&push[0], indices[i]);
|
|
_normalElement(&push[3], indices[i]);
|
|
_texCoordElement(&push[6], indices[i], 0);
|
|
_tangentElement(&push[8], indices[i]);
|
|
push += 11;
|
|
}
|
|
}
|
|
|
|
static void _drawElementsBumpShader(GLsizei count, const GLushort* indices)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for(int i = 0; i < count; ++i)
|
|
{
|
|
_vertexElement(&push[0], indices[i]);
|
|
_normalElement(&push[3], indices[i]);
|
|
_texCoordElement(&push[6], indices[i], 0);
|
|
_texCoordElement(&push[8], indices[i], 1);
|
|
_tangentElement(&push[10], indices[i]);
|
|
push += 13;
|
|
}
|
|
}
|
|
|
|
static void _drawElementsEnvShader(GLsizei count, const GLushort* indices)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for(int i = 0; i < count; ++i)
|
|
{
|
|
_vertexElement(&push[0], indices[i]);
|
|
_normalElement(&push[3], indices[i]);
|
|
push += 6;
|
|
}
|
|
}
|
|
|
|
typedef void(*drawelemfunc_t)(GLsizei, const GLushort*);
|
|
static drawelemfunc_t _drawElementFuncTable[12] =
|
|
{
|
|
_drawElementsV,
|
|
_drawElementsVN,
|
|
_drawElementsVT,
|
|
_drawElementsVNT,
|
|
_drawElementsVTT,
|
|
_drawElementsVNTT,
|
|
_drawElementsVC,
|
|
_drawElementsVCN,
|
|
_drawElementsVCT,
|
|
_drawElementsVCNT,
|
|
_drawElementsVCTT,
|
|
_drawElementsVCNTT,
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
=========================================================
|
|
FAST GEOMETRY DRAW LOOPS
|
|
|
|
Used by core draw routines to quickly copy
|
|
geometry from various source arrays to main
|
|
draw array.
|
|
=========================================================
|
|
*/
|
|
static void _drawArraysV(GLsizei first, GLsizei last)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = first; i < last; ++i)
|
|
{
|
|
_vertexElement(&push[0], i);
|
|
push[3] = glw_state->currentColor;
|
|
push += 4;
|
|
}
|
|
}
|
|
|
|
static void _drawArraysVN(GLsizei first, GLsizei last)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = first; i < last; ++i)
|
|
{
|
|
_vertexElement(&push[0], i);
|
|
_normalElement(&push[3], i);
|
|
push[6] = glw_state->currentColor;
|
|
push += 7;
|
|
}
|
|
}
|
|
|
|
static void _drawArraysVC(GLsizei first, GLsizei last)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = first; i < last; ++i)
|
|
{
|
|
_vertexElement(&push[0], i);
|
|
_colorElement(&push[3], i);
|
|
push += 4;
|
|
}
|
|
}
|
|
|
|
static void _drawArraysVCN(GLsizei first, GLsizei last)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = first; i < last; ++i)
|
|
{
|
|
_vertexElement(&push[0], i);
|
|
_normalElement(&push[3], i);
|
|
_colorElement(&push[6], i);
|
|
push += 7;
|
|
}
|
|
}
|
|
|
|
static void _drawArraysVCT(GLsizei first, GLsizei last)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = first; i < last; ++i)
|
|
{
|
|
_vertexElement(&push[0], i);
|
|
_colorElement(&push[3], i);
|
|
_texCoordElement(&push[4], i, 0);
|
|
push += 6;
|
|
}
|
|
}
|
|
|
|
static void _drawArraysVCNT(GLsizei first, GLsizei last)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = first; i < last; ++i)
|
|
{
|
|
_vertexElement(&push[0], i);
|
|
_normalElement(&push[3], i);
|
|
_colorElement(&push[6], i);
|
|
_texCoordElement(&push[7], i, 0);
|
|
push += 9;
|
|
}
|
|
}
|
|
|
|
static void _drawArraysVCTT(GLsizei first, GLsizei last)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = first; i < last; ++i)
|
|
{
|
|
_vertexElement(&push[0], i);
|
|
_colorElement(&push[3], i);
|
|
_texCoordElement(&push[4], i, 0);
|
|
_texCoordElement(&push[6], i, 1);
|
|
push += 8;
|
|
}
|
|
}
|
|
|
|
static void _drawArraysVCNTT(GLsizei first, GLsizei last)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = first; i < last; ++i)
|
|
{
|
|
_vertexElement(&push[0], i);
|
|
_normalElement(&push[3], i);
|
|
_colorElement(&push[6], i);
|
|
_texCoordElement(&push[7], i, 0);
|
|
_texCoordElement(&push[9], i, 1);
|
|
push += 11;
|
|
}
|
|
}
|
|
|
|
static void _drawArraysVT(GLsizei first, GLsizei last)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = first; i < last; ++i)
|
|
{
|
|
_vertexElement(&push[0], i);
|
|
push[3] = glw_state->currentColor;
|
|
_texCoordElement(&push[4], i, 0);
|
|
push += 6;
|
|
}
|
|
}
|
|
|
|
static void _drawArraysVNT(GLsizei first, GLsizei last)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = first; i < last; ++i)
|
|
{
|
|
_vertexElement(&push[0], i);
|
|
_normalElement(&push[3], i);
|
|
push[6] = glw_state->currentColor;
|
|
_texCoordElement(&push[7], i, 0);
|
|
push += 9;
|
|
}
|
|
}
|
|
|
|
static void _drawArraysVTT(GLsizei first, GLsizei last)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = first; i < last; ++i)
|
|
{
|
|
_vertexElement(&push[0], i);
|
|
push[3] = glw_state->currentColor;
|
|
_texCoordElement(&push[4], i, 0);
|
|
_texCoordElement(&push[6], i, 1);
|
|
push += 8;
|
|
}
|
|
}
|
|
|
|
static void _drawArraysVNTT(GLsizei first, GLsizei last)
|
|
{
|
|
DWORD* push = glw_state->drawArray;
|
|
for (int i = first; i < last; ++i)
|
|
{
|
|
_vertexElement(&push[0], i);
|
|
_normalElement(&push[3], i);
|
|
push[6] = glw_state->currentColor;
|
|
_texCoordElement(&push[7], i, 0);
|
|
_texCoordElement(&push[9], i, 1);
|
|
push += 11;
|
|
}
|
|
}
|
|
|
|
typedef void(*drawarrayfunc_t)(GLsizei, GLsizei);
|
|
static drawarrayfunc_t _drawArrayFuncTable[12] =
|
|
{
|
|
_drawArraysV,
|
|
_drawArraysVN,
|
|
_drawArraysVT,
|
|
_drawArraysVNT,
|
|
_drawArraysVTT,
|
|
_drawArraysVNTT,
|
|
_drawArraysVC,
|
|
_drawArraysVCN,
|
|
_drawArraysVCT,
|
|
_drawArraysVCNT,
|
|
_drawArraysVCTT,
|
|
_drawArraysVCNTT,
|
|
};
|
|
|
|
|
|
/*
|
|
=================
|
|
_getDrawFunc
|
|
|
|
Figure which drawing function we need based on
|
|
what vertex components we have. Use the returned
|
|
integer to index the draw function tables.
|
|
=================
|
|
*/
|
|
static int _getDrawFunc(void)
|
|
{
|
|
int func = 0;
|
|
if (glw_state->colorArrayState) func += 6;
|
|
if (glw_state->texCoordArrayState[0]) func += 2;
|
|
if (glw_state->texCoordArrayState[1]) func += 2;
|
|
if (glw_state->normalArrayState) ++func;
|
|
return func;
|
|
}
|
|
|
|
|
|
static void dllAccum(GLenum op, GLfloat value)
|
|
{
|
|
assert(false);
|
|
}
|
|
|
|
static void dllAlphaFunc(GLenum func, GLclampf ref)
|
|
{
|
|
D3DCMPFUNC f = _convertCompare(func);
|
|
glw_state->device->SetRenderState(D3DRS_ALPHAFUNC, f);
|
|
glw_state->device->SetRenderState(D3DRS_ALPHAREF, (DWORD)(ref * 255.));
|
|
}
|
|
|
|
GLboolean dllAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences)
|
|
{
|
|
assert(false);
|
|
return 1;
|
|
}
|
|
|
|
static void dllArrayElement(GLint i)
|
|
{
|
|
assert(glw_state->inDrawBlock);
|
|
|
|
_handleDrawOverflow();
|
|
|
|
DWORD* push = &glw_state->drawArray[glw_state->numVertices *
|
|
glw_state->drawStride];
|
|
|
|
_vertexElement(push, i);
|
|
push += 3;
|
|
|
|
if (glw_state->colorArrayState)
|
|
{
|
|
_colorElement(push, i);
|
|
++push;
|
|
}
|
|
else
|
|
{
|
|
*push++ = glw_state->currentColor;
|
|
}
|
|
|
|
for (int t = 0; t < GLW_MAX_TEXTURE_STAGES; ++t)
|
|
{
|
|
if (glw_state->texCoordArrayState[t])
|
|
{
|
|
_texCoordElement(push, i, t);
|
|
push += 2;
|
|
}
|
|
}
|
|
|
|
++glw_state->numVertices;
|
|
}
|
|
|
|
// EXTENSION: Begin a drawing block with at verts vertices
|
|
static void dllBeginEXT(GLenum mode, GLint verts, GLint colors, GLint normals, GLint tex0, GLint tex1)//, GLint tex2, GLint tex3)
|
|
{
|
|
assert(!glw_state->inDrawBlock);
|
|
|
|
// start the draw block
|
|
glw_state->inDrawBlock = true;
|
|
glw_state->primitiveMode = _convertPrimMode(mode);
|
|
|
|
// update DX with any pending state changes
|
|
_updateDrawStride(normals, tex0, tex1);//, tex2, tex3);
|
|
_updateShader(normals, tex0, tex1);//, tex2, tex3);
|
|
_updateTextures();
|
|
_updateMatrices();
|
|
|
|
// set vertex counters
|
|
glw_state->numVertices = 0;
|
|
glw_state->totalVertices = verts;
|
|
glw_state->maxVertices = _getMaxVerts();
|
|
|
|
#ifdef _XBOX
|
|
// open a draw packet
|
|
//int num_packets = ((verts * glw_state->drawStride) / GLW_MAX_DRAW_PACKET_SIZE) + 1;
|
|
int num_packets;
|
|
if(glw_state->maxVertices == 0) {
|
|
num_packets = 1;
|
|
} else {
|
|
num_packets = (verts / glw_state->maxVertices) + (!!(verts % glw_state->maxVertices));
|
|
}
|
|
int cmd_size = num_packets * 3;
|
|
int vert_size = glw_state->drawStride * verts;
|
|
|
|
glw_state->device->BeginPush(vert_size + cmd_size + 2,
|
|
&glw_state->drawArray);
|
|
|
|
glw_state->drawArray = _restartDrawPacket(
|
|
glw_state->drawArray, glw_state->maxVertices);
|
|
#endif
|
|
}
|
|
|
|
static void dllBegin(GLenum mode)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
// EXTENSION: Start a new drawing frame
|
|
GLboolean dllBeginFrame(void)
|
|
{
|
|
GLboolean result = glw_state->device->BeginScene() == D3D_OK;
|
|
return result;
|
|
}
|
|
|
|
// EXTENSION: Begin shadow draw mode
|
|
static void dllBeginShadow(void)
|
|
{
|
|
//Intentionally left blank
|
|
}
|
|
|
|
static void dllBindTexture(GLenum target, GLuint texture)
|
|
{
|
|
assert(target == GL_TEXTURE_2D);
|
|
|
|
if (glw_state->currentTexture[glw_state->serverTU] != texture)
|
|
{
|
|
glw_state->currentTexture[glw_state->serverTU] = texture;
|
|
glw_state->textureStageDirty[glw_state->serverTU] = true;
|
|
}
|
|
}
|
|
|
|
static void dllBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap)
|
|
{
|
|
assert(false);
|
|
}
|
|
|
|
static void dllBlendFunc(GLenum sfactor, GLenum dfactor)
|
|
{
|
|
D3DBLEND s = _convertBlendFactor(sfactor);
|
|
D3DBLEND d = _convertBlendFactor(dfactor);
|
|
|
|
glw_state->device->SetRenderState(D3DRS_SRCBLEND, s);
|
|
glw_state->device->SetRenderState(D3DRS_DESTBLEND, d);
|
|
}
|
|
|
|
static void dllCallList(GLuint lnum)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllCallLists(GLsizei n, GLenum type, const GLvoid *lists)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllClear(GLbitfield mask)
|
|
{
|
|
DWORD m = 0;
|
|
|
|
if (mask & GL_COLOR_BUFFER_BIT) m |= D3DCLEAR_TARGET;
|
|
if (mask & GL_STENCIL_BUFFER_BIT) m |= D3DCLEAR_STENCIL;
|
|
|
|
#ifdef _XBOX
|
|
// Clearing stencil when clearing depth buffer
|
|
// is faster on Xbox than just clearing depth alone.
|
|
if (mask & GL_DEPTH_BUFFER_BIT) m |= D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL;
|
|
#else
|
|
if (mask & GL_DEPTH_BUFFER_BIT) m |= D3DCLEAR_ZBUFFER;
|
|
#endif
|
|
|
|
glw_state->device->Clear(0, NULL, m, glw_state->clearColor,
|
|
glw_state->clearDepth, glw_state->clearStencil);
|
|
}
|
|
|
|
static void dllClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
|
|
{
|
|
glw_state->clearColor = D3DCOLOR_COLORVALUE(red, green, blue, alpha);
|
|
}
|
|
|
|
static void dllClearDepth(GLclampd depth)
|
|
{
|
|
glw_state->clearDepth = depth;
|
|
}
|
|
|
|
static void dllClearIndex(GLfloat c)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllClearStencil(GLint s)
|
|
{
|
|
glw_state->clearStencil = s;
|
|
}
|
|
|
|
static void dllClipPlane(GLenum plane, const GLdouble *equation)
|
|
{
|
|
//FIXME
|
|
}
|
|
|
|
static void setIntColor(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
|
|
{
|
|
glw_state->currentColor = D3DCOLOR_RGBA(red, green, blue, alpha);
|
|
}
|
|
|
|
static void setFloatColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
|
|
{
|
|
glw_state->currentColor = D3DCOLOR_COLORVALUE(red, green, blue, alpha);
|
|
}
|
|
|
|
static void dllColor3b(GLbyte red, GLbyte green, GLbyte blue)
|
|
{
|
|
setIntColor(red, green, blue, 127);
|
|
}
|
|
|
|
static void dllColor3bv(const GLbyte *v)
|
|
{
|
|
setIntColor(v[0], v[1], v[2], 127);
|
|
}
|
|
|
|
static void dllColor3d(GLdouble red, GLdouble green, GLdouble blue)
|
|
{
|
|
setFloatColor(red, green, blue, 1.f);
|
|
}
|
|
|
|
static void dllColor3dv(const GLdouble *v)
|
|
{
|
|
setFloatColor(v[0], v[1], v[2], 1.f);
|
|
}
|
|
|
|
static void dllColor3f(GLfloat red, GLfloat green, GLfloat blue)
|
|
{
|
|
setFloatColor(red, green, blue, 1.f);
|
|
}
|
|
|
|
static void dllColor3fv(const GLfloat *v)
|
|
{
|
|
setFloatColor(v[0], v[1], v[2], 1.f);
|
|
}
|
|
|
|
static void dllColor3i(GLint red, GLint green, GLint blue)
|
|
{
|
|
setIntColor(red, green, blue, 127);
|
|
}
|
|
|
|
static void dllColor3iv(const GLint *v)
|
|
{
|
|
setIntColor(v[0], v[1], v[2], 127);
|
|
}
|
|
|
|
static void dllColor3s(GLshort red, GLshort green, GLshort blue)
|
|
{
|
|
setIntColor(red, green, blue, 127);
|
|
}
|
|
|
|
static void dllColor3sv(const GLshort *v)
|
|
{
|
|
setIntColor(v[0], v[1], v[2], 127);
|
|
}
|
|
|
|
static void dllColor3ub(GLubyte red, GLubyte green, GLubyte blue)
|
|
{
|
|
setIntColor(red, green, blue, 127);
|
|
}
|
|
|
|
static void dllColor3ubv(const GLubyte *v)
|
|
{
|
|
setIntColor(v[0], v[1], v[2], 127);
|
|
}
|
|
|
|
static void dllColor3ui(GLuint red, GLuint green, GLuint blue)
|
|
{
|
|
setIntColor(red, green, blue, 127);
|
|
}
|
|
|
|
static void dllColor3uiv(const GLuint *v)
|
|
{
|
|
setIntColor(v[0], v[1], v[2], 127);
|
|
}
|
|
|
|
static void dllColor3us(GLushort red, GLushort green, GLushort blue)
|
|
{
|
|
setIntColor(red, green, blue, 127);
|
|
}
|
|
|
|
static void dllColor3usv(const GLushort *v)
|
|
{
|
|
setIntColor(v[0], v[1], v[2], 127);
|
|
}
|
|
|
|
static void dllColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha)
|
|
{
|
|
setIntColor(red, green, blue, alpha);
|
|
}
|
|
|
|
static void dllColor4bv(const GLbyte *v)
|
|
{
|
|
setIntColor(v[0], v[1], v[2], v[3]);
|
|
}
|
|
|
|
static void dllColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha)
|
|
{
|
|
setFloatColor(red, green, blue, alpha);
|
|
}
|
|
|
|
static void dllColor4dv(const GLdouble *v)
|
|
{
|
|
setFloatColor(v[0], v[1], v[2], v[3]);
|
|
}
|
|
|
|
static void dllColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
|
|
{
|
|
setFloatColor(red, green, blue, alpha);
|
|
}
|
|
|
|
static void dllColor4fv(const GLfloat *v)
|
|
{
|
|
setFloatColor(v[0], v[1], v[2], v[3]);
|
|
}
|
|
|
|
static void dllColor4i(GLint red, GLint green, GLint blue, GLint alpha)
|
|
{
|
|
setIntColor(red, green, blue, alpha);
|
|
}
|
|
|
|
static void dllColor4iv(const GLint *v)
|
|
{
|
|
setIntColor(v[0], v[1], v[2], v[3]);
|
|
}
|
|
|
|
static void dllColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha)
|
|
{
|
|
setIntColor(red, green, blue, alpha);
|
|
}
|
|
|
|
static void dllColor4sv(const GLshort *v)
|
|
{
|
|
setIntColor(v[0], v[1], v[2], v[3]);
|
|
}
|
|
|
|
static void dllColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
|
|
{
|
|
setIntColor(red, green, blue, alpha);
|
|
}
|
|
|
|
static void dllColor4ubv(const GLubyte *v)
|
|
{
|
|
setIntColor(v[0], v[1], v[2], v[3]);
|
|
}
|
|
|
|
static void dllColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha)
|
|
{
|
|
setIntColor(red, green, blue, alpha);
|
|
}
|
|
|
|
static void dllColor4uiv(const GLuint *v)
|
|
{
|
|
setIntColor(v[0], v[1], v[2], v[3]);
|
|
}
|
|
|
|
static void dllColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha)
|
|
{
|
|
setIntColor(red, green, blue, alpha);
|
|
}
|
|
|
|
static void dllColor4usv(const GLushort *v)
|
|
{
|
|
setIntColor(v[0], v[1], v[2], v[3]);
|
|
}
|
|
|
|
static void dllColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
|
|
{
|
|
DWORD m = 0;
|
|
if (red) m |= D3DCOLORWRITEENABLE_RED;
|
|
if (green) m |= D3DCOLORWRITEENABLE_GREEN;
|
|
if (blue) m |= D3DCOLORWRITEENABLE_BLUE;
|
|
if (alpha) m |= D3DCOLORWRITEENABLE_ALPHA;
|
|
glw_state->device->SetRenderState(D3DRS_COLORWRITEENABLE, m);
|
|
}
|
|
|
|
static void dllColorMaterial(GLenum face, GLenum mode)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
|
|
{
|
|
assert(!glw_state->inDrawBlock);
|
|
assert(size == 4 && type == GL_UNSIGNED_BYTE);
|
|
|
|
stride = (stride == 0) ? sizeof(GLint) : stride;
|
|
|
|
glw_state->colorPointer = pointer;
|
|
glw_state->colorStride = stride;
|
|
}
|
|
|
|
static void dllCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
/**********
|
|
copies a portion of the backbuffer to the current texture.
|
|
the current texture must be a linear format texture, if
|
|
a swizzled texture format is needed, use
|
|
dllCopyBackBufferToTexEXT
|
|
**********/
|
|
static void dllCopyTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
|
|
{
|
|
// check to make sure everything passed in is supported
|
|
assert((target == GL_TEXTURE_2D) && (level == 0) && (border == 0));
|
|
|
|
// locals
|
|
RECT rSrc;
|
|
POINT ptUpperLeft;
|
|
LPDIRECT3DSURFACE8 tSurf;
|
|
LPDIRECT3DSURFACE8 backbuffer;
|
|
glwstate_t::TextureInfo* tex;
|
|
HRESULT res;
|
|
|
|
// get the current texture
|
|
tex = _getCurrentTexture(glw_state->serverTU);
|
|
if (tex == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// set up the source rectangle
|
|
rSrc.left = x;
|
|
rSrc.right = x + width;
|
|
rSrc.top = (480 - y) - height;
|
|
rSrc.bottom = (480 - y);
|
|
|
|
// set up the target point
|
|
ptUpperLeft.x = 0;
|
|
ptUpperLeft.y = 0;
|
|
|
|
// attach the current texture to a surface
|
|
tex->mipmap->GetSurfaceLevel(0, &tSurf);
|
|
|
|
// attach the back buffer to a surface
|
|
res = glw_state->device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
|
|
|
|
// copy the data
|
|
res = glw_state->device->CopyRects(backbuffer, &rSrc, 0, tSurf, &ptUpperLeft);
|
|
|
|
// release surfaces
|
|
tSurf->Release();
|
|
backbuffer->Release();
|
|
}
|
|
|
|
static void dllCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllCullFace(GLenum mode)
|
|
{
|
|
switch (mode)
|
|
{
|
|
default: case GL_BACK: glw_state->cullMode = D3DCULL_CW; break;
|
|
case GL_FRONT: glw_state->cullMode = D3DCULL_CCW; break;
|
|
}
|
|
|
|
glw_state->device->SetRenderState(D3DRS_CULLMODE, glw_state->cullMode);
|
|
}
|
|
|
|
static void dllDeleteLists(GLuint lnum, GLsizei range)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllDeleteTextures(GLsizei n, const GLuint *textures)
|
|
{
|
|
for (int t = 0; t < n; ++t)
|
|
{
|
|
glwstate_t::texturexlat_t::iterator i =
|
|
glw_state->textureXlat.find(textures[t]);
|
|
|
|
if (i != glw_state->textureXlat.end())
|
|
{
|
|
#if MEMORY_PROFILE
|
|
texMemSize -= getTexMemSize(i->second.mipmap);
|
|
#endif
|
|
i->second.mipmap->Release();
|
|
glw_state->textureXlat.erase(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void dllDepthFunc(GLenum func)
|
|
{
|
|
D3DCMPFUNC f = _convertCompare(func);
|
|
glw_state->device->SetRenderState(D3DRS_ZFUNC, f);
|
|
}
|
|
|
|
static void dllDepthMask(GLboolean flag)
|
|
{
|
|
glw_state->device->SetRenderState(D3DRS_ZWRITEENABLE, flag);
|
|
}
|
|
|
|
static void dllDepthRange(GLclampd zNear, GLclampd zFar)
|
|
{
|
|
glw_state->viewport.MinZ = zNear;
|
|
glw_state->viewport.MaxZ = zFar;
|
|
glw_state->device->SetViewport(&glw_state->viewport);
|
|
}
|
|
|
|
#ifdef _XBOX
|
|
static void setPresent(bool vsync)
|
|
{
|
|
//extern void ShowOSMemory();
|
|
//ShowOSMemory();
|
|
|
|
D3DPRESENT_PARAMETERS pp;
|
|
pp.BackBufferWidth = glConfig.vidWidth;
|
|
pp.BackBufferHeight = glConfig.vidHeight;
|
|
pp.BackBufferFormat = D3DFMT_X8R8G8B8;
|
|
pp.BackBufferCount = 1;
|
|
pp.MultiSampleType = D3DMULTISAMPLE_NONE; //D3DMULTISAMPLE_4_SAMPLES_SUPERSAMPLE_LINEAR;
|
|
pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
|
pp.hDeviceWindow = 0;
|
|
pp.Windowed = FALSE;
|
|
pp.EnableAutoDepthStencil = TRUE;
|
|
pp.AutoDepthStencilFormat = D3DFMT_D24S8;
|
|
pp.Flags = 0;
|
|
pp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
|
|
pp.FullScreen_PresentationInterval =
|
|
vsync ? D3DPRESENT_INTERVAL_DEFAULT : D3DPRESENT_INTERVAL_IMMEDIATE;
|
|
pp.BufferSurfaces[0] = pp.BufferSurfaces[1] = pp.BufferSurfaces[2] = 0;
|
|
pp.DepthStencilSurface = 0;
|
|
glw_state->device->PersistDisplay();
|
|
glw_state->device->Reset(&pp);
|
|
|
|
//ShowOSMemory();
|
|
}
|
|
#endif
|
|
|
|
static void setCap(GLenum cap, bool flag)
|
|
{
|
|
switch (cap)
|
|
{
|
|
case GL_ALPHA_TEST: glw_state->device->SetRenderState(D3DRS_ALPHATESTENABLE, flag); break;
|
|
case GL_BLEND: glw_state->device->SetRenderState(D3DRS_ALPHABLENDENABLE, flag); break;
|
|
case GL_CULL_FACE:
|
|
glw_state->cullEnable = flag;
|
|
glw_state->device->SetRenderState(D3DRS_CULLMODE,
|
|
flag ? glw_state->cullMode : D3DCULL_NONE);
|
|
break;
|
|
case GL_DEPTH_TEST: glw_state->device->SetRenderState(D3DRS_ZENABLE, flag); break;
|
|
case GL_LIGHTING: glw_state->device->SetRenderState(D3DRS_LIGHTING, flag); break;
|
|
#ifdef _XBOX
|
|
case GL_POLYGON_OFFSET_POINT:
|
|
glw_state->device->SetRenderState(D3DRS_POINTOFFSETENABLE, flag);
|
|
break;
|
|
case GL_POLYGON_OFFSET_LINE:
|
|
glw_state->device->SetRenderState(D3DRS_WIREFRAMEOFFSETENABLE, flag);
|
|
break;
|
|
case GL_POLYGON_OFFSET_FILL:
|
|
glw_state->device->SetRenderState(D3DRS_SOLIDOFFSETENABLE, flag);
|
|
break;
|
|
case GL_SCISSOR_TEST:
|
|
glw_state->scissorEnable = flag;
|
|
glw_state->device->SetScissors(flag ? 1 : 0, FALSE, &glw_state->scissorBox);
|
|
break;
|
|
#endif
|
|
case GL_STENCIL_TEST: glw_state->device->SetRenderState(D3DRS_STENCILENABLE, flag); break;
|
|
case GL_TEXTURE_2D:
|
|
glw_state->textureStageEnable[glw_state->serverTU] = flag;
|
|
glw_state->textureStageDirty[glw_state->serverTU] = true;
|
|
break;
|
|
case GL_FOG:
|
|
glw_state->device->SetRenderState(D3DRS_FOGENABLE, flag);
|
|
break;
|
|
#ifdef _XBOX
|
|
case GL_VSYNC:
|
|
setPresent(flag);
|
|
break;
|
|
#endif
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
static void dllDisable(GLenum cap)
|
|
{
|
|
setCap(cap, false);
|
|
}
|
|
|
|
static void setArrayState(GLenum cap, bool state)
|
|
{
|
|
switch (cap)
|
|
{
|
|
case GL_COLOR_ARRAY: glw_state->colorArrayState = state; break;
|
|
case GL_TEXTURE_COORD_ARRAY: glw_state->texCoordArrayState[glw_state->clientTU] = state; break;
|
|
case GL_VERTEX_ARRAY: glw_state->vertexArrayState = state; break;
|
|
case GL_NORMAL_ARRAY: glw_state->normalArrayState = state; break;
|
|
}
|
|
}
|
|
|
|
static void dllDisableClientState(GLenum array)
|
|
{
|
|
assert(!glw_state->inDrawBlock);
|
|
setArrayState(array, false);
|
|
}
|
|
|
|
#ifdef _WINDOWS
|
|
static void _convertQuadsToTris(GLint first, GLsizei count)
|
|
{
|
|
glw_state->vertexPointerBack = glw_state->vertexPointer;
|
|
glw_state->normalPointerBack = glw_state->normalPointer;
|
|
glw_state->colorPointerBack = glw_state->colorPointer;
|
|
glw_state->texCoordPointerBack[0] = glw_state->texCoordPointer[0];
|
|
glw_state->texCoordPointerBack[1] = glw_state->texCoordPointer[1];
|
|
|
|
{
|
|
glw_state->vertexPointer =
|
|
Z_Malloc(count * glw_state->vertexStride * 3 / 2,
|
|
TAG_TEMP_WORKSPACE, qfalse);
|
|
for (int i = 0; i < count; i += 4)
|
|
{
|
|
int stride = glw_state->vertexStride / sizeof(float);
|
|
float* dst = (float*)glw_state->vertexPointer + (i * 3 / 2) * stride;
|
|
const float* src = (const float*)glw_state->vertexPointerBack +
|
|
(first + i) * stride;
|
|
|
|
for (int j = 0; j < 3; ++j)
|
|
{
|
|
dst[0 * stride + j] = src[0 * stride + j];
|
|
dst[1 * stride + j] = src[1 * stride + j];
|
|
dst[2 * stride + j] = src[2 * stride + j];
|
|
dst[3 * stride + j] = src[0 * stride + j];
|
|
dst[4 * stride + j] = src[2 * stride + j];
|
|
dst[5 * stride + j] = src[3 * stride + j];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (glw_state->normalArrayState)
|
|
{
|
|
glw_state->normalPointer =
|
|
Z_Malloc(count * glw_state->normalStride * 3 / 2,
|
|
TAG_TEMP_WORKSPACE, qfalse);
|
|
|
|
for (int i = 0; i < count; i += 4)
|
|
{
|
|
int stride = glw_state->normalStride / sizeof(float);
|
|
float* dst = (float*)glw_state->normalPointer + (i * 3 / 2) * stride;
|
|
const float* src = (const float*)glw_state->normalPointerBack +
|
|
(first + i) * stride;
|
|
|
|
for (int j = 0; j < 3; ++j)
|
|
{
|
|
dst[0 * stride + j] = src[0 * stride + j];
|
|
dst[1 * stride + j] = src[1 * stride + j];
|
|
dst[2 * stride + j] = src[2 * stride + j];
|
|
dst[3 * stride + j] = src[0 * stride + j];
|
|
dst[4 * stride + j] = src[2 * stride + j];
|
|
dst[5 * stride + j] = src[3 * stride + j];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (glw_state->colorArrayState)
|
|
{
|
|
glw_state->colorPointer =
|
|
Z_Malloc(count * glw_state->colorStride * 3 / 2,
|
|
TAG_TEMP_WORKSPACE, qfalse);
|
|
|
|
for (int i = 0; i < count; i += 4)
|
|
{
|
|
int stride = glw_state->colorStride / sizeof(DWORD);
|
|
DWORD* dst = (DWORD*)glw_state->colorPointer + (i * 3 / 2) * stride;
|
|
const DWORD* src = (const DWORD*)glw_state->colorPointerBack +
|
|
(first + i) * stride;
|
|
|
|
dst[0 * stride] = src[0 * stride];
|
|
dst[1 * stride] = src[1 * stride];
|
|
dst[2 * stride] = src[2 * stride];
|
|
dst[3 * stride] = src[0 * stride];
|
|
dst[4 * stride] = src[2 * stride];
|
|
dst[5 * stride] = src[3 * stride];
|
|
}
|
|
}
|
|
|
|
for (int t = 0; t < GLW_MAX_TEXTURE_STAGES; ++t)
|
|
{
|
|
if (glw_state->texCoordArrayState[t])
|
|
{
|
|
glw_state->texCoordPointer[t] =
|
|
Z_Malloc(count * glw_state->texCoordStride[t] * 3 / 2,
|
|
TAG_TEMP_WORKSPACE, qfalse);
|
|
|
|
for (int i = 0; i < count; i += 4)
|
|
{
|
|
int stride = glw_state->texCoordStride[t] / sizeof(float);
|
|
float* dst = (float*)glw_state->texCoordPointer[t] + (i * 3 / 2) * stride;
|
|
const float* src = (const float*)glw_state->texCoordPointerBack[t] +
|
|
(first + i) * stride;
|
|
|
|
for (int j = 0; j < 2; ++j)
|
|
{
|
|
dst[0 * stride + j] = src[0 * stride + j];
|
|
dst[1 * stride + j] = src[1 * stride + j];
|
|
dst[2 * stride + j] = src[2 * stride + j];
|
|
dst[3 * stride + j] = src[0 * stride + j];
|
|
dst[4 * stride + j] = src[2 * stride + j];
|
|
dst[5 * stride + j] = src[3 * stride + j];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void _cleanupQuadsToTris(void)
|
|
{
|
|
Z_Free(const_cast<void*>(glw_state->vertexPointer));
|
|
glw_state->vertexPointer = glw_state->vertexPointerBack;
|
|
|
|
if (glw_state->normalArrayState)
|
|
{
|
|
Z_Free(const_cast<void*>(glw_state->normalPointer));
|
|
glw_state->normalPointer = glw_state->normalPointerBack;
|
|
}
|
|
|
|
if (glw_state->colorArrayState)
|
|
{
|
|
Z_Free(const_cast<void*>(glw_state->colorPointer));
|
|
glw_state->colorPointer = glw_state->colorPointerBack;
|
|
}
|
|
|
|
for (int t = 0; t < GLW_MAX_TEXTURE_STAGES; ++t)
|
|
{
|
|
if (glw_state->texCoordArrayState[t])
|
|
{
|
|
Z_Free(const_cast<void*>(glw_state->texCoordPointer[t]));
|
|
glw_state->texCoordPointer[t] = glw_state->texCoordPointerBack[t];
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// NOTE: This is a core draw routine. It should be fast.
|
|
static void dllDrawArrays(GLenum mode, GLint first, GLsizei count)
|
|
{
|
|
#ifdef _WINDOWS
|
|
if (mode == GL_QUADS)
|
|
{
|
|
_convertQuadsToTris(first, count);
|
|
count = count * 3 / 2;
|
|
first = 0;
|
|
}
|
|
#endif
|
|
|
|
// start the draw mode
|
|
qglBeginEXT(mode, count, glw_state->colorArrayState ? count : 0,
|
|
glw_state->normalArrayState ? count : 0,
|
|
glw_state->texCoordArrayState[0] ? count : 0,
|
|
glw_state->texCoordArrayState[1] ? count : 0);
|
|
|
|
// get the draw function we need
|
|
drawarrayfunc_t func = _drawArrayFuncTable[_getDrawFunc()];
|
|
|
|
#ifndef _XBOX
|
|
DWORD* base = glw_state->drawArray;
|
|
#endif
|
|
|
|
int inc = glw_state->maxVertices;
|
|
// loop taking care not to draw too much at a time
|
|
for (int start = first; ; start += inc)//glw_state->maxVertices)
|
|
{
|
|
// draw glw_state->maxVertices amount of geometry
|
|
func(start, start + glw_state->maxVertices);
|
|
|
|
// are we done yet?
|
|
glw_state->totalVertices -= glw_state->maxVertices;
|
|
if (glw_state->totalVertices <= 0)
|
|
{
|
|
glw_state->numVertices = glw_state->maxVertices;
|
|
break;
|
|
}
|
|
|
|
// ready for another cycle
|
|
glw_state->drawArray += glw_state->maxVertices *
|
|
glw_state->drawStride;
|
|
glw_state->maxVertices = _getMaxVerts();
|
|
|
|
glw_state->drawArray = _restartDrawPacket(
|
|
glw_state->drawArray, glw_state->maxVertices);
|
|
}
|
|
|
|
#ifndef _XBOX
|
|
glw_state->drawArray = base;
|
|
#endif
|
|
|
|
#ifdef _WINDOWS
|
|
if (mode == GL_QUADS)
|
|
{
|
|
_cleanupQuadsToTris();
|
|
}
|
|
#endif
|
|
|
|
// finish up the draw
|
|
qglEnd();
|
|
}
|
|
|
|
static void dllDrawBuffer(GLenum mode)
|
|
{
|
|
//FIXME
|
|
}
|
|
|
|
|
|
static void PushIndices(GLsizei count, const GLushort *indices)
|
|
{
|
|
// open the index packet
|
|
// can only send 2047 indices thru at a time
|
|
// BUT, Microsoft recommends 511 pairs at a time (?)
|
|
int num_packets, numpairs, cnt;
|
|
bool singleindex = false;
|
|
|
|
numpairs = count / 2;
|
|
|
|
if(numpairs <= 511)
|
|
{
|
|
num_packets = 1;
|
|
|
|
if(glw_state->maxIndices % 2)
|
|
{
|
|
glw_state->maxIndices -= 1;
|
|
singleindex = true;
|
|
}
|
|
} else
|
|
{
|
|
num_packets = (count / glw_state->maxIndices) + (!!(count % glw_state->maxIndices));
|
|
}
|
|
|
|
glw_state->drawArray = _restartIndexPacket(glw_state->drawArray, glw_state->maxIndices);
|
|
|
|
int inc = glw_state->maxIndices;
|
|
for (int start = 0; ; start += inc)
|
|
{
|
|
for(int i = start; i < start + glw_state->maxIndices; i += 2)
|
|
{
|
|
*glw_state->drawArray++ = (DWORD)(((WORD)indices[i + 1] << 16) + (WORD)indices[i]);
|
|
}
|
|
// are we done yet?
|
|
glw_state->totalIndices -= glw_state->maxIndices;
|
|
if (glw_state->totalIndices <= 1)
|
|
{
|
|
glw_state->numIndices = glw_state->maxIndices;
|
|
break;
|
|
}
|
|
|
|
// ready for another cycle
|
|
//glw_state->drawArray += glw_state->maxVertices * glw_state->drawStride;
|
|
glw_state->maxIndices = _getMaxIndices();
|
|
|
|
if(glw_state->maxIndices % 2)
|
|
{
|
|
glw_state->maxIndices -= 1;
|
|
singleindex = true;
|
|
}
|
|
|
|
glw_state->drawArray = _restartIndexPacket(glw_state->drawArray, glw_state->maxIndices);
|
|
}
|
|
|
|
#define CMD_DRAW_INDEX_LAST 0x1808
|
|
if(singleindex)
|
|
{
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(CMD_DRAW_INDEX_LAST, 1);
|
|
*glw_state->drawArray++ = indices[count - 1];
|
|
}
|
|
}
|
|
|
|
// NOTE: This is a core draw routine. It should be fast.
|
|
static void dllDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
|
|
{
|
|
int normals, tex0, tex1, num_streams = 2;
|
|
|
|
assert(type == GL_UNSIGNED_SHORT);
|
|
|
|
normals = glw_state->normalArrayState ? tess.numVertexes : 0;
|
|
tex0 = glw_state->texCoordArrayState[0] ? tess.numVertexes : 0;
|
|
tex1 = glw_state->texCoordArrayState[1] ? tess.numVertexes : 0;
|
|
|
|
num_streams += ((normals > 0) + (tex0 > 0) + (tex1 > 0));
|
|
|
|
// start the draw block
|
|
glw_state->inDrawBlock = true;
|
|
glw_state->primitiveMode = _convertPrimMode(mode);
|
|
|
|
// update DX with any pending state changes
|
|
_updateDrawStride(normals, tex0, tex1);
|
|
_updateShader(normals, tex0, tex1);
|
|
_updateTextures();
|
|
_updateMatrices();
|
|
|
|
glw_state->drawStride += normals ? 2 : 1;
|
|
|
|
glw_state->numIndices = 0;
|
|
glw_state->totalIndices = count;
|
|
glw_state->maxIndices = _getMaxIndices();
|
|
|
|
glw_state->device->SetStreamSource(0, NULL, glw_state->drawStride * 4);
|
|
|
|
int vert_size = glw_state->drawStride * tess.numVertexes;
|
|
int index_size = count / 2;
|
|
|
|
glw_state->device->BeginPush(vert_size + index_size + 60, &glw_state->drawArray);
|
|
|
|
glw_state->drawArray = (DWORD*)*((DWORD*)glw_state->device);
|
|
|
|
DWORD *jumpaddress = 0, *stream = 0;
|
|
|
|
// Determine where the end of the vertex data is gonna be,
|
|
// that's where we're going to jump to
|
|
jumpaddress = (DWORD*)*((DWORD*)glw_state->device) + (vert_size + 1);
|
|
|
|
// Write the jump address
|
|
*glw_state->drawArray++ = ((DWORD)jumpaddress & 0x7fffffff) | 1;
|
|
|
|
// Set up our own fake vertex buffer
|
|
stream = glw_state->drawArray;
|
|
|
|
memcpy(glw_state->drawArray, tess.xyz, sizeof(vec4_t) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes * 4;
|
|
|
|
if(normals)
|
|
{
|
|
memcpy(glw_state->drawArray, tess.normal, sizeof(vec4_t) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes * 4;
|
|
}
|
|
|
|
if(glw_state->colorArrayState)
|
|
{
|
|
memcpy(glw_state->drawArray, tess.svars.colors, sizeof(D3DCOLOR) * tess.numVertexes);
|
|
}
|
|
else
|
|
{
|
|
for( int v = 0; v < tess.numVertexes; ++v )
|
|
glw_state->drawArray[v] = glw_state->currentColor;
|
|
}
|
|
glw_state->drawArray += tess.numVertexes;
|
|
|
|
if(tex0)
|
|
{
|
|
memcpy(glw_state->drawArray, tess.svars.texcoords[0], sizeof(vec2_t) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes * 2;
|
|
}
|
|
|
|
if(tex1)
|
|
{
|
|
memcpy(glw_state->drawArray, tess.svars.texcoords[1], sizeof(vec2_t) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes * 2;
|
|
}
|
|
|
|
// Write the vertex shader
|
|
#define CMD_STREAM_STRIDEANDTYPE0 0x1760
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(CMD_STREAM_STRIDEANDTYPE0, 16);
|
|
*glw_state->drawArray++ = (16 << 8)|D3DVSDT_FLOAT3;
|
|
|
|
if(1)
|
|
{
|
|
*glw_state->drawArray++ = ((glw_state->drawStride * 4) << 8) | D3DVSDT_NONE;
|
|
}
|
|
|
|
if(normals)
|
|
{
|
|
*glw_state->drawArray++ = (16 << 8) | D3DVSDT_FLOAT3;
|
|
}
|
|
else
|
|
{
|
|
*glw_state->drawArray++ = ((glw_state->drawStride * 4) << 8) | D3DVSDT_NONE;
|
|
}
|
|
|
|
*glw_state->drawArray++ = (4 << 8) | D3DVSDT_D3DCOLOR;
|
|
|
|
for(int i = 0; i < 5; i++)
|
|
{
|
|
*glw_state->drawArray++ = ((glw_state->drawStride * 4) << 8) | D3DVSDT_NONE;
|
|
}
|
|
|
|
if(tex0)
|
|
{
|
|
*glw_state->drawArray++ = (8 << 8) | D3DVSDT_FLOAT2;
|
|
}
|
|
else
|
|
{
|
|
*glw_state->drawArray++ = ((glw_state->drawStride * 4) << 8) | D3DVSDT_NONE;
|
|
}
|
|
|
|
if(tex1)
|
|
{
|
|
*glw_state->drawArray++ = (8 << 8) | D3DVSDT_FLOAT2;
|
|
}
|
|
else
|
|
{
|
|
*glw_state->drawArray++ = ((glw_state->drawStride * 4) << 8) | D3DVSDT_NONE;
|
|
}
|
|
|
|
for(i = 0; i < 5; i++)
|
|
{
|
|
*glw_state->drawArray++ = ((glw_state->drawStride * 4) << 8) | D3DVSDT_NONE;
|
|
}
|
|
|
|
// Write the indicator to our vertex stream
|
|
#define CMD_VERTEXSTREAM_XYZ 0x1720
|
|
#define CMD_VERTEXSTREAM_NORMAL 0x1728
|
|
#define CMD_VERTEXSTREAM_COLOR 0x172c
|
|
#define CMD_VERTEXSTREAM_TEX0 0x1744
|
|
#define CMD_VERTEXSTREAM_TEX1 0x1748
|
|
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(CMD_VERTEXSTREAM_XYZ, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes * 4;//3;
|
|
|
|
if(normals)
|
|
{
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(CMD_VERTEXSTREAM_NORMAL, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes * 4;//3;
|
|
}
|
|
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(CMD_VERTEXSTREAM_COLOR, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes;//1;
|
|
|
|
if(tex0)
|
|
{
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(CMD_VERTEXSTREAM_TEX0, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes * 2;//2;
|
|
}
|
|
|
|
if(tex1)
|
|
{
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(CMD_VERTEXSTREAM_TEX1, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
}
|
|
|
|
// Send thru the index data
|
|
PushIndices(count, (GLushort*)indices);
|
|
|
|
// finish up the draw
|
|
glw_state->inDrawBlock = false;
|
|
|
|
DWORD* push = _terminateIndexPacket(glw_state->drawArray);
|
|
|
|
glw_state->device->EndPush(push);
|
|
}
|
|
|
|
static void dllDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEdgeFlag(GLboolean flag)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEdgeFlagPointer(GLsizei stride, const GLvoid *pointer)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEdgeFlagv(const GLboolean *flag)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEnable(GLenum cap)
|
|
{
|
|
setCap(cap, true);
|
|
}
|
|
|
|
static void dllEnableClientState(GLenum array)
|
|
{
|
|
assert(!glw_state->inDrawBlock);
|
|
setArrayState(array, true);
|
|
}
|
|
|
|
static void dllEnd(void)
|
|
{
|
|
assert(glw_state->inDrawBlock);
|
|
glw_state->inDrawBlock = false;
|
|
#ifdef _XBOX
|
|
// on Xbox, just close the draw packet
|
|
DWORD* push = _terminateDrawPacket(
|
|
&glw_state->drawArray[glw_state->numVertices *
|
|
glw_state->drawStride]);
|
|
|
|
glw_state->device->EndPush(push);
|
|
#else
|
|
// on the PC, use DrawPrimitiveUp (a little slow)
|
|
int num = 0;
|
|
switch (glw_state->primitiveMode)
|
|
{
|
|
case D3DPT_POINTLIST: num = glw_state->numVertices; break;
|
|
case D3DPT_LINELIST: num = glw_state->numVertices / 2; break;
|
|
case D3DPT_LINESTRIP: num = glw_state->numVertices - 1; break;
|
|
case D3DPT_TRIANGLELIST: num = glw_state->numVertices / 3; break;
|
|
case D3DPT_TRIANGLESTRIP: num = glw_state->numVertices - 2; break;
|
|
case D3DPT_TRIANGLEFAN: num = glw_state->numVertices - 2; break;
|
|
}
|
|
|
|
glw_state->device->DrawPrimitiveUP(
|
|
glw_state->primitiveMode, num,
|
|
glw_state->drawArray, glw_state->drawStride * sizeof(DWORD));
|
|
#endif
|
|
}
|
|
|
|
// EXTENSION: End drawing for a frame
|
|
static void dllEndFrame(void)
|
|
{
|
|
assert(!glw_state->inDrawBlock);
|
|
|
|
// the blend state can get reset by Present()...
|
|
GLboolean blend = qglIsEnabled(GL_BLEND);
|
|
|
|
glw_state->device->EndScene();
|
|
|
|
qglViewport(0, 0, glConfig.vidWidth, glConfig.vidHeight);
|
|
glw_state->device->Present(NULL, NULL, NULL, NULL);
|
|
|
|
// restore the pre-Present state
|
|
if (blend) qglEnable(GL_BLEND);
|
|
else qglDisable(GL_BLEND);
|
|
}
|
|
|
|
// EXTENSION: End shadow draw mode
|
|
static void dllEndShadow(void)
|
|
{
|
|
//Intentionally left blank
|
|
}
|
|
|
|
static void dllEndList(void)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEvalCoord1d(GLdouble u)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEvalCoord1dv(const GLdouble *u)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEvalCoord1f(GLfloat u)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEvalCoord1fv(const GLfloat *u)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEvalCoord2d(GLdouble u, GLdouble v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEvalCoord2dv(const GLdouble *u)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEvalCoord2f(GLfloat u, GLfloat v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEvalCoord2fv(const GLfloat *u)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEvalMesh1(GLenum mode, GLint i1, GLint i2)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEvalPoint1(GLint i)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllEvalPoint2(GLint i, GLint j)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllFinish(void)
|
|
{
|
|
#ifdef _XBOX
|
|
glw_state->device->BlockUntilIdle();
|
|
#endif
|
|
}
|
|
|
|
static void dllFlush(void)
|
|
{
|
|
#ifdef _XBOX
|
|
glw_state->device->BlockUntilIdle();
|
|
#endif
|
|
}
|
|
|
|
// EXTENSION: Draw the shadow
|
|
static void dllFlushShadow(void)
|
|
{
|
|
//Intentionally left blank
|
|
}
|
|
|
|
static D3DFOGMODE _convertFogMode(GLint param)
|
|
{
|
|
switch(param)
|
|
{
|
|
case GL_LINEAR: return D3DFOG_LINEAR; break;
|
|
case GL_EXP: return D3DFOG_EXP; break;
|
|
case GL_EXP2: return D3DFOG_EXP2; break;
|
|
}
|
|
|
|
return D3DFOG_NONE;
|
|
}
|
|
|
|
static void dllFogf(GLenum pname, GLfloat param)
|
|
{
|
|
assert(pname == GL_FOG_DENSITY || pname == GL_FOG_START || pname == GL_FOG_END);
|
|
|
|
switch(pname)
|
|
{
|
|
case GL_FOG_DENSITY: glw_state->device->SetRenderState( D3DRS_FOGDENSITY, *(DWORD*)¶m ); break;
|
|
case GL_FOG_START: glw_state->device->SetRenderState( D3DRS_FOGSTART, *(DWORD*)¶m ); break;
|
|
case GL_FOG_END: glw_state->device->SetRenderState( D3DRS_FOGEND, *(DWORD*)¶m ); break;
|
|
}
|
|
}
|
|
|
|
static void dllFogfv(GLenum pname, const GLfloat *params)
|
|
{
|
|
assert(pname == GL_FOG_COLOR);
|
|
|
|
D3DCOLOR color = D3DCOLOR_ARGB(0x00,
|
|
(int)(params[0] * 255.0f),
|
|
(int)(params[1] * 255.0f),
|
|
(int)(params[2] * 255.0f));
|
|
|
|
glw_state->device->SetRenderState( D3DRS_FOGCOLOR, color );
|
|
}
|
|
|
|
static void dllFogi(GLenum pname, GLint param)
|
|
{
|
|
assert(pname == GL_FOG_MODE);
|
|
|
|
glw_state->device->SetRenderState( D3DRS_FOGTABLEMODE, _convertFogMode(param) );
|
|
}
|
|
|
|
static void dllFogiv(GLenum pname, const GLint *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllFrontFace(GLenum mode)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
|
|
{
|
|
D3DXMATRIX m;
|
|
D3DXMatrixPerspectiveOffCenterRH(&m, left, right, bottom, top, zNear, zFar);
|
|
glw_state->matrixStack[glw_state->matrixMode]->MultMatrix(&m);
|
|
glw_state->matricesDirty[glw_state->matrixMode] = true;
|
|
}
|
|
|
|
GLuint dllGenLists(GLsizei range)
|
|
{
|
|
assert(0);
|
|
return 0;
|
|
}
|
|
|
|
static void dllGenTextures(GLsizei n, GLuint *textures)
|
|
{
|
|
for (int i = 0; i < n; ++i)
|
|
{
|
|
textures[i] = glw_state->textureBindNum++;
|
|
}
|
|
}
|
|
|
|
// Implemented only the states we use.
|
|
template <typename T>
|
|
static void _getState(GLenum pname, T *params)
|
|
{
|
|
switch (pname)
|
|
{
|
|
case GL_CULL_FACE: params[0] = (T)glw_state->cullEnable; break;
|
|
case GL_MAX_TEXTURE_SIZE: params[0] = (T)512; break;
|
|
case GL_MAX_ACTIVE_TEXTURES_ARB: params[0] = GLW_MAX_TEXTURE_STAGES; break;
|
|
default:
|
|
assert(0);
|
|
params[0] = (T)0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void dllGetBooleanv(GLenum pname, GLboolean *params)
|
|
{
|
|
_getState(pname, params);
|
|
}
|
|
|
|
static void dllGetClipPlane(GLenum plane, GLdouble *equation)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetDoublev(GLenum pname, GLdouble *params)
|
|
{
|
|
_getState(pname, params);
|
|
}
|
|
|
|
GLenum dllGetError(void)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static void dllGetFloatv(GLenum pname, GLfloat *params)
|
|
{
|
|
_getState(pname, params);
|
|
}
|
|
|
|
static void dllGetIntegerv(GLenum pname, GLint *params)
|
|
{
|
|
_getState(pname, params);
|
|
}
|
|
|
|
static void dllGetLightfv(GLenum light, GLenum pname, GLfloat *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetLightiv(GLenum light, GLenum pname, GLint *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetMapdv(GLenum target, GLenum query, GLdouble *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetMapfv(GLenum target, GLenum query, GLfloat *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetMapiv(GLenum target, GLenum query, GLint *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetMaterialiv(GLenum face, GLenum pname, GLint *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetPixelMapfv(GLenum map, GLfloat *values)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetPixelMapuiv(GLenum map, GLuint *values)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetPixelMapusv(GLenum map, GLushort *values)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetPointerv(GLenum pname, GLvoid* *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetPolygonStipple(GLubyte *mask)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
const GLubyte * dllGetString(GLenum name)
|
|
{
|
|
switch (name)
|
|
{
|
|
case GL_VENDOR: return (const unsigned char*)"Vicarious Visions";
|
|
case GL_RENDERER: return (const unsigned char*)"Optimized DX8/OpenGL Layer";
|
|
case GL_VERSION: return (const unsigned char*)"0.1";
|
|
case GL_EXTENSIONS:
|
|
return (const unsigned char*)
|
|
"EXT_texture_env_add GL_ARB_multitexture EXT_texture_filter_anisotropic";
|
|
default: return (const unsigned char*)"";
|
|
}
|
|
}
|
|
|
|
static void dllGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetTexEnviv(GLenum target, GLenum pname, GLint *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetTexGendv(GLenum coord, GLenum pname, GLdouble *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetTexGeniv(GLenum coord, GLenum pname, GLint *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllGetTexParameteriv(GLenum target, GLenum pname, GLint *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllHint(GLenum target, GLenum mode)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
// Convert an triangle index array (indices) to a
|
|
// triangle strip index array (dest) with primitive
|
|
// length array.
|
|
static void buildStrips(GLuint* len, GLsizei* num_lens, GLushort* dest, GLsizei* num_indices, const GLushort* src)
|
|
{
|
|
GLushort last[3];
|
|
|
|
// prime the strip
|
|
GLsizei cur_index = 0;
|
|
dest[cur_index++] = src[0];
|
|
dest[cur_index++] = src[1];
|
|
dest[cur_index++] = src[2];
|
|
GLuint cur_length = 3;
|
|
GLsizei num_strips = 0;
|
|
|
|
GLuint max_length = GLW_MAX_DRAW_PACKET_SIZE / glw_state->drawStride;
|
|
|
|
last[0] = src[0];
|
|
last[1] = src[1];
|
|
last[2] = src[2];
|
|
|
|
qboolean even = qfalse;
|
|
|
|
for ( GLsizei i = 3; i < *num_indices; i += 3 )
|
|
{
|
|
// odd numbered triangle in potential strip
|
|
if ( !even )
|
|
{
|
|
// check previous triangle to see if we're continuing a strip
|
|
if ( ( src[i+0] == last[2] ) && ( src[i+1] == last[1] ) &&
|
|
cur_length < max_length )
|
|
{
|
|
++cur_length;
|
|
dest[cur_index++] = src[i+2];
|
|
even = qtrue;
|
|
}
|
|
// otherwise we're done with this strip so finish it and start
|
|
// a new one
|
|
else
|
|
{
|
|
len[num_strips++] = cur_length;
|
|
cur_length = 3;
|
|
|
|
dest[cur_index++] = src[i+0];
|
|
dest[cur_index++] = src[i+1];
|
|
dest[cur_index++] = src[i+2];
|
|
|
|
even = qfalse;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// check previous triangle to see if we're continuing a strip
|
|
if ( ( last[2] == src[i+1] ) && ( last[0] == src[i+0] ) &&
|
|
cur_length < max_length )
|
|
{
|
|
++cur_length;
|
|
dest[cur_index++] = src[i+2];
|
|
even = qfalse;
|
|
}
|
|
// otherwise we're done with this strip so finish it and start
|
|
// a new one
|
|
else
|
|
{
|
|
len[num_strips++] = cur_length;
|
|
cur_length = 3;
|
|
|
|
dest[cur_index++] = src[i+0];
|
|
dest[cur_index++] = src[i+1];
|
|
dest[cur_index++] = src[i+2];
|
|
|
|
even = qfalse;
|
|
}
|
|
}
|
|
|
|
// cache the last three vertices
|
|
last[0] = src[i+0];
|
|
last[1] = src[i+1];
|
|
last[2] = src[i+2];
|
|
}
|
|
|
|
len[num_strips++] = cur_length;
|
|
*num_lens = num_strips;
|
|
*num_indices = cur_index;
|
|
|
|
assert(num_strips <= GLW_MAX_STRIPS);
|
|
}
|
|
|
|
#ifdef _XBOX
|
|
void renderObject_Light()
|
|
{
|
|
int i;
|
|
|
|
// start the draw mode
|
|
assert(!glw_state->inDrawBlock);
|
|
|
|
glw_state->inDrawBlock = true;
|
|
glw_state->primitiveMode = D3DPT_TRIANGLELIST;
|
|
|
|
glw_state->drawStride = 14;
|
|
|
|
glw_state->numIndices = 0;
|
|
glw_state->totalIndices = tess.numIndexes;
|
|
glw_state->maxIndices = _getMaxIndices();
|
|
|
|
glw_state->device->SetStreamSource(0, NULL, glw_state->drawStride * 4);
|
|
|
|
int vert_size = glw_state->drawStride * tess.numVertexes;
|
|
int index_size = tess.numIndexes / 2;
|
|
|
|
glw_state->device->BeginPush(vert_size + index_size + 60, &glw_state->drawArray);
|
|
|
|
glw_state->drawArray = (DWORD*)*((DWORD*)glw_state->device);
|
|
|
|
DWORD *jumpaddress = 0, *stream = 0;
|
|
|
|
// Determine where the end of the vertex data is gonna be,
|
|
// that's where we're going to jump to
|
|
jumpaddress = (DWORD*)*((DWORD*)glw_state->device) + (vert_size + 1);
|
|
|
|
// Write the jump address
|
|
*glw_state->drawArray++ = ((DWORD)jumpaddress & 0x7fffffff) | 1;
|
|
|
|
// Set up our own fake vertex buffer
|
|
stream = glw_state->drawArray;
|
|
|
|
memcpy(glw_state->drawArray, tess.xyz, sizeof(vec4_t) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes * 4;
|
|
|
|
memcpy(glw_state->drawArray, tess.normal, sizeof(vec4_t) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes * 4;
|
|
|
|
memcpy(glw_state->drawArray, tess.svars.texcoords[0], sizeof(vec2_t) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes * 2;
|
|
|
|
memcpy(glw_state->drawArray, tess.tangent, sizeof(vec4_t) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes * 4;
|
|
|
|
// Write the vertex shader
|
|
#define CMD_STREAM_STRIDEANDTYPE0 0x1760
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(CMD_STREAM_STRIDEANDTYPE0, 16);
|
|
|
|
// Position
|
|
*glw_state->drawArray++ = (16 << 8)|D3DVSDT_FLOAT3;
|
|
|
|
// Normal
|
|
*glw_state->drawArray++ = (16 << 8) | D3DVSDT_FLOAT3;
|
|
|
|
// Tex Coord
|
|
*glw_state->drawArray++ = (8 << 8) | D3DVSDT_FLOAT2;
|
|
|
|
// Tangent
|
|
*glw_state->drawArray++ = (16 << 8) | D3DVSDT_FLOAT3;
|
|
|
|
for(i = 0; i < 12; i++)
|
|
{
|
|
*glw_state->drawArray++ = ((glw_state->drawStride * 4) << 8) | D3DVSDT_NONE;
|
|
}
|
|
|
|
// Write the indicator to our vertex stream
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(0x1720, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes * 4;
|
|
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(0x1724, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes * 4;
|
|
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(0x1728, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes * 2;
|
|
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(0x172c, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes * 4;
|
|
|
|
// Send thru the index data
|
|
PushIndices(tess.numIndexes, (GLushort*)tess.indexes);
|
|
|
|
// finish up the draw
|
|
glw_state->inDrawBlock = false;
|
|
|
|
DWORD* push = _terminateIndexPacket(glw_state->drawArray);
|
|
|
|
glw_state->device->EndPush(push);
|
|
}
|
|
|
|
void renderObject_Bump()
|
|
{
|
|
// start the draw mode
|
|
assert(!glw_state->inDrawBlock);
|
|
|
|
glw_state->inDrawBlock = true;
|
|
glw_state->primitiveMode = D3DPT_TRIANGLELIST;
|
|
|
|
glw_state->drawStride = 16;
|
|
|
|
glw_state->numIndices = 0;
|
|
glw_state->totalIndices = tess.numIndexes;
|
|
glw_state->maxIndices = _getMaxIndices();
|
|
|
|
glw_state->device->SetStreamSource(0, NULL, glw_state->drawStride * 4);
|
|
|
|
int vert_size = glw_state->drawStride * tess.numVertexes;
|
|
int index_size = tess.numIndexes / 2;
|
|
|
|
glw_state->device->BeginPush(vert_size + index_size + 60, &glw_state->drawArray);
|
|
|
|
glw_state->drawArray = (DWORD*)*((DWORD*)glw_state->device);
|
|
|
|
DWORD *jumpaddress = 0, *stream = 0;
|
|
|
|
// Determine where the end of the vertex data is gonna be,
|
|
// that's where we're going to jump to
|
|
jumpaddress = (DWORD*)*((DWORD*)glw_state->device) + (vert_size + 1);
|
|
|
|
// Write the jump address
|
|
*glw_state->drawArray++ = ((DWORD)jumpaddress & 0x7fffffff) | 1;
|
|
|
|
// Set up our own fake vertex buffer
|
|
stream = glw_state->drawArray;
|
|
|
|
memcpy(glw_state->drawArray, tess.xyz, sizeof(vec4_t) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes * 4;
|
|
|
|
memcpy(glw_state->drawArray, tess.normal, sizeof(vec4_t) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes * 4;
|
|
|
|
memcpy(glw_state->drawArray, tess.svars.texcoords[0], sizeof(vec2_t) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes * 2;
|
|
|
|
memcpy(glw_state->drawArray, tess.svars.texcoords[1], sizeof(vec2_t) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes * 2;
|
|
|
|
memcpy(glw_state->drawArray, tess.tangent, sizeof(vec4_t) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes * 4;
|
|
|
|
// Write the vertex shader
|
|
#define CMD_STREAM_STRIDEANDTYPE0 0x1760
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(CMD_STREAM_STRIDEANDTYPE0, 16);
|
|
|
|
// Position
|
|
*glw_state->drawArray++ = (16 << 8)|D3DVSDT_FLOAT3;
|
|
|
|
// Normal
|
|
*glw_state->drawArray++ = (16 << 8) | D3DVSDT_FLOAT3;
|
|
|
|
// Tex Coord 0
|
|
*glw_state->drawArray++ = (8 << 8) | D3DVSDT_FLOAT2;
|
|
|
|
// Tex Coord 1
|
|
*glw_state->drawArray++ = (8 << 8) | D3DVSDT_FLOAT2;
|
|
|
|
// Tangent
|
|
*glw_state->drawArray++ = (16 << 8) | D3DVSDT_FLOAT3;
|
|
|
|
for(int i = 0; i < 11; i++)
|
|
{
|
|
*glw_state->drawArray++ = ((glw_state->drawStride * 4) << 8) | D3DVSDT_NONE;
|
|
}
|
|
|
|
// Write the indicator to our vertex stream
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(0x1720, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes * 4;
|
|
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(0x1724, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes * 4;
|
|
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(0x1728, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes * 2;
|
|
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(0x172c, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes * 2;
|
|
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(0x1730, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes * 4;
|
|
|
|
// Send thru the index data
|
|
PushIndices(tess.numIndexes, (GLushort*)tess.indexes);
|
|
|
|
// finish up the draw
|
|
glw_state->inDrawBlock = false;
|
|
|
|
DWORD* push = _terminateIndexPacket(glw_state->drawArray);
|
|
|
|
glw_state->device->EndPush(push);
|
|
}
|
|
|
|
void renderObject_Env()
|
|
{
|
|
// start the draw mode
|
|
assert(!glw_state->inDrawBlock);
|
|
|
|
glw_state->inDrawBlock = true;
|
|
glw_state->primitiveMode = D3DPT_TRIANGLELIST;
|
|
|
|
glw_state->drawStride = 9;
|
|
_updateTextures();
|
|
|
|
glw_state->numIndices = 0;
|
|
glw_state->totalIndices = tess.numIndexes;
|
|
glw_state->maxIndices = _getMaxIndices();
|
|
|
|
glw_state->device->SetStreamSource(0, NULL, glw_state->drawStride * 4);
|
|
|
|
int vert_size = glw_state->drawStride * tess.numVertexes;
|
|
int index_size = tess.numIndexes / 2;
|
|
|
|
glw_state->device->BeginPush(vert_size + index_size + 60, &glw_state->drawArray);
|
|
|
|
glw_state->drawArray = (DWORD*)*((DWORD*)glw_state->device);
|
|
|
|
DWORD *jumpaddress = 0, *stream = 0;
|
|
|
|
// Determine where the end of the vertex data is gonna be,
|
|
// that's where we're going to jump to
|
|
jumpaddress = (DWORD*)*((DWORD*)glw_state->device) + (vert_size + 1);
|
|
|
|
// Write the jump address
|
|
*glw_state->drawArray++ = ((DWORD)jumpaddress & 0x7fffffff) | 1;
|
|
|
|
// Set up our own fake vertex buffer
|
|
stream = glw_state->drawArray;
|
|
|
|
memcpy(glw_state->drawArray, tess.xyz, sizeof(vec4_t) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes * 4;
|
|
|
|
memcpy(glw_state->drawArray, tess.normal, sizeof(vec4_t) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes * 4;
|
|
|
|
memcpy(glw_state->drawArray, tess.svars.colors, sizeof(D3DCOLOR) * tess.numVertexes);
|
|
glw_state->drawArray += tess.numVertexes;
|
|
|
|
// Write the vertex shader
|
|
#define CMD_STREAM_STRIDEANDTYPE0 0x1760
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(CMD_STREAM_STRIDEANDTYPE0, 16);
|
|
|
|
// Position
|
|
*glw_state->drawArray++ = (16 << 8)|D3DVSDT_FLOAT3;
|
|
|
|
// Normal
|
|
*glw_state->drawArray++ = (16 << 8) | D3DVSDT_FLOAT3;
|
|
|
|
// Color
|
|
*glw_state->drawArray++ = (4 << 8) | D3DVSDT_D3DCOLOR;
|
|
|
|
for(int i = 0; i < 13; i++)
|
|
{
|
|
*glw_state->drawArray++ = ((glw_state->drawStride * 4) << 8) | D3DVSDT_NONE;
|
|
}
|
|
|
|
// Write the indicator to our vertex stream
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(0x1720, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes * 4;
|
|
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(0x1724, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes * 4;
|
|
|
|
*glw_state->drawArray++ = D3DPUSH_ENCODE(0x1728, 1);
|
|
*glw_state->drawArray++ = (DWORD)stream & 0x7fffffff;
|
|
stream += tess.numVertexes;
|
|
|
|
// Send thru the index data
|
|
PushIndices(tess.numIndexes, (GLushort*)tess.indexes);
|
|
|
|
// finish up the draw
|
|
glw_state->inDrawBlock = false;
|
|
|
|
DWORD* push = _terminateIndexPacket(glw_state->drawArray);
|
|
|
|
glw_state->device->EndPush(push);
|
|
}
|
|
#endif
|
|
|
|
// EXTENSION: Take an array of triangle indices and draw
|
|
// the appropriate triangle strips. Virtually ALL geometry
|
|
// is drawn with this function so it better be fast.
|
|
static void dllIndexedTriToStrip(GLsizei count, const GLushort *indices)
|
|
{
|
|
#ifndef _XBOX
|
|
#ifdef GLW_USE_TRI_STRIPS
|
|
|
|
// update the render state
|
|
_updateDrawStride(glw_state->normalArrayState,
|
|
glw_state->texCoordArrayState[0] ? count : 0,
|
|
glw_state->texCoordArrayState[1] ? count : 0);
|
|
_updateShader(glw_state->normalArrayState,
|
|
glw_state->texCoordArrayState[0],
|
|
glw_state->texCoordArrayState[1]);
|
|
_updateTextures();
|
|
_updateMatrices();
|
|
|
|
// convert triangles to strips -- guarantees that
|
|
// no strip exceeds the max draw packet size
|
|
if(tess.currentPass == 0)
|
|
{
|
|
buildStrips(glw_state->strip_lengths,
|
|
&glw_state->num_strip_lengths, glw_state->strip_dest, &count, indices);
|
|
}
|
|
|
|
// Yeah, its a hack, but I gotta do this so bumpmapping
|
|
// doesnt go all crazy on the 'force speed' effect and
|
|
// 'disintegration' effect
|
|
if(tess.shader &&
|
|
tess.shader->isBumpMap &&
|
|
(backEnd.currentEntity->e.renderfx &
|
|
// VVFIXME : This is probably wrong. It looks like RF_ALPHA_FADE is renamed
|
|
// RF_RGB_TINT in MP. Substitute?
|
|
#ifndef _JK2MP
|
|
(RF_ALPHA_FADE | RF_DISINTEGRATE1 | RF_DISINTEGRATE2)))
|
|
#else
|
|
(RF_DISINTEGRATE1 | RF_DISINTEGRATE2)))
|
|
#endif
|
|
{
|
|
if(tess.currentPass != 2)
|
|
return;
|
|
}
|
|
|
|
#ifdef _XBOX
|
|
glw_state->primitiveMode = D3DPT_TRIANGLESTRIP;
|
|
|
|
// get the necessary draw function
|
|
drawelemfunc_t func = _drawElementFuncTable[_getDrawFunc()];
|
|
int stride = glw_state->drawStride;
|
|
|
|
int index = 0;
|
|
for (int l = 0; l < glw_state->num_strip_lengths; ++l)
|
|
{
|
|
int cur_len = glw_state->strip_lengths[l];
|
|
|
|
// start a draw packet
|
|
DWORD* push;
|
|
glw_state->device->BeginPush(stride * cur_len + 5, &push);
|
|
push = _restartDrawPacket(push, cur_len);
|
|
|
|
// draw the geometry
|
|
glw_state->drawArray = push;
|
|
func(cur_len, &glw_state->strip_dest[index]);
|
|
index += cur_len;
|
|
|
|
// finish the draw packet
|
|
push = _terminateDrawPacket(&push[stride * cur_len]);
|
|
glw_state->device->EndPush(push);
|
|
}
|
|
#else _XBOX
|
|
// simplified render on the PC
|
|
int index = 0;
|
|
for (int l = 0; l < glw_state->num_strip_lengths; ++l)
|
|
{
|
|
dllDrawElements(GL_TRIANGLE_STRIP, glw_state->strip_lengths[l],
|
|
GL_UNSIGNED_SHORT, &glw_state->strip_dest[index]);
|
|
index += glw_state->strip_lengths[l];
|
|
}
|
|
#endif _XBOX
|
|
|
|
#else GLW_USE_TRI_STRIPS
|
|
// just render simple triangles
|
|
dllDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, indices);
|
|
#endif GLW_USE_TRI_STRIPS
|
|
#endif
|
|
}
|
|
|
|
static void dllIndexMask(GLuint mask)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllIndexd(GLdouble c)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllIndexdv(const GLdouble *c)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllIndexf(GLfloat c)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllIndexfv(const GLfloat *c)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllIndexi(GLint c)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllIndexiv(const GLint *c)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllIndexs(GLshort c)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllIndexsv(const GLshort *c)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllIndexub(GLubyte c)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllIndexubv(const GLubyte *c)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllInitNames(void)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
GLboolean dllIsEnabled(GLenum cap)
|
|
{
|
|
DWORD flag;
|
|
switch (cap)
|
|
{
|
|
case GL_ALPHA_TEST: glw_state->device->GetRenderState(D3DRS_ALPHATESTENABLE, &flag); break;
|
|
case GL_BLEND: glw_state->device->GetRenderState(D3DRS_ALPHABLENDENABLE, &flag); break;
|
|
case GL_CULL_FACE: return glw_state->cullEnable;
|
|
case GL_DEPTH_TEST: glw_state->device->GetRenderState(D3DRS_ZENABLE, &flag); break;
|
|
case GL_FOG: glw_state->device->GetRenderState(D3DRS_FOGENABLE, &flag); break;
|
|
case GL_LIGHTING: glw_state->device->GetRenderState(D3DRS_LIGHTING, &flag); break;
|
|
#ifdef _XBOX
|
|
case GL_POLYGON_OFFSET_FILL: glw_state->device->GetRenderState(D3DRS_SOLIDOFFSETENABLE, &flag); break;
|
|
#else
|
|
case GL_POLYGON_OFFSET_FILL: return FALSE;
|
|
#endif
|
|
case GL_SCISSOR_TEST: return glw_state->scissorEnable;
|
|
case GL_STENCIL_TEST: glw_state->device->GetRenderState(D3DRS_STENCILENABLE, &flag); break;
|
|
case GL_TEXTURE_2D: return glw_state->textureStageEnable[glw_state->serverTU];
|
|
default: return FALSE;
|
|
}
|
|
return flag;
|
|
}
|
|
|
|
GLboolean dllIsList(GLuint lnum)
|
|
{
|
|
assert(0);
|
|
return 1;
|
|
}
|
|
|
|
GLboolean dllIsTexture(GLuint texture)
|
|
{
|
|
assert(0);
|
|
return 1;
|
|
}
|
|
|
|
static void dllLightModelf(GLenum pname, GLfloat param)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllLightModelfv(GLenum pname, const GLfloat *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllLightModeli(GLenum pname, GLint param)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllLightModeliv(GLenum pname, const GLint *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllLightf(GLenum light, GLenum pname, GLfloat param)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllLightfv(GLenum light, GLenum pname, const GLfloat *params)
|
|
{
|
|
switch(pname)
|
|
{
|
|
case GL_AMBIENT:
|
|
{
|
|
glw_state->dirLight.Ambient.r = params[0] / 255.0f;
|
|
glw_state->dirLight.Ambient.g = params[1] / 255.0f;
|
|
glw_state->dirLight.Ambient.b = params[2] / 255.0f;
|
|
}
|
|
break;
|
|
|
|
case GL_DIFFUSE:
|
|
{
|
|
glw_state->dirLight.Diffuse.r = params[0] / 255.0f;
|
|
glw_state->dirLight.Diffuse.g = params[1] / 255.0f;
|
|
glw_state->dirLight.Diffuse.b = params[2] / 255.0f;
|
|
}
|
|
break;
|
|
|
|
case GL_SPECULAR:
|
|
{
|
|
glw_state->dirLight.Specular.r = params[0] / 255.0f;
|
|
glw_state->dirLight.Specular.g = params[1] / 255.0f;
|
|
glw_state->dirLight.Specular.b = params[2] / 255.0f;
|
|
}
|
|
break;
|
|
case GL_POSITION:
|
|
{
|
|
glw_state->dirLight.Position.x = params[0];
|
|
glw_state->dirLight.Position.y = params[1];
|
|
glw_state->dirLight.Position.z = params[2];
|
|
}
|
|
break;
|
|
|
|
case GL_SPOT_DIRECTION:
|
|
{
|
|
glw_state->dirLight.Direction.x = -params[0];
|
|
glw_state->dirLight.Direction.y = -params[1];
|
|
glw_state->dirLight.Direction.z = -params[2];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
assert(0);
|
|
break;
|
|
}
|
|
|
|
glw_state->device->SetLight(light, &glw_state->dirLight);
|
|
glw_state->device->LightEnable(light, TRUE);
|
|
}
|
|
|
|
static void dllLighti(GLenum light, GLenum pname, GLint param)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllLightiv(GLenum light, GLenum pname, const GLint *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllLineStipple(GLint factor, GLushort pattern)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllLineWidth(GLfloat width)
|
|
{
|
|
// assert(0);
|
|
}
|
|
|
|
static void dllListBase(GLuint base)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllLoadIdentity(void)
|
|
{
|
|
glw_state->matrixStack[glw_state->matrixMode]->LoadIdentity();
|
|
glw_state->matricesDirty[glw_state->matrixMode] = true;
|
|
}
|
|
|
|
static void dllLoadMatrixd(const GLdouble *m)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllLoadMatrixf(const GLfloat *m)
|
|
{
|
|
glw_state->matrixStack[glw_state->matrixMode]->LoadMatrix((D3DXMATRIX*)m);
|
|
glw_state->matricesDirty[glw_state->matrixMode] = true;
|
|
}
|
|
|
|
static void dllLoadName(GLuint name)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllLogicOp(GLenum opcode)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllMapGrid1d(GLint un, GLdouble u1, GLdouble u2)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllMapGrid1f(GLint un, GLfloat u1, GLfloat u2)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllMaterialf(GLenum face, GLenum pname, GLfloat param)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
|
|
{
|
|
switch(pname)
|
|
{
|
|
case GL_AMBIENT:
|
|
glw_state->mtrl.Ambient.r = params[0] / 255.0f;
|
|
glw_state->mtrl.Ambient.g = params[1] / 255.0f;
|
|
glw_state->mtrl.Ambient.b = params[2] / 255.0f;
|
|
glw_state->mtrl.Ambient.a = params[3] / 255.0f;
|
|
break;
|
|
|
|
case GL_DIFFUSE:
|
|
glw_state->mtrl.Diffuse.r = params[0] / 255.0f;
|
|
glw_state->mtrl.Diffuse.g = params[1] / 255.0f;
|
|
glw_state->mtrl.Diffuse.b = params[2] / 255.0f;
|
|
glw_state->mtrl.Diffuse.a = params[3] / 255.0f;
|
|
break;
|
|
|
|
case GL_SPECULAR:
|
|
glw_state->mtrl.Specular.r = params[0] / 255.0f;
|
|
glw_state->mtrl.Specular.g = params[1] / 255.0f;
|
|
glw_state->mtrl.Specular.b = params[2] / 255.0f;
|
|
glw_state->mtrl.Specular.a = params[3] / 255.0f;
|
|
break;
|
|
|
|
case GL_EMISSION:
|
|
glw_state->mtrl.Emissive.r = params[0] / 255.0f;
|
|
glw_state->mtrl.Emissive.g = params[1] / 255.0f;
|
|
glw_state->mtrl.Emissive.b = params[2] / 255.0f;
|
|
glw_state->mtrl.Emissive.a = params[3] / 255.0f;
|
|
break;
|
|
|
|
default:
|
|
assert(0);
|
|
break;
|
|
}
|
|
|
|
glw_state->device->SetMaterial(&glw_state->mtrl);
|
|
}
|
|
|
|
static void dllMateriali(GLenum face, GLenum pname, GLint param)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllMaterialiv(GLenum face, GLenum pname, const GLint *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllMatrixMode(GLenum mode)
|
|
{
|
|
switch (mode)
|
|
{
|
|
case GL_MODELVIEW: glw_state->matrixMode = glwstate_t::MatrixMode_Model; break;
|
|
case GL_PROJECTION: glw_state->matrixMode = glwstate_t::MatrixMode_Projection; break;
|
|
#ifdef _XBOX
|
|
case GL_TEXTURE0: glw_state->matrixMode = glwstate_t::MatrixMode_Texture0; break;
|
|
case GL_TEXTURE1: glw_state->matrixMode = glwstate_t::MatrixMode_Texture1; break;
|
|
#endif
|
|
default: assert(false); break;
|
|
}
|
|
}
|
|
|
|
static void dllMultMatrixd(const GLdouble *m)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllMultMatrixf(const GLfloat *m)
|
|
{
|
|
glw_state->matrixStack[glw_state->matrixMode]->MultMatrixLocal((D3DXMATRIX*)m);
|
|
glw_state->matricesDirty[glw_state->matrixMode] = true;
|
|
}
|
|
|
|
static void dllNewList(GLuint lnum, GLenum mode)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void setNormal(float x, float y, float z)
|
|
{
|
|
assert(glw_state->inDrawBlock);
|
|
|
|
_handleDrawOverflow();
|
|
|
|
DWORD* push = &glw_state->drawArray[glw_state->numVertices * glw_state->drawStride + 4];
|
|
push[0] = *((DWORD*)&x);
|
|
push[1] = *((DWORD*)&y);
|
|
push[2] = *((DWORD*)&z);
|
|
push[3] = glw_state->currentColor;
|
|
}
|
|
static void dllNormal3b(GLbyte nx, GLbyte ny, GLbyte nz)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllNormal3bv(const GLbyte *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllNormal3d(GLdouble nx, GLdouble ny, GLdouble nz)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllNormal3dv(const GLdouble *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
|
|
{
|
|
setNormal(nx, ny, nz);
|
|
}
|
|
|
|
static void dllNormal3fv(const GLfloat *v)
|
|
{
|
|
setNormal(v[0], v[1], v[2]);
|
|
}
|
|
|
|
static void dllNormal3i(GLint nx, GLint ny, GLint nz)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllNormal3iv(const GLint *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllNormal3s(GLshort nx, GLshort ny, GLshort nz)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllNormal3sv(const GLshort *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
|
|
{
|
|
assert(type == GL_FLOAT);
|
|
|
|
stride = (stride == 0) ? (sizeof(GLfloat) * 3) : stride;
|
|
|
|
glw_state->normalPointer = pointer;
|
|
glw_state->normalStride = stride;
|
|
}
|
|
|
|
static void dllOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
|
|
{
|
|
D3DXMATRIX m;
|
|
D3DXMatrixOrthoOffCenterRH(&m, left, right, top, bottom, zNear, zFar);
|
|
glw_state->matrixStack[glw_state->matrixMode]->MultMatrix(&m);
|
|
glw_state->matricesDirty[glw_state->matrixMode] = true;
|
|
}
|
|
|
|
static void dllPassThrough(GLfloat token)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPixelStoref(GLenum pname, GLfloat param)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPixelStorei(GLenum pname, GLint param)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPixelTransferf(GLenum pname, GLfloat param)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPixelTransferi(GLenum pname, GLint param)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPixelZoom(GLfloat xfactor, GLfloat yfactor)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPointSize(GLfloat size)
|
|
{
|
|
glw_state->device->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);
|
|
glw_state->device->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&size));
|
|
}
|
|
|
|
static void dllPolygonMode(GLenum face, GLenum mode)
|
|
{
|
|
D3DFILLMODE m;
|
|
switch (mode)
|
|
{
|
|
case GL_POINT: m = D3DFILL_POINT; break;
|
|
case GL_LINE: m = D3DFILL_WIREFRAME; break;
|
|
case GL_FILL: m = D3DFILL_SOLID; break;
|
|
default: assert(0); break;
|
|
}
|
|
|
|
switch (face)
|
|
{
|
|
case GL_FRONT:
|
|
glw_state->device->SetRenderState(D3DRS_FILLMODE, m);
|
|
break;
|
|
case GL_BACK:
|
|
#ifdef _XBOX
|
|
glw_state->device->SetRenderState(D3DRS_BACKFILLMODE, m);
|
|
#endif
|
|
break;
|
|
case GL_FRONT_AND_BACK:
|
|
glw_state->device->SetRenderState(D3DRS_FILLMODE, m);
|
|
#ifdef _XBOX
|
|
glw_state->device->SetRenderState(D3DRS_BACKFILLMODE, m);
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void dllPolygonOffset(GLfloat factor, GLfloat units)
|
|
{
|
|
#ifdef _XBOX
|
|
glw_state->device->SetRenderState(D3DRS_POLYGONOFFSETZOFFSET, *((DWORD*)&factor));
|
|
glw_state->device->SetRenderState(D3DRS_POLYGONOFFSETZSLOPESCALE, *((DWORD*)&units));
|
|
#endif
|
|
}
|
|
|
|
static void dllPolygonStipple(const GLubyte *mask)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPopAttrib(void)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPopClientAttrib(void)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPopMatrix(void)
|
|
{
|
|
glw_state->matrixStack[glw_state->matrixMode]->Pop();
|
|
glw_state->matricesDirty[glw_state->matrixMode] = true;
|
|
}
|
|
|
|
static void dllPopName(void)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPushAttrib(GLbitfield mask)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPushClientAttrib(GLbitfield mask)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllPushMatrix(void)
|
|
{
|
|
glw_state->matrixStack[glw_state->matrixMode]->Push();
|
|
glw_state->matricesDirty[glw_state->matrixMode] = true;
|
|
}
|
|
|
|
static void dllPushName(GLuint name)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos2d(GLdouble x, GLdouble y)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos2dv(const GLdouble *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos2f(GLfloat x, GLfloat y)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos2fv(const GLfloat *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos2i(GLint x, GLint y)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos2iv(const GLint *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos2s(GLshort x, GLshort y)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos2sv(const GLshort *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos3d(GLdouble x, GLdouble y, GLdouble z)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos3dv(const GLdouble *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos3f(GLfloat x, GLfloat y, GLfloat z)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos3fv(const GLfloat *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos3i(GLint x, GLint y, GLint z)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos3iv(const GLint *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos3s(GLshort x, GLshort y, GLshort z)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos3sv(const GLshort *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos4dv(const GLdouble *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos4fv(const GLfloat *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos4i(GLint x, GLint y, GLint z, GLint w)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos4iv(const GLint *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRasterPos4sv(const GLshort *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllReadBuffer(GLenum mode)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
//static void dllReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei twidth, GLsizei theight, GLvoid *pixels)
|
|
static void dllReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
|
|
{
|
|
return;
|
|
|
|
/*
|
|
// assert((format == GL_LIN_RGB8) && (type == GL_UNSIGNED_BYTE));
|
|
|
|
// create a temporary storage surface
|
|
IDirect3DSurface8 *target;
|
|
glw_state->device->CreateImageSurface(twidth, theight, D3DFMT_A8R8G8B8, &target);
|
|
|
|
// get a pointer to the back buffer
|
|
IDirect3DSurface8* screen;
|
|
glw_state->device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &screen);
|
|
|
|
// copy the back buffer into a surface of the appropriate size and format
|
|
RECT r;
|
|
r.left = x;
|
|
r.top = y;
|
|
r.right = x + width;
|
|
r.bottom = y + height;
|
|
D3DXLoadSurfaceFromSurface(target, NULL, NULL, screen, NULL, &r, D3DX_DEFAULT, 0);
|
|
screen->Release();
|
|
|
|
// lock the target surface
|
|
D3DLOCKED_RECT lock;
|
|
target->LockRect(&lock, NULL, D3DLOCK_READONLY);
|
|
|
|
// copy the pixel data
|
|
for (int y = 0; y < theight; ++y)
|
|
{
|
|
memcpy((char*)pixels + twidth * y * 4,
|
|
(char*)lock.pBits + lock.Pitch * y,
|
|
twidth * 4);
|
|
}
|
|
|
|
// all done
|
|
target->UnlockRect();
|
|
target->Release();
|
|
*/
|
|
|
|
/*
|
|
// create target storage surface
|
|
IDirect3DSurface8 *target;
|
|
glw_state->device->CreateImageSurface(twidth, theight, D3DFMT_A8R8G8B8, &target);
|
|
|
|
// get a pointer to the back buffer
|
|
IDirect3DSurface8* back;
|
|
glw_state->device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &back);
|
|
|
|
D3DSURFACE_DESC ddsd;
|
|
back->GetDesc(&ddsd);
|
|
int bpp = XGBytesPerPixelFromFormat(ddsd.Format);
|
|
|
|
// create surface to hold screen data
|
|
// (512x512 is exactly big enough to hold the screen but we
|
|
// need to save some memory so I'm going to clip the edges)
|
|
IDirect3DSurface8 *screen;
|
|
glw_state->device->CreateImageSurface(512, 512, ddsd.Format, &screen);
|
|
|
|
// copy back buffer to non-tiled screen surface
|
|
RECT r;
|
|
r.left = 64;
|
|
r.top = 0;
|
|
r.right = 576;
|
|
r.bottom = 480;
|
|
POINT ul = {0, 0};
|
|
glw_state->device->CopyRects(back, &r, 1, screen, &ul);
|
|
back->Release();
|
|
|
|
// deswizzle the screen
|
|
D3DLOCKED_RECT lock;
|
|
screen->LockRect(&lock, NULL, D3DLOCK_READONLY);
|
|
void* deswizzled = Z_Malloc(512*512*bpp, TAG_TEMP_WORKSPACE, qfalse, 16);
|
|
XGUnswizzleRect(lock.pBits, 512, 512, NULL, deswizzled, 0, NULL, bpp);
|
|
screen->UnlockRect();
|
|
screen->Release();
|
|
|
|
// copy the screen into a surface of the appropriate size and format
|
|
r.left = 0;
|
|
r.top = 0;
|
|
r.right = 512;
|
|
r.bottom = 480;
|
|
D3DXLoadSurfaceFromMemory(target, NULL, NULL, deswizzled, ddsd.Format,
|
|
512*bpp, NULL, &r, D3DX_DEFAULT, 0);
|
|
Z_Free(deswizzled);
|
|
|
|
// lock the target surface
|
|
target->LockRect(&lock, NULL, D3DLOCK_READONLY);
|
|
|
|
// copy the pixel data
|
|
for (int y = 0; y < theight; ++y)
|
|
{
|
|
memcpy((char*)pixels + twidth * y * 4,
|
|
(char*)lock.pBits + lock.Pitch * y,
|
|
twidth * 4);
|
|
}
|
|
|
|
// all done
|
|
target->UnlockRect();
|
|
target->Release();
|
|
*/
|
|
}
|
|
/**********
|
|
dllCopyBackBufferToTex
|
|
Does a direct copy of the backbuffer to the current texture. The current texture
|
|
must be linear, and it must be 640 x 480 in size. If a more complex copy is
|
|
needed, use dllCopyBackBufferToTexEXT.
|
|
**********/
|
|
static void dllCopyBackBufferToTex()
|
|
{
|
|
glwstate_t::TextureInfo* info = _getCurrentTexture(glw_state->serverTU);
|
|
if (info == NULL) return;
|
|
|
|
LPDIRECT3DSURFACE8 surf;
|
|
LPDIRECT3DSURFACE8 backbuffer;
|
|
|
|
info->mipmap->GetSurfaceLevel(0, &surf);
|
|
glw_state->device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
|
|
|
|
glw_state->device->CopyRects(backbuffer, NULL, 0, surf, NULL);
|
|
|
|
surf->Release();
|
|
backbuffer->Release();
|
|
}
|
|
|
|
/**********
|
|
dllCopyBackBufferToTexEXT
|
|
Copies a portion of the backbuffer to a texture
|
|
If the destination is a DXT1 texture, then the buffer will be compressed
|
|
width - width of the backbuffer polygon rendered to the destination texture
|
|
height - height of the backbuffer polygon rendered to the destination texture
|
|
u,v - describes the potion of the backbuffer to be copied in screen coords
|
|
**********/
|
|
static void dllCopyBackBufferToTexEXT(float width, float height, float u1, float v1, float u2, float v2)
|
|
{
|
|
glwstate_t::TextureInfo* info = _getCurrentTexture(glw_state->serverTU);
|
|
if (info == NULL) return;
|
|
|
|
struct QUAD { D3DXVECTOR4 p; FLOAT tu,tv;} q[4];
|
|
q[0].p = D3DXVECTOR4( 0.0f, 0.0f, 1.0f, 1.0f );
|
|
q[0].tu = u1; q[0].tv = v1;
|
|
q[1].p = D3DXVECTOR4( width, 0.0f, 1.0f, 1.0f );
|
|
q[1].tu = u2; q[1].tv = v1;
|
|
q[2].p = D3DXVECTOR4( 0.0f, height , 1.0f, 1.0f );
|
|
q[2].tu = u1; q[2].tv = v2;
|
|
q[3].p = D3DXVECTOR4( width, height, 1.0f, 1.0f );
|
|
q[3].tu = u2; q[3].tv = v2;
|
|
|
|
|
|
LPDIRECT3DSURFACE8 pSurface;
|
|
LPDIRECT3DSURFACE8 pBackBuffer;
|
|
LPDIRECT3DSURFACE8 pStencilBuffer;
|
|
D3DSURFACE_DESC desc;
|
|
D3DBaseTexture* pTexStage0;
|
|
D3DBaseTexture* pTexStage1;
|
|
D3DBaseTexture* pTexStage2;
|
|
D3DBaseTexture* pTexStage3;
|
|
D3DTexture* pRenderTex;
|
|
int w = 0;
|
|
int h = 0;
|
|
|
|
DWORD srcblend, destblend, alphablend, alphatest, zwrite, zenable, vShader, pShader;
|
|
DWORD colorop, colorarg1, addressu, addressv, minfilter, magfilter, colorwriteenable;
|
|
|
|
// save the current state
|
|
glw_state->device->GetRenderState( D3DRS_SRCBLEND, &srcblend );
|
|
glw_state->device->GetRenderState( D3DRS_DESTBLEND, &destblend );
|
|
glw_state->device->GetRenderState( D3DRS_ALPHABLENDENABLE, &alphablend );
|
|
glw_state->device->GetRenderState( D3DRS_ALPHATESTENABLE, &alphatest );
|
|
glw_state->device->GetRenderState( D3DRS_ZWRITEENABLE, &zwrite );
|
|
glw_state->device->GetRenderState( D3DRS_ZENABLE, &zenable );
|
|
glw_state->device->GetRenderState( D3DRS_COLORWRITEENABLE, &colorwriteenable);
|
|
glw_state->device->GetVertexShader( &vShader );
|
|
glw_state->device->GetPixelShader( &pShader );
|
|
glw_state->device->GetTexture(0,&pTexStage0);
|
|
glw_state->device->GetTexture(1,&pTexStage1);
|
|
glw_state->device->GetTexture(2,&pTexStage2);
|
|
glw_state->device->GetTexture(3,&pTexStage3);
|
|
glw_state->device->GetTextureStageState(0, D3DTSS_COLOROP, &colorop);
|
|
glw_state->device->GetTextureStageState(0, D3DTSS_COLORARG1, &colorarg1);
|
|
glw_state->device->GetTextureStageState(0, D3DTSS_ADDRESSU, &addressu);
|
|
glw_state->device->GetTextureStageState(0, D3DTSS_ADDRESSV, &addressv);
|
|
glw_state->device->GetTextureStageState(0, D3DTSS_MINFILTER, &minfilter);
|
|
glw_state->device->GetTextureStageState(0, D3DTSS_MAGFILTER, &magfilter);
|
|
|
|
// get the buffers
|
|
glw_state->device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer);
|
|
glw_state->device->GetDepthStencilSurface(&pStencilBuffer);
|
|
|
|
// get a surface desc
|
|
info->mipmap->GetLevelDesc(0, &desc);
|
|
|
|
// check to see if the texture needs to be resized
|
|
if( desc.Width != width || desc.Height != height)
|
|
{
|
|
int refCount;
|
|
refCount = info->mipmap->Release();
|
|
|
|
// Had to remove this. Multiple characters using force push in one
|
|
// frame triggers the assert. Things clean up by the end of the frame.
|
|
// assert(refCount == 0);
|
|
|
|
glw_state->device->CreateTexture( width,
|
|
height,
|
|
1,
|
|
0,
|
|
desc.Format,
|
|
0,
|
|
&info->mipmap );
|
|
}
|
|
|
|
// check to see if we want a compressed output texture
|
|
if( desc.Format == D3DFMT_DXT1)
|
|
{
|
|
|
|
w = desc.Width;
|
|
h = desc.Height;
|
|
|
|
// create a new texture to use as a render target
|
|
glw_state->device->CreateTexture( w,
|
|
h,
|
|
1,
|
|
0,
|
|
D3DFMT_LIN_X8R8G8B8,
|
|
0,
|
|
&pRenderTex );
|
|
}
|
|
else
|
|
{
|
|
pRenderTex = info->mipmap;
|
|
|
|
}
|
|
|
|
// make our current surface a render target
|
|
pRenderTex->GetSurfaceLevel(0, &pSurface);
|
|
glw_state->device->SetRenderTarget( pSurface, NULL );
|
|
|
|
// set texture 0 to the back buffer data
|
|
glw_state->device->SetTexture(0,(LPDIRECT3DTEXTURE8)pBackBuffer);
|
|
|
|
// clear the other texture stages
|
|
glw_state->device->SetTexture(1, NULL);
|
|
glw_state->device->SetTexture(2, NULL);
|
|
glw_state->device->SetTexture(3, NULL);
|
|
|
|
// set the texture 0 state
|
|
glw_state->device->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
|
|
glw_state->device->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
|
|
glw_state->device->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
|
|
glw_state->device->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
|
|
glw_state->device->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
|
|
glw_state->device->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
|
|
|
|
// set the render state
|
|
glw_state->device->SetRenderState( D3DRS_ZENABLE, FALSE );
|
|
glw_state->device->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
|
|
glw_state->device->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE);
|
|
glw_state->device->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
|
|
glw_state->device->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_SRCALPHA | D3DBLEND_INVSRCALPHA );
|
|
glw_state->device->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALL);
|
|
|
|
// set our vertex shader and draw the backbuffer to the texture
|
|
glw_state->device->SetVertexShader( D3DFVF_XYZRHW|D3DFVF_TEX1 );
|
|
glw_state->device->SetPixelShader( NULL );
|
|
glw_state->device->Clear(NULL,NULL,D3DCLEAR_TARGET,D3DCOLOR_COLORVALUE(1.0f, 1.0f, 1.0f, 1.0f), 1.0f, 0);
|
|
glw_state->device->DrawPrimitiveUP( D3DPT_QUADSTRIP, 1, q, sizeof(QUAD) );
|
|
|
|
// now that everything is rendered, check again to see
|
|
// if we want a compressed texture
|
|
if( desc.Format == D3DFMT_DXT1)
|
|
{
|
|
LPDIRECT3DTEXTURE8 pSrcTex;
|
|
LPDIRECT3DTEXTURE8 pDstTex;
|
|
D3DLOCKED_RECT srcLock;
|
|
D3DLOCKED_RECT dstLock;
|
|
|
|
pSrcTex = pRenderTex;
|
|
pDstTex = info->mipmap;
|
|
|
|
// lock our textures
|
|
pSrcTex->LockRect(0, &srcLock, NULL, 0);
|
|
pDstTex->LockRect(0, &dstLock, NULL, 0);
|
|
|
|
// compress the texture
|
|
XGCompressRect( dstLock.pBits,
|
|
D3DFMT_DXT1,
|
|
dstLock.Pitch,
|
|
w,
|
|
h,
|
|
srcLock.pBits,
|
|
D3DFMT_LIN_X8R8G8B8,
|
|
srcLock.Pitch,
|
|
1,
|
|
0 );
|
|
|
|
// unlock
|
|
pSrcTex->UnlockRect(0);
|
|
pDstTex->UnlockRect(0);
|
|
|
|
// release the render texture
|
|
pRenderTex->Release();
|
|
}
|
|
|
|
// return our state
|
|
glw_state->device->SetRenderState( D3DRS_SRCBLEND, srcblend );
|
|
glw_state->device->SetRenderState( D3DRS_DESTBLEND, destblend );
|
|
glw_state->device->SetRenderState( D3DRS_ALPHABLENDENABLE, alphablend );
|
|
glw_state->device->SetRenderState( D3DRS_ALPHATESTENABLE, alphatest );
|
|
glw_state->device->SetRenderState( D3DRS_ZWRITEENABLE, zwrite );
|
|
glw_state->device->SetRenderState( D3DRS_ZENABLE, zenable );
|
|
glw_state->device->SetRenderState( D3DRS_COLORWRITEENABLE, colorwriteenable);
|
|
|
|
glw_state->device->SetTexture(0,pTexStage0);
|
|
glw_state->device->SetTexture(1,pTexStage1);
|
|
glw_state->device->SetTexture(2,pTexStage2);
|
|
glw_state->device->SetTexture(3,pTexStage3);
|
|
glw_state->device->SetTextureStageState(0, D3DTSS_COLOROP, colorop);
|
|
glw_state->device->SetTextureStageState(0, D3DTSS_COLORARG1, colorarg1);
|
|
glw_state->device->SetTextureStageState(0, D3DTSS_ADDRESSU, addressu);
|
|
glw_state->device->SetTextureStageState(0, D3DTSS_ADDRESSV, addressv);
|
|
glw_state->device->SetTextureStageState(0, D3DTSS_MINFILTER, minfilter);
|
|
glw_state->device->SetTextureStageState(0, D3DTSS_MAGFILTER, magfilter);
|
|
|
|
glw_state->device->SetVertexShader( vShader );
|
|
glw_state->device->SetPixelShader( pShader );
|
|
|
|
glw_state->device->SetRenderTarget( pBackBuffer, pStencilBuffer );
|
|
|
|
// release our surfaces/textures
|
|
if(pTexStage0)
|
|
pTexStage0->Release();
|
|
|
|
if(pTexStage1)
|
|
pTexStage1->Release();
|
|
|
|
if(pTexStage2)
|
|
pTexStage2->Release();
|
|
|
|
if(pTexStage3)
|
|
pTexStage3->Release();
|
|
|
|
pSurface->Release();
|
|
pBackBuffer->Release();
|
|
pStencilBuffer->Release();
|
|
}
|
|
|
|
static void dllRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRectdv(const GLdouble *v1, const GLdouble *v2)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRectfv(const GLfloat *v1, const GLfloat *v2)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRecti(GLint x1, GLint y1, GLint x2, GLint y2)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRectiv(const GLint *v1, const GLint *v2)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRectsv(const GLshort *v1, const GLshort *v2)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
GLint dllRenderMode(GLenum mode)
|
|
{
|
|
assert(0);
|
|
return 0;
|
|
}
|
|
|
|
static void dllRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
|
|
{
|
|
D3DXVECTOR3 v(x, y, z);
|
|
glw_state->matrixStack[glw_state->matrixMode]->RotateAxisLocal(&v, angle);
|
|
glw_state->matricesDirty[glw_state->matrixMode] = true;
|
|
}
|
|
|
|
static void dllScaled(GLdouble x, GLdouble y, GLdouble z)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllScalef(GLfloat x, GLfloat y, GLfloat z)
|
|
{
|
|
glw_state->matrixStack[glw_state->matrixMode]->Scale(x, y, z);
|
|
glw_state->matricesDirty[glw_state->matrixMode] = true;
|
|
}
|
|
|
|
static void dllScissor(GLint x, GLint y, GLsizei width, GLsizei height)
|
|
{
|
|
#ifdef _XBOX
|
|
_fixupScreenCoords(x, y, width, height);
|
|
|
|
glw_state->scissorBox.x1 = x;
|
|
glw_state->scissorBox.y1 = y;
|
|
glw_state->scissorBox.x2 = x + width;
|
|
glw_state->scissorBox.y2 = y + height;
|
|
|
|
if (glw_state->scissorEnable)
|
|
{
|
|
glw_state->device->SetScissors(1, FALSE, &glw_state->scissorBox);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static void dllSelectBuffer(GLsizei size, GLuint *buffer)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllShadeModel(GLenum mode)
|
|
{
|
|
D3DSHADEMODE m;
|
|
switch (mode)
|
|
{
|
|
case GL_FLAT: m = D3DSHADE_FLAT; break;
|
|
case GL_SMOOTH: default: m = D3DSHADE_GOURAUD; break;
|
|
}
|
|
|
|
glw_state->device->SetRenderState(D3DRS_SHADEMODE, m);
|
|
}
|
|
|
|
static void dllStencilFunc(GLenum func, GLint ref, GLuint mask)
|
|
{
|
|
D3DCMPFUNC f = _convertCompare(func);
|
|
|
|
glw_state->device->SetRenderState(D3DRS_STENCILFUNC, f);
|
|
glw_state->device->SetRenderState(D3DRS_STENCILREF, ref);
|
|
glw_state->device->SetRenderState(D3DRS_STENCILMASK, mask);
|
|
}
|
|
|
|
static void dllStencilMask(GLuint mask)
|
|
{
|
|
glw_state->device->SetRenderState(D3DRS_STENCILWRITEMASK, mask);
|
|
}
|
|
|
|
static D3DSTENCILOP _convertStencilOp(GLenum op)
|
|
{
|
|
switch (op)
|
|
{
|
|
default: case GL_KEEP: return D3DSTENCILOP_KEEP;
|
|
case GL_ZERO: return D3DSTENCILOP_ZERO;
|
|
case GL_REPLACE: return D3DSTENCILOP_REPLACE;
|
|
case GL_INCR: return D3DSTENCILOP_INCR;
|
|
case GL_DECR: return D3DSTENCILOP_DECR;
|
|
case GL_INVERT: return D3DSTENCILOP_INVERT;
|
|
}
|
|
}
|
|
|
|
static void dllStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
|
|
{
|
|
D3DSTENCILOP f = _convertStencilOp(fail);
|
|
D3DSTENCILOP zf = _convertStencilOp(zfail);
|
|
D3DSTENCILOP zp = _convertStencilOp(zpass);
|
|
|
|
glw_state->device->SetRenderState(D3DRS_STENCILFAIL, f);
|
|
glw_state->device->SetRenderState(D3DRS_STENCILZFAIL, zf);
|
|
glw_state->device->SetRenderState(D3DRS_STENCILPASS, zp);
|
|
}
|
|
|
|
static void dllTexCoord1d(GLdouble s)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord1dv(const GLdouble *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord1f(GLfloat s)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord1fv(const GLfloat *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord1i(GLint s)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord1iv(const GLint *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord1s(GLshort s)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord1sv(const GLshort *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void setTexCoord(float s, float t)
|
|
{
|
|
assert(glw_state->inDrawBlock);
|
|
|
|
_handleDrawOverflow();
|
|
|
|
int off = 0;
|
|
if(glw_state->normalArrayState)
|
|
off = 3;
|
|
|
|
DWORD* push = &glw_state->drawArray[
|
|
glw_state->numVertices * glw_state->drawStride +
|
|
4 + off + glw_state->serverTU * 2];
|
|
|
|
*push++ = *((DWORD*)&s);
|
|
*push++ = *((DWORD*)&t);
|
|
}
|
|
|
|
static void dllTexCoord2d(GLdouble s, GLdouble t)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord2dv(const GLdouble *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord2f(GLfloat s, GLfloat t)
|
|
{
|
|
setTexCoord(s, t);
|
|
}
|
|
|
|
static void dllTexCoord2fv(const GLfloat *v)
|
|
{
|
|
setTexCoord(v[0], v[1]);
|
|
}
|
|
|
|
static void dllTexCoord2i(GLint s, GLint t)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord2iv(const GLint *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord2s(GLshort s, GLshort t)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord2sv(const GLshort *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord3d(GLdouble s, GLdouble t, GLdouble r)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord3dv(const GLdouble *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord3f(GLfloat s, GLfloat t, GLfloat r)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord3fv(const GLfloat *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord3i(GLint s, GLint t, GLint r)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord3iv(const GLint *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord3s(GLshort s, GLshort t, GLshort r)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord3sv(const GLshort *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord4dv(const GLdouble *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord4fv(const GLfloat *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord4i(GLint s, GLint t, GLint r, GLint q)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord4iv(const GLint *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoord4sv(const GLshort *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
|
|
{
|
|
assert(size == 2 && type == GL_FLOAT);
|
|
|
|
stride = (stride == 0) ? (sizeof(GLfloat) * 2) : stride;
|
|
|
|
glw_state->texCoordPointer[glw_state->clientTU] = pointer;
|
|
glw_state->texCoordStride[glw_state->clientTU] = stride;
|
|
}
|
|
|
|
static void dllTexEnvf(GLenum target, GLenum pname, GLfloat param)
|
|
{
|
|
qglTexEnvi(target, pname, (GLint)param);
|
|
}
|
|
|
|
static void dllTexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexEnvi(GLenum target, GLenum pname, GLint param)
|
|
{
|
|
assert(target == GL_TEXTURE_ENV && pname == GL_TEXTURE_ENV_MODE);
|
|
|
|
/*glwstate_t::TextureInfo* info = _getCurrentTexture(glw_state->serverTU);
|
|
if (!info) return;*/
|
|
|
|
D3DTEXTUREOP env;
|
|
switch (param)
|
|
{
|
|
case GL_MODULATE: default: env = D3DTOP_MODULATE; break;
|
|
case GL_REPLACE: env = D3DTOP_SELECTARG1; break;
|
|
// MATT! - I use GL_DECAL as the bumpmapping state
|
|
case GL_DECAL: env = D3DTOP_DOTPRODUCT3; break;
|
|
case GL_ADD: env = D3DTOP_ADD; break;
|
|
case GL_NONE: env = D3DTOP_DISABLE; break;
|
|
}
|
|
|
|
if (glw_state->textureEnv[glw_state->serverTU] != env)
|
|
{
|
|
glw_state->textureEnv[glw_state->serverTU] = env;
|
|
glw_state->textureStageDirty[glw_state->serverTU] = true;
|
|
}
|
|
}
|
|
|
|
static void dllTexEnviv(GLenum target, GLenum pname, const GLint *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexGend(GLenum coord, GLenum pname, GLdouble param)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexGendv(GLenum coord, GLenum pname, const GLdouble *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexGenf(GLenum coord, GLenum pname, GLfloat param)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexGenfv(GLenum coord, GLenum pname, const GLfloat *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexGeni(GLenum coord, GLenum pname, GLint param)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexGeniv(GLenum coord, GLenum pname, const GLint *params)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void _d3d_check(HRESULT err, const char* func)
|
|
{
|
|
if (err != D3D_OK)
|
|
{
|
|
MEMORYSTATUS status;
|
|
GlobalMemoryStatus(&status);
|
|
Sys_Print(va("%s returned %d! Memfree=%d\n", func, err, status.dwAvailPhys));
|
|
}
|
|
}
|
|
|
|
static void _texImageDDS(glwstate_t::TextureInfo* info, GLint numlevels, GLsizei width, GLsizei height, GLenum format, const GLvoid *pixels)
|
|
{
|
|
_d3d_check(D3DXCreateTextureFromFileInMemoryEx(glw_state->device,
|
|
pixels,
|
|
Z_Size(const_cast<void*>(pixels)),
|
|
width,
|
|
height,
|
|
numlevels,
|
|
0,
|
|
D3DFMT_UNKNOWN,
|
|
D3DPOOL_MANAGED,
|
|
D3DX_DEFAULT,
|
|
D3DX_DEFAULT,
|
|
0,
|
|
NULL,
|
|
NULL,
|
|
&info->mipmap),
|
|
"D3DXCreateTextureFromFileInMemoryEx");
|
|
}
|
|
|
|
static void _texImageRGBA(glwstate_t::TextureInfo* info, GLint numlevels, GLint internalformat, GLsizei width, GLsizei height, GLenum format, const GLvoid *pixels)
|
|
{
|
|
IDirect3DSurface8 *pSurf = NULL;
|
|
D3DFORMAT f;
|
|
float bpp;
|
|
int pitch;
|
|
RECT srcRect;
|
|
|
|
srcRect.top = 0;
|
|
srcRect.left = 0;
|
|
srcRect.right = width;
|
|
srcRect.bottom = height;
|
|
|
|
switch(format)
|
|
{
|
|
case GL_RGB:
|
|
f = D3DFMT_X8R8G8B8;
|
|
bpp = 3;
|
|
break;
|
|
|
|
case GL_RGBA:
|
|
f = D3DFMT_A8R8G8B8;
|
|
bpp = 4;
|
|
break;
|
|
|
|
case GL_LIN_RGBA:
|
|
f = D3DFMT_LIN_A8R8G8B8;
|
|
bpp = 4;
|
|
break;
|
|
|
|
case GL_LIN_RGB:
|
|
f = D3DFMT_LIN_X8R8G8B8;
|
|
bpp = 4;
|
|
break;
|
|
|
|
case GL_LIN_RGB8:
|
|
f = D3DFMT_LIN_X8R8G8B8;
|
|
bpp = 4;
|
|
break;
|
|
|
|
case GL_RGB8:
|
|
f = D3DFMT_X8R8G8B8;
|
|
bpp = 4;
|
|
break;
|
|
|
|
case GL_RGB_SWIZZLE_EXT:
|
|
f = D3DFMT_R5G6B5;
|
|
bpp = 2;
|
|
break;
|
|
|
|
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
|
f = D3DFMT_DXT1;
|
|
bpp = 0.5;
|
|
break;
|
|
|
|
default:
|
|
assert(0);
|
|
}
|
|
|
|
_d3d_check(glw_state->device->CreateImageSurface(width, height, f, &pSurf),
|
|
"CreateImageSurface");
|
|
|
|
pitch = (int)((float)width * bpp);
|
|
|
|
_d3d_check(D3DXLoadSurfaceFromMemory(pSurf,
|
|
NULL,
|
|
NULL,
|
|
(LPCVOID)pixels,
|
|
f,
|
|
pitch,
|
|
NULL,
|
|
&srcRect,
|
|
D3DX_FILTER_NONE,
|
|
0),
|
|
"D3DXLoadSurfaceFromMemory");
|
|
|
|
switch(internalformat)
|
|
{
|
|
case GL_RGB5:
|
|
case GL_RGB4_S3TC:
|
|
f = D3DFMT_R5G6B5;
|
|
break;
|
|
|
|
case GL_RGBA4:
|
|
f = D3DFMT_A4R4G4B4;
|
|
break;
|
|
|
|
case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
|
|
f = D3DFMT_DXT1;
|
|
break;
|
|
|
|
case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
|
|
f = D3DFMT_DXT5;
|
|
break;
|
|
|
|
case GL_RGB8:
|
|
case 3:
|
|
f = D3DFMT_X8R8G8B8;
|
|
break;
|
|
|
|
case GL_LIN_RGBA8:
|
|
f = D3DFMT_LIN_A8R8G8B8;
|
|
break;
|
|
case GL_LIN_RGB8:
|
|
f = D3DFMT_LIN_X8R8G8B8;
|
|
break;
|
|
|
|
case GL_RGBA8:
|
|
case 4:
|
|
f = D3DFMT_A8R8G8B8;
|
|
break;
|
|
case GL_RGB:
|
|
f = D3DFMT_X8R8G8B8;
|
|
break;
|
|
|
|
default:
|
|
assert(0);
|
|
}
|
|
|
|
_d3d_check(D3DXCreateTexture(glw_state->device,
|
|
width,
|
|
height,
|
|
numlevels,
|
|
0,
|
|
f,
|
|
D3DPOOL_MANAGED,
|
|
&info->mipmap),
|
|
"D3DXCreateTexture");
|
|
|
|
LPDIRECT3DSURFACE8 txtSurf;
|
|
_d3d_check(info->mipmap->GetSurfaceLevel(0, &txtSurf),
|
|
"GetSurfaceLevel");
|
|
|
|
_d3d_check(D3DXLoadSurfaceFromSurface(txtSurf, NULL, NULL,
|
|
pSurf, NULL, NULL, D3DX_DEFAULT, 0),
|
|
"D3DXLoadSurfaceFromSurface");
|
|
|
|
txtSurf->Release();
|
|
pSurf->Release();
|
|
|
|
if(numlevels > 1)
|
|
{
|
|
_d3d_check(D3DXFilterTexture(info->mipmap,
|
|
NULL,
|
|
D3DX_DEFAULT,
|
|
D3DX_DEFAULT),
|
|
"D3DXFilterTexture");
|
|
}
|
|
}
|
|
|
|
// EXTENSION: glTexImage2D plus "numlevels" number of mipmaps
|
|
static void dllTexImage2DEXT(GLenum target, GLint level, GLint numlevels, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
|
|
{
|
|
assert(target == GL_TEXTURE_2D && border == 0 && type == GL_UNSIGNED_BYTE);
|
|
|
|
// In Direct3D, setting 0 for number of mipmap
|
|
// levels means create the whole chain....
|
|
/*if(numlevels == 0)
|
|
numlevels = 1;*/
|
|
|
|
glwstate_t::TextureInfo* info;
|
|
|
|
glwstate_t::texturexlat_t::iterator current =
|
|
glw_state->textureXlat.find(
|
|
glw_state->currentTexture[glw_state->serverTU]);
|
|
|
|
// If we already have a texture bound to this ID, remove it.
|
|
if (current != glw_state->textureXlat.end())
|
|
{
|
|
info = ¤t->second;
|
|
info->mipmap->Release();
|
|
}
|
|
// Otherwise, initialize it.
|
|
else
|
|
{
|
|
info = &glw_state->textureXlat[
|
|
glw_state->currentTexture[glw_state->serverTU]];
|
|
|
|
info->minFilter = D3DTEXF_NONE;
|
|
info->mipFilter = D3DTEXF_NONE;
|
|
info->magFilter = D3DTEXF_NONE;
|
|
info->anisotropy = 1.f;
|
|
info->wrapU = D3DTADDRESS_CLAMP;
|
|
info->wrapV = D3DTADDRESS_CLAMP;
|
|
|
|
glw_state->textureStageDirty[glw_state->serverTU] = true;
|
|
}
|
|
|
|
// force any DX allocs to temp memory
|
|
Z_SetNewDeleteTemporary(true);
|
|
|
|
if (format == GL_DDS1_EXT ||
|
|
format == GL_DDS5_EXT ||
|
|
format == GL_DDS_RGB16_EXT ||
|
|
format == GL_DDS_RGBA32_EXT)
|
|
{
|
|
_texImageDDS(info, numlevels, width, height, format, pixels);
|
|
}
|
|
else
|
|
{
|
|
_texImageRGBA(info, numlevels,
|
|
internalformat, width, height,
|
|
format, pixels);
|
|
}
|
|
|
|
// Done DX calls to new and delete
|
|
Z_SetNewDeleteTemporary(false);
|
|
|
|
#if MEMORY_PROFILE
|
|
texMemSize += getTexMemSize(info->mipmap);
|
|
#endif
|
|
}
|
|
|
|
static void dllTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
|
|
{
|
|
dllTexImage2DEXT(target, level, 1, internalformat, width, height, border, format, type, pixels);
|
|
}
|
|
|
|
static void dllTexParameteri(GLenum target, GLenum pname, GLint param)
|
|
{
|
|
assert(target == GL_TEXTURE_2D);
|
|
|
|
if (glw_state->currentTexture[glw_state->serverTU] == 0) return;
|
|
|
|
glwstate_t::TextureInfo* info = _getCurrentTexture(glw_state->serverTU);
|
|
if (!info) return;
|
|
|
|
glw_state->textureStageDirty[glw_state->serverTU] = true;
|
|
|
|
switch (pname)
|
|
{
|
|
case GL_TEXTURE_MIN_FILTER:
|
|
switch (param)
|
|
{
|
|
case GL_NEAREST:
|
|
info->minFilter = D3DTEXF_POINT;
|
|
info->mipFilter = D3DTEXF_NONE;
|
|
break;
|
|
case GL_LINEAR:
|
|
info->minFilter = D3DTEXF_LINEAR;
|
|
info->mipFilter = D3DTEXF_NONE;
|
|
break;
|
|
case GL_NEAREST_MIPMAP_NEAREST:
|
|
info->minFilter = D3DTEXF_POINT;
|
|
info->mipFilter = D3DTEXF_POINT;
|
|
break;
|
|
case GL_LINEAR_MIPMAP_NEAREST:
|
|
info->minFilter = D3DTEXF_LINEAR;
|
|
info->mipFilter = D3DTEXF_POINT;
|
|
break;
|
|
case GL_NEAREST_MIPMAP_LINEAR:
|
|
info->minFilter = D3DTEXF_POINT;
|
|
info->mipFilter = D3DTEXF_LINEAR;
|
|
break;
|
|
case GL_LINEAR_MIPMAP_LINEAR:
|
|
info->minFilter = D3DTEXF_LINEAR;
|
|
info->mipFilter = D3DTEXF_LINEAR;
|
|
break;
|
|
}
|
|
info->anisotropy = 1.f;
|
|
break;
|
|
case GL_TEXTURE_MAG_FILTER:
|
|
switch (param)
|
|
{
|
|
case GL_NEAREST:
|
|
info->magFilter = D3DTEXF_POINT;
|
|
break;
|
|
case GL_LINEAR:
|
|
info->magFilter = D3DTEXF_LINEAR;
|
|
break;
|
|
}
|
|
info->anisotropy = 1.f;
|
|
break;
|
|
case GL_TEXTURE_WRAP_S:
|
|
switch (param)
|
|
{
|
|
case GL_REPEAT: info->wrapU = D3DTADDRESS_WRAP; break;
|
|
case GL_CLAMP: info->wrapU = D3DTADDRESS_CLAMP; break;
|
|
}
|
|
break;
|
|
case GL_TEXTURE_WRAP_T:
|
|
switch (param)
|
|
{
|
|
case GL_REPEAT: info->wrapV = D3DTADDRESS_WRAP; break;
|
|
case GL_CLAMP: info->wrapV = D3DTADDRESS_CLAMP; break;
|
|
}
|
|
break;
|
|
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
|
|
info->anisotropy = (float)param;
|
|
info->minFilter = D3DTEXF_ANISOTROPIC;
|
|
info->magFilter = D3DTEXF_ANISOTROPIC;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void dllTexParameterf(GLenum target, GLenum pname, GLfloat param)
|
|
{
|
|
dllTexParameteri(target, pname, param);
|
|
}
|
|
|
|
static void dllTexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
|
|
{
|
|
// Intentionally left blank
|
|
}
|
|
|
|
static void dllTexParameteriv(GLenum target, GLenum pname, const GLint *params)
|
|
{
|
|
// Intentionally left blank
|
|
}
|
|
|
|
static void dllTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
|
|
{
|
|
assert(target == GL_TEXTURE_2D && level == 0 && type == GL_UNSIGNED_BYTE);
|
|
|
|
glwstate_t::TextureInfo* info = _getCurrentTexture(glw_state->serverTU);
|
|
if (info == NULL) return;
|
|
|
|
RECT sr;
|
|
sr.top = 0;
|
|
sr.left = 0;
|
|
sr.right = width;
|
|
sr.bottom = height;
|
|
|
|
RECT dr;
|
|
dr.top = xoffset;
|
|
dr.left = yoffset;
|
|
dr.right = xoffset + width;
|
|
dr.bottom = yoffset + height;
|
|
|
|
Z_SetNewDeleteTemporary(true);
|
|
|
|
LPDIRECT3DSURFACE8 surf;
|
|
info->mipmap->GetSurfaceLevel(0, &surf);
|
|
|
|
// We use the supplied format to handle pixel data correctly, the way OGL would
|
|
D3DFORMAT srcFormat;
|
|
switch(format)
|
|
{
|
|
case GL_RGB:
|
|
srcFormat = D3DFMT_LIN_X8R8G8B8;
|
|
break;
|
|
|
|
case GL_RGBA:
|
|
srcFormat = D3DFMT_LIN_A8R8G8B8;
|
|
break;
|
|
|
|
default:
|
|
assert(0 && "Unsupported format in dllTexSubImage2D");
|
|
return;
|
|
}
|
|
|
|
D3DXLoadSurfaceFromMemory(surf, NULL, &dr, pixels,
|
|
srcFormat, width * 4, NULL, &sr, D3DX_DEFAULT, 0);
|
|
|
|
surf->Release();
|
|
|
|
Z_SetNewDeleteTemporary(false);
|
|
}
|
|
|
|
static void dllTranslated(GLdouble x, GLdouble y, GLdouble z)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllTranslatef(GLfloat x, GLfloat y, GLfloat z)
|
|
{
|
|
glw_state->matrixStack[glw_state->matrixMode]->TranslateLocal(x, y, z);
|
|
glw_state->matricesDirty[glw_state->matrixMode] = true;
|
|
}
|
|
|
|
static void setVertex(float x, float y, float z)
|
|
{
|
|
assert(glw_state->inDrawBlock);
|
|
|
|
_handleDrawOverflow();
|
|
|
|
DWORD* push = &glw_state->drawArray[glw_state->numVertices * glw_state->drawStride];
|
|
push[0] = *((DWORD*)&x);
|
|
push[1] = *((DWORD*)&y);
|
|
push[2] = *((DWORD*)&z);
|
|
push[3] = glw_state->currentColor;
|
|
|
|
++glw_state->numVertices;
|
|
}
|
|
|
|
static void dllVertex2d(GLdouble x, GLdouble y)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex2dv(const GLdouble *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex2f(GLfloat x, GLfloat y)
|
|
{
|
|
setVertex(x, y, 0.f);
|
|
}
|
|
|
|
static void dllVertex2fv(const GLfloat *v)
|
|
{
|
|
setVertex(v[0], v[1], 0.f);
|
|
}
|
|
|
|
static void dllVertex2i(GLint x, GLint y)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex2iv(const GLint *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex2s(GLshort x, GLshort y)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex2sv(const GLshort *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex3d(GLdouble x, GLdouble y, GLdouble z)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex3dv(const GLdouble *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex3f(GLfloat x, GLfloat y, GLfloat z)
|
|
{
|
|
setVertex(x, y, z);
|
|
}
|
|
|
|
static void dllVertex3fv(const GLfloat *v)
|
|
{
|
|
setVertex(v[0], v[1], v[2]);
|
|
}
|
|
|
|
static void dllVertex3i(GLint x, GLint y, GLint z)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex3iv(const GLint *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex3s(GLshort x, GLshort y, GLshort z)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex3sv(const GLshort *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex4dv(const GLdouble *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w)
|
|
{
|
|
setVertex(x, y, z);
|
|
}
|
|
|
|
static void dllVertex4fv(const GLfloat *v)
|
|
{
|
|
setVertex(v[0], v[1], v[2]);
|
|
}
|
|
|
|
static void dllVertex4i(GLint x, GLint y, GLint z, GLint w)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex4iv(const GLint *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex4s(GLshort x, GLshort y, GLshort z, GLshort w)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertex4sv(const GLshort *v)
|
|
{
|
|
assert(0);
|
|
}
|
|
|
|
static void dllVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
|
|
{
|
|
assert(size == 3 && type == GL_FLOAT);
|
|
|
|
stride = (stride == 0) ? (sizeof(GLfloat) * 3) : stride;
|
|
|
|
glw_state->vertexPointer = pointer;
|
|
glw_state->vertexStride = stride;
|
|
}
|
|
|
|
static void dllViewport(GLint x, GLint y, GLsizei width, GLsizei height)
|
|
{
|
|
_fixupScreenCoords(x, y, width, height);
|
|
|
|
glw_state->viewport.X = x;
|
|
glw_state->viewport.Y = y;
|
|
glw_state->viewport.Width = width;
|
|
glw_state->viewport.Height = height;
|
|
glw_state->device->SetViewport(&glw_state->viewport);
|
|
}
|
|
|
|
|
|
static void dllMultiTexCoord2fARB(GLenum texture, GLfloat s, GLfloat t)
|
|
{
|
|
assert(glw_state->inDrawBlock);
|
|
|
|
_handleDrawOverflow();
|
|
|
|
DWORD* push = &glw_state->drawArray[
|
|
glw_state->numVertices * glw_state->drawStride +
|
|
4 + (texture - GL_TEXTURE0_ARB) * 2];
|
|
|
|
*push++ = *((DWORD*)&s);
|
|
*push++ = *((DWORD*)&t);
|
|
}
|
|
|
|
static void dllActiveTextureARB(GLenum texture)
|
|
{
|
|
assert(GLW_MAX_TEXTURE_STAGES > texture - GL_TEXTURE0_ARB);
|
|
glw_state->serverTU = texture - GL_TEXTURE0_ARB;
|
|
}
|
|
|
|
static void dllClientActiveTextureARB(GLenum texture)
|
|
{
|
|
assert(GLW_MAX_TEXTURE_STAGES > texture - GL_TEXTURE0_ARB);
|
|
glw_state->clientTU = texture - GL_TEXTURE0_ARB;
|
|
}
|
|
|
|
|
|
/*
|
|
** QGL_Shutdown
|
|
**
|
|
** Unloads the specified DLL then nulls out all the proc pointers. This
|
|
** is only called during a hard shutdown of the OGL subsystem (e.g. vid_restart).
|
|
*/
|
|
void QGL_Shutdown( void )
|
|
{
|
|
VID_Printf( PRINT_ALL, "...shutting down QGL\n" );
|
|
|
|
qglAccum = NULL;
|
|
qglAlphaFunc = NULL;
|
|
qglAreTexturesResident = NULL;
|
|
qglArrayElement = NULL;
|
|
qglBegin = NULL;
|
|
qglBeginEXT = NULL;
|
|
qglBeginFrame = NULL;
|
|
qglBeginShadow = NULL;
|
|
qglBindTexture = NULL;
|
|
qglBitmap = NULL;
|
|
qglBlendFunc = NULL;
|
|
qglCallList = NULL;
|
|
qglCallLists = NULL;
|
|
qglClear = NULL;
|
|
qglClearAccum = NULL;
|
|
qglClearColor = NULL;
|
|
qglClearDepth = NULL;
|
|
qglClearIndex = NULL;
|
|
qglClearStencil = NULL;
|
|
qglClipPlane = NULL;
|
|
qglColor3b = NULL;
|
|
qglColor3bv = NULL;
|
|
qglColor3d = NULL;
|
|
qglColor3dv = NULL;
|
|
qglColor3f = NULL;
|
|
qglColor3fv = NULL;
|
|
qglColor3i = NULL;
|
|
qglColor3iv = NULL;
|
|
qglColor3s = NULL;
|
|
qglColor3sv = NULL;
|
|
qglColor3ub = NULL;
|
|
qglColor3ubv = NULL;
|
|
qglColor3ui = NULL;
|
|
qglColor3uiv = NULL;
|
|
qglColor3us = NULL;
|
|
qglColor3usv = NULL;
|
|
qglColor4b = NULL;
|
|
qglColor4bv = NULL;
|
|
qglColor4d = NULL;
|
|
qglColor4dv = NULL;
|
|
qglColor4f = NULL;
|
|
qglColor4fv = NULL;
|
|
qglColor4i = NULL;
|
|
qglColor4iv = NULL;
|
|
qglColor4s = NULL;
|
|
qglColor4sv = NULL;
|
|
qglColor4ub = NULL;
|
|
qglColor4ubv = NULL;
|
|
qglColor4ui = NULL;
|
|
qglColor4uiv = NULL;
|
|
qglColor4us = NULL;
|
|
qglColor4usv = NULL;
|
|
qglColorMask = NULL;
|
|
qglColorMaterial = NULL;
|
|
qglColorPointer = NULL;
|
|
qglCopyPixels = NULL;
|
|
qglCopyTexImage1D = NULL;
|
|
qglCopyTexImage2D = NULL;
|
|
qglCopyTexSubImage1D = NULL;
|
|
qglCopyTexSubImage2D = NULL;
|
|
qglCullFace = NULL;
|
|
qglDeleteLists = NULL;
|
|
qglDeleteTextures = NULL;
|
|
qglDepthFunc = NULL;
|
|
qglDepthMask = NULL;
|
|
qglDepthRange = NULL;
|
|
qglDisable = NULL;
|
|
qglDisableClientState = NULL;
|
|
qglDrawArrays = NULL;
|
|
qglDrawBuffer = NULL;
|
|
qglDrawElements = NULL;
|
|
qglDrawPixels = NULL;
|
|
qglEdgeFlag = NULL;
|
|
qglEdgeFlagPointer = NULL;
|
|
qglEdgeFlagv = NULL;
|
|
qglEnable = NULL;
|
|
qglEnableClientState = NULL;
|
|
qglEnd = NULL;
|
|
qglEndFrame = NULL;
|
|
qglEndShadow = NULL;
|
|
qglEndList = NULL;
|
|
qglEvalCoord1d = NULL;
|
|
qglEvalCoord1dv = NULL;
|
|
qglEvalCoord1f = NULL;
|
|
qglEvalCoord1fv = NULL;
|
|
qglEvalCoord2d = NULL;
|
|
qglEvalCoord2dv = NULL;
|
|
qglEvalCoord2f = NULL;
|
|
qglEvalCoord2fv = NULL;
|
|
qglEvalMesh1 = NULL;
|
|
qglEvalMesh2 = NULL;
|
|
qglEvalPoint1 = NULL;
|
|
qglEvalPoint2 = NULL;
|
|
qglFeedbackBuffer = NULL;
|
|
qglFinish = NULL;
|
|
qglFlush = NULL;
|
|
qglFlushShadow = NULL;
|
|
qglFogf = NULL;
|
|
qglFogfv = NULL;
|
|
qglFogi = NULL;
|
|
qglFogiv = NULL;
|
|
qglFrontFace = NULL;
|
|
qglFrustum = NULL;
|
|
qglGenLists = NULL;
|
|
qglGenTextures = NULL;
|
|
qglGetBooleanv = NULL;
|
|
qglGetClipPlane = NULL;
|
|
qglGetDoublev = NULL;
|
|
qglGetError = NULL;
|
|
qglGetFloatv = NULL;
|
|
qglGetIntegerv = NULL;
|
|
qglGetLightfv = NULL;
|
|
qglGetLightiv = NULL;
|
|
qglGetMapdv = NULL;
|
|
qglGetMapfv = NULL;
|
|
qglGetMapiv = NULL;
|
|
qglGetMaterialfv = NULL;
|
|
qglGetMaterialiv = NULL;
|
|
qglGetPixelMapfv = NULL;
|
|
qglGetPixelMapuiv = NULL;
|
|
qglGetPixelMapusv = NULL;
|
|
qglGetPointerv = NULL;
|
|
qglGetPolygonStipple = NULL;
|
|
qglGetString = NULL;
|
|
qglGetTexEnvfv = NULL;
|
|
qglGetTexEnviv = NULL;
|
|
qglGetTexGendv = NULL;
|
|
qglGetTexGenfv = NULL;
|
|
qglGetTexGeniv = NULL;
|
|
qglGetTexImage = NULL;
|
|
qglGetTexLevelParameterfv = NULL;
|
|
qglGetTexLevelParameteriv = NULL;
|
|
qglGetTexParameterfv = NULL;
|
|
qglGetTexParameteriv = NULL;
|
|
qglHint = NULL;
|
|
qglIndexedTriToStrip = NULL;
|
|
qglIndexMask = NULL;
|
|
qglIndexPointer = NULL;
|
|
qglIndexd = NULL;
|
|
qglIndexdv = NULL;
|
|
qglIndexf = NULL;
|
|
qglIndexfv = NULL;
|
|
qglIndexi = NULL;
|
|
qglIndexiv = NULL;
|
|
qglIndexs = NULL;
|
|
qglIndexsv = NULL;
|
|
qglIndexub = NULL;
|
|
qglIndexubv = NULL;
|
|
qglInitNames = NULL;
|
|
qglInterleavedArrays = NULL;
|
|
qglIsEnabled = NULL;
|
|
qglIsList = NULL;
|
|
qglIsTexture = NULL;
|
|
qglLightModelf = NULL;
|
|
qglLightModelfv = NULL;
|
|
qglLightModeli = NULL;
|
|
qglLightModeliv = NULL;
|
|
qglLightf = NULL;
|
|
qglLightfv = NULL;
|
|
qglLighti = NULL;
|
|
qglLightiv = NULL;
|
|
qglLineStipple = NULL;
|
|
qglLineWidth = NULL;
|
|
qglListBase = NULL;
|
|
qglLoadIdentity = NULL;
|
|
qglLoadMatrixd = NULL;
|
|
qglLoadMatrixf = NULL;
|
|
qglLoadName = NULL;
|
|
qglLogicOp = NULL;
|
|
qglMap1d = NULL;
|
|
qglMap1f = NULL;
|
|
qglMap2d = NULL;
|
|
qglMap2f = NULL;
|
|
qglMapGrid1d = NULL;
|
|
qglMapGrid1f = NULL;
|
|
qglMapGrid2d = NULL;
|
|
qglMapGrid2f = NULL;
|
|
qglMaterialf = NULL;
|
|
qglMaterialfv = NULL;
|
|
qglMateriali = NULL;
|
|
qglMaterialiv = NULL;
|
|
qglMatrixMode = NULL;
|
|
qglMultMatrixd = NULL;
|
|
qglMultMatrixf = NULL;
|
|
qglNewList = NULL;
|
|
qglNormal3b = NULL;
|
|
qglNormal3bv = NULL;
|
|
qglNormal3d = NULL;
|
|
qglNormal3dv = NULL;
|
|
qglNormal3f = NULL;
|
|
qglNormal3fv = NULL;
|
|
qglNormal3i = NULL;
|
|
qglNormal3iv = NULL;
|
|
qglNormal3s = NULL;
|
|
qglNormal3sv = NULL;
|
|
qglNormalPointer = NULL;
|
|
qglOrtho = NULL;
|
|
qglPassThrough = NULL;
|
|
qglPixelMapfv = NULL;
|
|
qglPixelMapuiv = NULL;
|
|
qglPixelMapusv = NULL;
|
|
qglPixelStoref = NULL;
|
|
qglPixelStorei = NULL;
|
|
qglPixelTransferf = NULL;
|
|
qglPixelTransferi = NULL;
|
|
qglPixelZoom = NULL;
|
|
qglPointSize = NULL;
|
|
qglPolygonMode = NULL;
|
|
qglPolygonOffset = NULL;
|
|
qglPolygonStipple = NULL;
|
|
qglPopAttrib = NULL;
|
|
qglPopClientAttrib = NULL;
|
|
qglPopMatrix = NULL;
|
|
qglPopName = NULL;
|
|
qglPrioritizeTextures = NULL;
|
|
qglPushAttrib = NULL;
|
|
qglPushClientAttrib = NULL;
|
|
qglPushMatrix = NULL;
|
|
qglPushName = NULL;
|
|
qglRasterPos2d = NULL;
|
|
qglRasterPos2dv = NULL;
|
|
qglRasterPos2f = NULL;
|
|
qglRasterPos2fv = NULL;
|
|
qglRasterPos2i = NULL;
|
|
qglRasterPos2iv = NULL;
|
|
qglRasterPos2s = NULL;
|
|
qglRasterPos2sv = NULL;
|
|
qglRasterPos3d = NULL;
|
|
qglRasterPos3dv = NULL;
|
|
qglRasterPos3f = NULL;
|
|
qglRasterPos3fv = NULL;
|
|
qglRasterPos3i = NULL;
|
|
qglRasterPos3iv = NULL;
|
|
qglRasterPos3s = NULL;
|
|
qglRasterPos3sv = NULL;
|
|
qglRasterPos4d = NULL;
|
|
qglRasterPos4dv = NULL;
|
|
qglRasterPos4f = NULL;
|
|
qglRasterPos4fv = NULL;
|
|
qglRasterPos4i = NULL;
|
|
qglRasterPos4iv = NULL;
|
|
qglRasterPos4s = NULL;
|
|
qglRasterPos4sv = NULL;
|
|
qglReadBuffer = NULL;
|
|
qglReadPixels = NULL;
|
|
qglRectd = NULL;
|
|
qglRectdv = NULL;
|
|
qglRectf = NULL;
|
|
qglRectfv = NULL;
|
|
qglRecti = NULL;
|
|
qglRectiv = NULL;
|
|
qglRects = NULL;
|
|
qglRectsv = NULL;
|
|
qglRenderMode = NULL;
|
|
qglRotated = NULL;
|
|
qglRotatef = NULL;
|
|
qglScaled = NULL;
|
|
qglScalef = NULL;
|
|
qglScissor = NULL;
|
|
qglSelectBuffer = NULL;
|
|
qglShadeModel = NULL;
|
|
qglStencilFunc = NULL;
|
|
qglStencilMask = NULL;
|
|
qglStencilOp = NULL;
|
|
qglTexCoord1d = NULL;
|
|
qglTexCoord1dv = NULL;
|
|
qglTexCoord1f = NULL;
|
|
qglTexCoord1fv = NULL;
|
|
qglTexCoord1i = NULL;
|
|
qglTexCoord1iv = NULL;
|
|
qglTexCoord1s = NULL;
|
|
qglTexCoord1sv = NULL;
|
|
qglTexCoord2d = NULL;
|
|
qglTexCoord2dv = NULL;
|
|
qglTexCoord2f = NULL;
|
|
qglTexCoord2fv = NULL;
|
|
qglTexCoord2i = NULL;
|
|
qglTexCoord2iv = NULL;
|
|
qglTexCoord2s = NULL;
|
|
qglTexCoord2sv = NULL;
|
|
qglTexCoord3d = NULL;
|
|
qglTexCoord3dv = NULL;
|
|
qglTexCoord3f = NULL;
|
|
qglTexCoord3fv = NULL;
|
|
qglTexCoord3i = NULL;
|
|
qglTexCoord3iv = NULL;
|
|
qglTexCoord3s = NULL;
|
|
qglTexCoord3sv = NULL;
|
|
qglTexCoord4d = NULL;
|
|
qglTexCoord4dv = NULL;
|
|
qglTexCoord4f = NULL;
|
|
qglTexCoord4fv = NULL;
|
|
qglTexCoord4i = NULL;
|
|
qglTexCoord4iv = NULL;
|
|
qglTexCoord4s = NULL;
|
|
qglTexCoord4sv = NULL;
|
|
qglTexCoordPointer = NULL;
|
|
qglTexEnvf = NULL;
|
|
qglTexEnvfv = NULL;
|
|
qglTexEnvi = NULL;
|
|
qglTexEnviv = NULL;
|
|
qglTexGend = NULL;
|
|
qglTexGendv = NULL;
|
|
qglTexGenf = NULL;
|
|
qglTexGenfv = NULL;
|
|
qglTexGeni = NULL;
|
|
qglTexGeniv = NULL;
|
|
qglTexImage1D = NULL;
|
|
qglTexImage2D = NULL;
|
|
qglTexImage2DEXT = NULL;
|
|
qglTexParameterf = NULL;
|
|
qglTexParameterfv = NULL;
|
|
qglTexParameteri = NULL;
|
|
qglTexParameteriv = NULL;
|
|
qglTexSubImage1D = NULL;
|
|
qglTexSubImage2D = NULL;
|
|
qglTranslated = NULL;
|
|
qglTranslatef = NULL;
|
|
qglVertex2d = NULL;
|
|
qglVertex2dv = NULL;
|
|
qglVertex2f = NULL;
|
|
qglVertex2fv = NULL;
|
|
qglVertex2i = NULL;
|
|
qglVertex2iv = NULL;
|
|
qglVertex2s = NULL;
|
|
qglVertex2sv = NULL;
|
|
qglVertex3d = NULL;
|
|
qglVertex3dv = NULL;
|
|
qglVertex3f = NULL;
|
|
qglVertex3fv = NULL;
|
|
qglVertex3i = NULL;
|
|
qglVertex3iv = NULL;
|
|
qglVertex3s = NULL;
|
|
qglVertex3sv = NULL;
|
|
qglVertex4d = NULL;
|
|
qglVertex4dv = NULL;
|
|
qglVertex4f = NULL;
|
|
qglVertex4fv = NULL;
|
|
qglVertex4i = NULL;
|
|
qglVertex4iv = NULL;
|
|
qglVertex4s = NULL;
|
|
qglVertex4sv = NULL;
|
|
qglVertexPointer = NULL;
|
|
qglViewport = NULL;
|
|
|
|
qglActiveTextureARB = NULL;
|
|
qglClientActiveTextureARB = NULL;
|
|
qglMultiTexCoord2fARB = NULL;
|
|
}
|
|
|
|
/*
|
|
** QGL_Init
|
|
**
|
|
** This is responsible for binding our qgl function pointers to
|
|
** the appropriate GL stuff. In Windows this means doing a
|
|
** LoadLibrary and a bunch of calls to GetProcAddress. On other
|
|
** operating systems we need to do the right thing, whatever that
|
|
** might be.
|
|
*/
|
|
qboolean QGL_Init( const char *dllname )
|
|
{
|
|
qglAccum = dllAccum;
|
|
qglAlphaFunc = dllAlphaFunc;
|
|
qglAreTexturesResident = dllAreTexturesResident;
|
|
qglArrayElement = dllArrayElement;
|
|
qglBegin = dllBegin;
|
|
qglBeginEXT = dllBeginEXT;
|
|
qglBeginFrame = dllBeginFrame;
|
|
qglBeginShadow = dllBeginShadow;
|
|
qglBindTexture = dllBindTexture;
|
|
qglBitmap = dllBitmap;
|
|
qglBlendFunc = dllBlendFunc;
|
|
qglCallList = dllCallList;
|
|
qglCallLists = dllCallLists;
|
|
qglClear = dllClear;
|
|
qglClearAccum = dllClearAccum;
|
|
qglClearColor = dllClearColor;
|
|
qglClearDepth = dllClearDepth;
|
|
qglClearIndex = dllClearIndex;
|
|
qglClearStencil = dllClearStencil;
|
|
qglClipPlane = dllClipPlane;
|
|
qglColor3b = dllColor3b;
|
|
qglColor3bv = dllColor3bv;
|
|
qglColor3d = dllColor3d;
|
|
qglColor3dv = dllColor3dv;
|
|
qglColor3f = dllColor3f;
|
|
qglColor3fv = dllColor3fv;
|
|
qglColor3i = dllColor3i;
|
|
qglColor3iv = dllColor3iv;
|
|
qglColor3s = dllColor3s;
|
|
qglColor3sv = dllColor3sv;
|
|
qglColor3ub = dllColor3ub;
|
|
qglColor3ubv = dllColor3ubv;
|
|
qglColor3ui = dllColor3ui;
|
|
qglColor3uiv = dllColor3uiv;
|
|
qglColor3us = dllColor3us;
|
|
qglColor3usv = dllColor3usv;
|
|
qglColor4b = dllColor4b;
|
|
qglColor4bv = dllColor4bv;
|
|
qglColor4d = dllColor4d;
|
|
qglColor4dv = dllColor4dv;
|
|
qglColor4f = dllColor4f;
|
|
qglColor4fv = dllColor4fv;
|
|
qglColor4i = dllColor4i;
|
|
qglColor4iv = dllColor4iv;
|
|
qglColor4s = dllColor4s;
|
|
qglColor4sv = dllColor4sv;
|
|
qglColor4ub = dllColor4ub;
|
|
qglColor4ubv = dllColor4ubv;
|
|
qglColor4ui = dllColor4ui;
|
|
qglColor4uiv = dllColor4uiv;
|
|
qglColor4us = dllColor4us;
|
|
qglColor4usv = dllColor4usv;
|
|
qglColorMask = dllColorMask;
|
|
qglColorMaterial = dllColorMaterial;
|
|
qglColorPointer = dllColorPointer;
|
|
qglCopyPixels = dllCopyPixels;
|
|
qglCopyTexImage1D = dllCopyTexImage1D;
|
|
qglCopyTexImage2D = dllCopyTexImage2D;
|
|
qglCopyTexSubImage1D = dllCopyTexSubImage1D;
|
|
qglCopyTexSubImage2D = dllCopyTexSubImage2D;
|
|
qglCullFace = dllCullFace;
|
|
qglDeleteLists = dllDeleteLists;
|
|
qglDeleteTextures = dllDeleteTextures;
|
|
qglDepthFunc = dllDepthFunc;
|
|
qglDepthMask = dllDepthMask;
|
|
qglDepthRange = dllDepthRange;
|
|
qglDisable = dllDisable;
|
|
qglDisableClientState = dllDisableClientState;
|
|
qglDrawArrays = dllDrawArrays;
|
|
qglDrawBuffer = dllDrawBuffer;
|
|
qglDrawElements = dllDrawElements;
|
|
qglDrawPixels = dllDrawPixels;
|
|
qglEdgeFlag = dllEdgeFlag;
|
|
qglEdgeFlagPointer = dllEdgeFlagPointer;
|
|
qglEdgeFlagv = dllEdgeFlagv;
|
|
qglEnable = dllEnable ;
|
|
qglEnableClientState = dllEnableClientState ;
|
|
qglEnd = dllEnd ;
|
|
qglEndFrame = dllEndFrame ;
|
|
qglEndShadow = dllEndShadow ;
|
|
qglEndList = dllEndList ;
|
|
qglEvalCoord1d = dllEvalCoord1d ;
|
|
qglEvalCoord1dv = dllEvalCoord1dv ;
|
|
qglEvalCoord1f = dllEvalCoord1f ;
|
|
qglEvalCoord1fv = dllEvalCoord1fv ;
|
|
qglEvalCoord2d = dllEvalCoord2d ;
|
|
qglEvalCoord2dv = dllEvalCoord2dv ;
|
|
qglEvalCoord2f = dllEvalCoord2f ;
|
|
qglEvalCoord2fv = dllEvalCoord2fv ;
|
|
qglEvalMesh1 = dllEvalMesh1 ;
|
|
qglEvalMesh2 = dllEvalMesh2 ;
|
|
qglEvalPoint1 = dllEvalPoint1 ;
|
|
qglEvalPoint2 = dllEvalPoint2 ;
|
|
qglFeedbackBuffer = dllFeedbackBuffer ;
|
|
qglFinish = dllFinish ;
|
|
qglFlush = dllFlush ;
|
|
qglFlushShadow = dllFlushShadow ;
|
|
qglFogf = dllFogf ;
|
|
qglFogfv = dllFogfv ;
|
|
qglFogi = dllFogi ;
|
|
qglFogiv = dllFogiv ;
|
|
qglFrontFace = dllFrontFace ;
|
|
qglFrustum = dllFrustum ;
|
|
qglGenLists = dllGenLists ;
|
|
qglGenTextures = dllGenTextures ;
|
|
qglGetBooleanv = dllGetBooleanv ;
|
|
qglGetClipPlane = dllGetClipPlane ;
|
|
qglGetDoublev = dllGetDoublev ;
|
|
qglGetError = dllGetError ;
|
|
qglGetFloatv = dllGetFloatv ;
|
|
qglGetIntegerv = dllGetIntegerv ;
|
|
qglGetLightfv = dllGetLightfv ;
|
|
qglGetLightiv = dllGetLightiv ;
|
|
qglGetMapdv = dllGetMapdv ;
|
|
qglGetMapfv = dllGetMapfv ;
|
|
qglGetMapiv = dllGetMapiv ;
|
|
qglGetMaterialfv = dllGetMaterialfv ;
|
|
qglGetMaterialiv = dllGetMaterialiv ;
|
|
qglGetPixelMapfv = dllGetPixelMapfv ;
|
|
qglGetPixelMapuiv = dllGetPixelMapuiv ;
|
|
qglGetPixelMapusv = dllGetPixelMapusv ;
|
|
qglGetPointerv = dllGetPointerv ;
|
|
qglGetPolygonStipple = dllGetPolygonStipple ;
|
|
qglGetString = dllGetString ;
|
|
qglGetTexEnvfv = dllGetTexEnvfv ;
|
|
qglGetTexEnviv = dllGetTexEnviv ;
|
|
qglGetTexGendv = dllGetTexGendv ;
|
|
qglGetTexGenfv = dllGetTexGenfv ;
|
|
qglGetTexGeniv = dllGetTexGeniv ;
|
|
qglGetTexImage = dllGetTexImage ;
|
|
// qglGetTexLevelParameterfv = dllGetTexLevelParameterfv ;
|
|
// qglGetTexLevelParameteriv = dllGetTexLevelParameteriv ;
|
|
qglGetTexParameterfv = dllGetTexParameterfv ;
|
|
qglGetTexParameteriv = dllGetTexParameteriv ;
|
|
qglHint = dllHint ;
|
|
qglIndexedTriToStrip = dllIndexedTriToStrip ;
|
|
qglIndexMask = dllIndexMask ;
|
|
qglIndexPointer = dllIndexPointer ;
|
|
qglIndexd = dllIndexd ;
|
|
qglIndexdv = dllIndexdv ;
|
|
qglIndexf = dllIndexf ;
|
|
qglIndexfv = dllIndexfv ;
|
|
qglIndexi = dllIndexi ;
|
|
qglIndexiv = dllIndexiv ;
|
|
qglIndexs = dllIndexs ;
|
|
qglIndexsv = dllIndexsv ;
|
|
qglIndexub = dllIndexub ;
|
|
qglIndexubv = dllIndexubv ;
|
|
qglInitNames = dllInitNames ;
|
|
qglInterleavedArrays = dllInterleavedArrays ;
|
|
qglIsEnabled = dllIsEnabled ;
|
|
qglIsList = dllIsList ;
|
|
qglIsTexture = dllIsTexture ;
|
|
qglLightModelf = dllLightModelf ;
|
|
qglLightModelfv = dllLightModelfv ;
|
|
qglLightModeli = dllLightModeli ;
|
|
qglLightModeliv = dllLightModeliv ;
|
|
qglLightf = dllLightf ;
|
|
qglLightfv = dllLightfv ;
|
|
qglLighti = dllLighti ;
|
|
qglLightiv = dllLightiv ;
|
|
qglLineStipple = dllLineStipple ;
|
|
qglLineWidth = dllLineWidth ;
|
|
qglListBase = dllListBase ;
|
|
qglLoadIdentity = dllLoadIdentity ;
|
|
qglLoadMatrixd = dllLoadMatrixd ;
|
|
qglLoadMatrixf = dllLoadMatrixf ;
|
|
qglLoadName = dllLoadName ;
|
|
qglLogicOp = dllLogicOp ;
|
|
qglMap1d = dllMap1d ;
|
|
qglMap1f = dllMap1f ;
|
|
qglMap2d = dllMap2d ;
|
|
qglMap2f = dllMap2f ;
|
|
qglMapGrid1d = dllMapGrid1d ;
|
|
qglMapGrid1f = dllMapGrid1f ;
|
|
qglMapGrid2d = dllMapGrid2d ;
|
|
qglMapGrid2f = dllMapGrid2f ;
|
|
qglMaterialf = dllMaterialf ;
|
|
qglMaterialfv = dllMaterialfv ;
|
|
qglMateriali = dllMateriali ;
|
|
qglMaterialiv = dllMaterialiv ;
|
|
qglMatrixMode = dllMatrixMode ;
|
|
qglMultMatrixd = dllMultMatrixd ;
|
|
qglMultMatrixf = dllMultMatrixf ;
|
|
qglNewList = dllNewList ;
|
|
qglNormal3b = dllNormal3b ;
|
|
qglNormal3bv = dllNormal3bv ;
|
|
qglNormal3d = dllNormal3d ;
|
|
qglNormal3dv = dllNormal3dv ;
|
|
qglNormal3f = dllNormal3f ;
|
|
qglNormal3fv = dllNormal3fv ;
|
|
qglNormal3i = dllNormal3i ;
|
|
qglNormal3iv = dllNormal3iv ;
|
|
qglNormal3s = dllNormal3s ;
|
|
qglNormal3sv = dllNormal3sv ;
|
|
qglNormalPointer = dllNormalPointer ;
|
|
qglOrtho = dllOrtho ;
|
|
qglPassThrough = dllPassThrough ;
|
|
qglPixelMapfv = dllPixelMapfv ;
|
|
qglPixelMapuiv = dllPixelMapuiv ;
|
|
qglPixelMapusv = dllPixelMapusv ;
|
|
qglPixelStoref = dllPixelStoref ;
|
|
qglPixelStorei = dllPixelStorei ;
|
|
qglPixelTransferf = dllPixelTransferf ;
|
|
qglPixelTransferi = dllPixelTransferi ;
|
|
qglPixelZoom = dllPixelZoom ;
|
|
qglPointSize = dllPointSize ;
|
|
qglPolygonMode = dllPolygonMode ;
|
|
qglPolygonOffset = dllPolygonOffset ;
|
|
qglPolygonStipple = dllPolygonStipple ;
|
|
qglPopAttrib = dllPopAttrib ;
|
|
qglPopClientAttrib = dllPopClientAttrib ;
|
|
qglPopMatrix = dllPopMatrix ;
|
|
qglPopName = dllPopName ;
|
|
qglPrioritizeTextures = dllPrioritizeTextures ;
|
|
qglPushAttrib = dllPushAttrib ;
|
|
qglPushClientAttrib = dllPushClientAttrib ;
|
|
qglPushMatrix = dllPushMatrix ;
|
|
qglPushName = dllPushName ;
|
|
qglRasterPos2d = dllRasterPos2d ;
|
|
qglRasterPos2dv = dllRasterPos2dv ;
|
|
qglRasterPos2f = dllRasterPos2f ;
|
|
qglRasterPos2fv = dllRasterPos2fv ;
|
|
qglRasterPos2i = dllRasterPos2i ;
|
|
qglRasterPos2iv = dllRasterPos2iv ;
|
|
qglRasterPos2s = dllRasterPos2s ;
|
|
qglRasterPos2sv = dllRasterPos2sv ;
|
|
qglRasterPos3d = dllRasterPos3d ;
|
|
qglRasterPos3dv = dllRasterPos3dv ;
|
|
qglRasterPos3f = dllRasterPos3f ;
|
|
qglRasterPos3fv = dllRasterPos3fv ;
|
|
qglRasterPos3i = dllRasterPos3i ;
|
|
qglRasterPos3iv = dllRasterPos3iv ;
|
|
qglRasterPos3s = dllRasterPos3s ;
|
|
qglRasterPos3sv = dllRasterPos3sv ;
|
|
qglRasterPos4d = dllRasterPos4d ;
|
|
qglRasterPos4dv = dllRasterPos4dv ;
|
|
qglRasterPos4f = dllRasterPos4f ;
|
|
qglRasterPos4fv = dllRasterPos4fv ;
|
|
qglRasterPos4i = dllRasterPos4i ;
|
|
qglRasterPos4iv = dllRasterPos4iv ;
|
|
qglRasterPos4s = dllRasterPos4s ;
|
|
qglRasterPos4sv = dllRasterPos4sv ;
|
|
qglReadBuffer = dllReadBuffer ;
|
|
qglReadPixels = dllReadPixels ;
|
|
qglCopyBackBufferToTexEXT = dllCopyBackBufferToTexEXT ;
|
|
qglCopyBackBufferToTex = dllCopyBackBufferToTex ;
|
|
qglRectd = dllRectd ;
|
|
qglRectdv = dllRectdv ;
|
|
qglRectf = dllRectf ;
|
|
qglRectfv = dllRectfv ;
|
|
qglRecti = dllRecti ;
|
|
qglRectiv = dllRectiv ;
|
|
qglRects = dllRects ;
|
|
qglRectsv = dllRectsv ;
|
|
qglRenderMode = dllRenderMode ;
|
|
qglRotated = dllRotated ;
|
|
qglRotatef = dllRotatef ;
|
|
qglScaled = dllScaled ;
|
|
qglScalef = dllScalef ;
|
|
qglScissor = dllScissor ;
|
|
qglSelectBuffer = dllSelectBuffer ;
|
|
qglShadeModel = dllShadeModel ;
|
|
qglStencilFunc = dllStencilFunc ;
|
|
qglStencilMask = dllStencilMask ;
|
|
qglStencilOp = dllStencilOp ;
|
|
qglTexCoord1d = dllTexCoord1d ;
|
|
qglTexCoord1dv = dllTexCoord1dv ;
|
|
qglTexCoord1f = dllTexCoord1f ;
|
|
qglTexCoord1fv = dllTexCoord1fv ;
|
|
qglTexCoord1i = dllTexCoord1i ;
|
|
qglTexCoord1iv = dllTexCoord1iv ;
|
|
qglTexCoord1s = dllTexCoord1s ;
|
|
qglTexCoord1sv = dllTexCoord1sv ;
|
|
qglTexCoord2d = dllTexCoord2d ;
|
|
qglTexCoord2dv = dllTexCoord2dv ;
|
|
qglTexCoord2f = dllTexCoord2f ;
|
|
qglTexCoord2fv = dllTexCoord2fv ;
|
|
qglTexCoord2i = dllTexCoord2i ;
|
|
qglTexCoord2iv = dllTexCoord2iv ;
|
|
qglTexCoord2s = dllTexCoord2s ;
|
|
qglTexCoord2sv = dllTexCoord2sv ;
|
|
qglTexCoord3d = dllTexCoord3d ;
|
|
qglTexCoord3dv = dllTexCoord3dv ;
|
|
qglTexCoord3f = dllTexCoord3f ;
|
|
qglTexCoord3fv = dllTexCoord3fv ;
|
|
qglTexCoord3i = dllTexCoord3i ;
|
|
qglTexCoord3iv = dllTexCoord3iv ;
|
|
qglTexCoord3s = dllTexCoord3s ;
|
|
qglTexCoord3sv = dllTexCoord3sv ;
|
|
qglTexCoord4d = dllTexCoord4d ;
|
|
qglTexCoord4dv = dllTexCoord4dv ;
|
|
qglTexCoord4f = dllTexCoord4f ;
|
|
qglTexCoord4fv = dllTexCoord4fv ;
|
|
qglTexCoord4i = dllTexCoord4i ;
|
|
qglTexCoord4iv = dllTexCoord4iv ;
|
|
qglTexCoord4s = dllTexCoord4s ;
|
|
qglTexCoord4sv = dllTexCoord4sv ;
|
|
qglTexCoordPointer = dllTexCoordPointer ;
|
|
qglTexEnvf = dllTexEnvf ;
|
|
qglTexEnvfv = dllTexEnvfv ;
|
|
qglTexEnvi = dllTexEnvi ;
|
|
qglTexEnviv = dllTexEnviv ;
|
|
qglTexGend = dllTexGend ;
|
|
qglTexGendv = dllTexGendv ;
|
|
qglTexGenf = dllTexGenf ;
|
|
qglTexGenfv = dllTexGenfv ;
|
|
qglTexGeni = dllTexGeni ;
|
|
qglTexGeniv = dllTexGeniv ;
|
|
qglTexImage1D = dllTexImage1D ;
|
|
qglTexImage2D = dllTexImage2D ;
|
|
qglTexImage2DEXT = dllTexImage2DEXT ;
|
|
qglTexParameterf = dllTexParameterf ;
|
|
qglTexParameterfv = dllTexParameterfv ;
|
|
qglTexParameteri = dllTexParameteri ;
|
|
qglTexParameteriv = dllTexParameteriv ;
|
|
qglTexSubImage1D = dllTexSubImage1D ;
|
|
qglTexSubImage2D = dllTexSubImage2D ;
|
|
qglTranslated = dllTranslated ;
|
|
qglTranslatef = dllTranslatef ;
|
|
qglVertex2d = dllVertex2d ;
|
|
qglVertex2dv = dllVertex2dv ;
|
|
qglVertex2f = dllVertex2f ;
|
|
qglVertex2fv = dllVertex2fv ;
|
|
qglVertex2i = dllVertex2i ;
|
|
qglVertex2iv = dllVertex2iv ;
|
|
qglVertex2s = dllVertex2s ;
|
|
qglVertex2sv = dllVertex2sv ;
|
|
qglVertex3d = dllVertex3d ;
|
|
qglVertex3dv = dllVertex3dv ;
|
|
qglVertex3f = dllVertex3f ;
|
|
qglVertex3fv = dllVertex3fv ;
|
|
qglVertex3i = dllVertex3i ;
|
|
qglVertex3iv = dllVertex3iv ;
|
|
qglVertex3s = dllVertex3s ;
|
|
qglVertex3sv = dllVertex3sv ;
|
|
qglVertex4d = dllVertex4d ;
|
|
qglVertex4dv = dllVertex4dv ;
|
|
qglVertex4f = dllVertex4f ;
|
|
qglVertex4fv = dllVertex4fv ;
|
|
qglVertex4i = dllVertex4i ;
|
|
qglVertex4iv = dllVertex4iv ;
|
|
qglVertex4s = dllVertex4s ;
|
|
qglVertex4sv = dllVertex4sv ;
|
|
qglVertexPointer = dllVertexPointer ;
|
|
qglViewport = dllViewport ;
|
|
|
|
qglActiveTextureARB = dllActiveTextureARB ;
|
|
qglClientActiveTextureARB = dllClientActiveTextureARB ;
|
|
qglMultiTexCoord2fARB = dllMultiTexCoord2fARB ;
|
|
|
|
return qtrue;
|
|
}
|
|
|
|
void QGL_EnableLogging( qboolean enable )
|
|
{
|
|
}
|
|
|
|
// Extra functions bound to d3d_ commands for controlling crazy D3D performance things
|
|
#ifndef FINAL_BUILD
|
|
|
|
// D3D_AutoPerfData controls automatic display of performance information:
|
|
// framerate, push buffer data, etc... Usage:
|
|
// d3d_autoperf - Toggle on and off
|
|
// d3d_autoperf n - Set display frequency in ms (default 5000)
|
|
static void D3D_AutoPerfData_f( void )
|
|
{
|
|
static DWORD sdwInterval = 5000;
|
|
static bool sbEnabled = false;
|
|
|
|
int numArgs = Cmd_Argc();
|
|
|
|
if (numArgs > 2)
|
|
{
|
|
Com_Printf("D3D_AutoPerfData_f: Too many arguments.\n");
|
|
}
|
|
else if (numArgs <= 1)
|
|
{
|
|
sbEnabled = !sbEnabled;
|
|
D3DPERF_SetShowFrameRateInterval(sbEnabled ? sdwInterval : 0);
|
|
}
|
|
else // numArgs == 2 -> Exactly one real argument
|
|
{
|
|
int new_interval = atoi(Cmd_Argv(1));
|
|
|
|
if (!new_interval)
|
|
{
|
|
// Fancy way to turn it off, don't change stored interval
|
|
sbEnabled = false;
|
|
}
|
|
else
|
|
{
|
|
// Force it on
|
|
sdwInterval = new_interval;
|
|
sbEnabled = true;
|
|
}
|
|
D3DPERF_SetShowFrameRateInterval(sbEnabled ? sdwInterval : 0);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
extern void GLimp_SetGamma(float);
|
|
|
|
|
|
static void _createWindow(int width, int height, int colorbits, qboolean cdsFullscreen)
|
|
{
|
|
glConfig.colorBits = colorbits;
|
|
|
|
if ( r_depthbits->integer == 0 ) {
|
|
if ( colorbits > 16 ) {
|
|
glConfig.depthBits = 24;
|
|
} else {
|
|
glConfig.depthBits = 16;
|
|
}
|
|
} else {
|
|
glConfig.depthBits = r_depthbits->integer;
|
|
}
|
|
|
|
glConfig.stencilBits = r_stencilbits->integer;
|
|
if ( glConfig.depthBits < 24 )
|
|
{
|
|
glConfig.stencilBits = 0;
|
|
}
|
|
|
|
glConfig.displayFrequency = 75;
|
|
glConfig.stereoEnabled = qfalse;
|
|
|
|
// VVFIXME : This is surely wrong.
|
|
glConfig.vidHeight = height;
|
|
glConfig.vidWidth = width;
|
|
|
|
}
|
|
|
|
enum VideoModes
|
|
{
|
|
VM_480i = 0,
|
|
VM_480p,
|
|
VM_720p,
|
|
VM_1080i
|
|
};
|
|
|
|
|
|
void GLW_Init(int width, int height, int colorbits, qboolean cdsFullscreen)
|
|
{
|
|
glw_state = new glwstate_t;
|
|
int mode = VM_480i;
|
|
|
|
glw_state->isWidescreen = false;
|
|
if( XGetVideoFlags() & XC_VIDEO_FLAGS_WIDESCREEN )
|
|
{
|
|
glw_state->isWidescreen = true;
|
|
|
|
if( XGetVideoFlags() & XC_VIDEO_FLAGS_HDTV_480p )
|
|
{
|
|
width = 720;
|
|
height = 480;
|
|
mode = VM_480p;
|
|
}
|
|
|
|
/*if( XGetVideoFlags() & XC_VIDEO_FLAGS_HDTV_720p )
|
|
{
|
|
width = 1280;
|
|
height = 720;
|
|
mode = VM_720p;
|
|
}
|
|
|
|
if( XGetVideoFlags() & XC_VIDEO_FLAGS_HDTV_1080i )
|
|
{
|
|
width = 1920;
|
|
height = 1080;
|
|
mode = VM_1080i;
|
|
}*/
|
|
}
|
|
|
|
_createWindow(width, height, colorbits, cdsFullscreen);
|
|
|
|
glw_state->matrixMode = glwstate_t::MatrixMode_Model;
|
|
glw_state->inDrawBlock = false;
|
|
|
|
glw_state->serverTU = 0;
|
|
glw_state->clientTU = 0;
|
|
|
|
glw_state->colorArrayState = false;
|
|
glw_state->vertexArrayState = false;
|
|
glw_state->normalArrayState = false;
|
|
|
|
glw_state->cullEnable = true;
|
|
glw_state->cullMode = D3DCULL_CCW;
|
|
|
|
glw_state->scissorEnable = false;
|
|
glw_state->scissorBox.x1 = 0;
|
|
glw_state->scissorBox.y1 = 0;
|
|
glw_state->scissorBox.x2 = glConfig.vidWidth;
|
|
glw_state->scissorBox.y2 = glConfig.vidHeight;
|
|
|
|
glw_state->shaderMask = 0;
|
|
|
|
glw_state->clearColor = D3DCOLOR_RGBA(255, 255, 255, 255);
|
|
glw_state->clearDepth = 1.f;
|
|
glw_state->clearStencil = 0;
|
|
|
|
glw_state->currentColor = D3DCOLOR_RGBA(255, 255, 255, 255);
|
|
|
|
glw_state->viewport.MinZ = 0.f;
|
|
glw_state->viewport.MaxZ = 1.f;
|
|
|
|
for (int t = 0; t < GLW_MAX_TEXTURE_STAGES; ++t)
|
|
{
|
|
glw_state->textureEnv[t] = D3DTOP_MODULATE;
|
|
glw_state->texCoordArrayState[t] = false;
|
|
glw_state->currentTexture[t] = 0;
|
|
glw_state->textureStageDirty[t] = false;
|
|
}
|
|
|
|
glw_state->textureBindNum = 1;
|
|
|
|
D3DPRESENT_PARAMETERS present;
|
|
present.BackBufferWidth = width;
|
|
present.BackBufferHeight = height;
|
|
present.BackBufferFormat = D3DFMT_A8R8G8B8;
|
|
present.BackBufferCount = 1;
|
|
present.MultiSampleType = D3DMULTISAMPLE_NONE;
|
|
present.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
|
present.hDeviceWindow = 0;
|
|
present.Windowed = FALSE;
|
|
present.EnableAutoDepthStencil = TRUE;
|
|
present.AutoDepthStencilFormat = D3DFMT_LIN_D24S8;
|
|
present.Flags = 0;
|
|
if( glw_state->isWidescreen )
|
|
{
|
|
present.Flags = D3DPRESENTFLAG_WIDESCREEN;
|
|
extern void CGCam_SetWidescreen(qboolean widescreen);
|
|
if(mode == VM_480p)
|
|
{
|
|
present.Flags |= D3DPRESENTFLAG_PROGRESSIVE;
|
|
}
|
|
//else if(mode == VM_720p)
|
|
//{
|
|
// present.Flags |= D3DPRESENTFLAG_PROGRESSIVE;
|
|
//}
|
|
//else if(mode == VM_1080i)
|
|
//{
|
|
// present.Flags |= D3DPRESENTFLAG_INTERLACED; // | D3DPRESENTFLAG_FIELD;
|
|
//}
|
|
|
|
|
|
present.Flags |= D3DPRESENTFLAG_WIDESCREEN;
|
|
CGCam_SetWidescreen(qtrue);
|
|
}
|
|
|
|
present.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
|
|
present.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
|
|
present.BufferSurfaces[0] = NULL;
|
|
present.BufferSurfaces[1] = NULL;
|
|
present.BufferSurfaces[2] = NULL;
|
|
present.DepthStencilSurface = NULL;
|
|
|
|
if (IDirect3D8::CreateDevice(D3DADAPTER_DEFAULT,
|
|
D3DDEVTYPE_HAL,
|
|
NULL,
|
|
D3DCREATE_HARDWARE_VERTEXPROCESSING,
|
|
&present,
|
|
&glw_state->device) != D3D_OK)
|
|
{
|
|
Com_Printf("Failed to create device. That's bad.\n");
|
|
}
|
|
// qglEnable(GL_VSYNC);
|
|
|
|
for (int m = 0; m < glwstate_t::Num_MatrixModes; ++m)
|
|
{
|
|
D3DXCreateMatrixStack(0, &glw_state->matrixStack[m]);
|
|
glw_state->matrixStack[m]->LoadIdentity();
|
|
glw_state->matricesDirty[m] = false;
|
|
}
|
|
|
|
// VVFIXME: Hack - turn off lighting
|
|
dllDisable(GL_LIGHTING);
|
|
|
|
// Set a material (for lighting)
|
|
memset( &glw_state->mtrl, 0, sizeof(D3DMATERIAL8) );
|
|
glw_state->mtrl.Diffuse.r = glw_state->mtrl.Ambient.r = 1.0f;
|
|
glw_state->mtrl.Diffuse.g = glw_state->mtrl.Ambient.g = 1.0f;
|
|
glw_state->mtrl.Diffuse.b = glw_state->mtrl.Ambient.b = 1.0f;
|
|
glw_state->mtrl.Diffuse.a = glw_state->mtrl.Ambient.a = 1.0f;
|
|
glw_state->device->SetMaterial( &glw_state->mtrl );
|
|
// Gamma hack
|
|
GLimp_SetGamma(1.3f);
|
|
|
|
// Set up our directional light (used for diffuse lighting)
|
|
memset(&glw_state->dirLight, 0, sizeof(D3DLIGHT8));
|
|
|
|
// Set up a white point light.
|
|
glw_state->dirLight.Type = D3DLIGHT_DIRECTIONAL;
|
|
glw_state->dirLight.Diffuse.r = 1.0f;
|
|
glw_state->dirLight.Diffuse.g = 1.0f;
|
|
glw_state->dirLight.Diffuse.b = 1.0f;
|
|
glw_state->dirLight.Direction.x = 1.0f;
|
|
glw_state->dirLight.Direction.y = 0.0f;
|
|
glw_state->dirLight.Direction.z = 0.0f;
|
|
|
|
// Don't attenuate.
|
|
glw_state->dirLight.Attenuation0 = 1.0f;
|
|
glw_state->dirLight.Range = 1000.0f;
|
|
|
|
//glw_state->drawArray = new DWORD[SHADER_MAX_VERTEXES * 12];
|
|
glw_state->drawArray = NULL;
|
|
|
|
#ifdef _XBOX
|
|
#ifdef VV_LIGHTING
|
|
// glw_state->flareEffect = new FlareEffect;
|
|
// glw_state->flareEffect->Initialize();
|
|
glw_state->lightEffects = new LightEffects;
|
|
#endif // VV_LIGHTING
|
|
HDREffect.Initialize();
|
|
#endif
|
|
|
|
#ifndef FINAL_BUILD
|
|
Cmd_AddCommand("d3d_autoperf", D3D_AutoPerfData_f);
|
|
#endif
|
|
}
|
|
|
|
void GLW_Shutdown(void)
|
|
{
|
|
#ifdef _XBOX
|
|
#ifdef VV_LIGHTING
|
|
delete glw_state->lightEffects;
|
|
#endif
|
|
#endif
|
|
|
|
for (int m = 0; m < glwstate_t::Num_MatrixModes; ++m)
|
|
{
|
|
glw_state->matrixStack[m]->Release();
|
|
}
|
|
|
|
glw_state->device->Release();
|
|
|
|
#ifdef _XBOX
|
|
// delete glw_state->flareEffect;
|
|
#endif
|
|
|
|
delete glw_state;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Compressed Screen Shot code for the save game system
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define CSS_IMAGE_HDR_SIZE 2048
|
|
#define CSS_IMAGE_WH 256
|
|
#define CSS_IMAGE_DATA_SIZE ((CSS_IMAGE_WH * CSS_IMAGE_WH) / 2 )
|
|
|
|
struct XprImageHeader
|
|
{
|
|
XPR_HEADER xpr; // Standard XPR struct
|
|
IDirect3DTexture8 txt; // Standard D3D texture struct
|
|
DWORD dwEndOfHeader; // 0xFFFFFFFF
|
|
};
|
|
|
|
struct XprImage
|
|
{
|
|
XprImageHeader hdr;
|
|
CHAR strPad[ CSS_IMAGE_HDR_SIZE - sizeof( XprImageHeader ) ];
|
|
BYTE pBits[ CSS_IMAGE_DATA_SIZE ]; // data bits
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// SaveCompressedScreenshot
|
|
// Saves a copy of the backbuffer to a .xbx file specified by filename
|
|
//-----------------------------------------------------------------------------
|
|
void SaveCompressedScreenshot(const char* filename)
|
|
{
|
|
LPDIRECT3DSURFACE8 screenShot = 0;
|
|
HRESULT res;
|
|
glw_state->device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &screenShot);
|
|
|
|
// Copy over the screen shot to the new image that is CSS_IMAGE_WH x CSS_IMAGE_WH
|
|
LPDIRECT3DSURFACE8 compressedSaveGameImage = 0;
|
|
glw_state->device->CreateImageSurface( CSS_IMAGE_WH, CSS_IMAGE_WH, D3DFMT_DXT1, &compressedSaveGameImage );
|
|
D3DXLoadSurfaceFromSurface( compressedSaveGameImage, NULL, NULL, screenShot, NULL, NULL, D3DX_DEFAULT, D3DCOLOR( 0 ) );
|
|
|
|
// Free the big screenshot 640x480x4?
|
|
if ( screenShot )
|
|
screenShot->Release();
|
|
|
|
// Write out the saveimage to the utility drive
|
|
res = XGWriteSurfaceOrTextureToXPR( compressedSaveGameImage, filename, TRUE );
|
|
|
|
// Free the compressed CSS_IMAGE_WH x CSS_IMAGE_WH image
|
|
if ( compressedSaveGameImage )
|
|
compressedSaveGameImage->Release();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// LoadCompressedScreenshot
|
|
// Loads a .xbx screenshot file and replaces the current texture
|
|
//-----------------------------------------------------------------------------
|
|
BOOL LoadCompressedScreenshot(const char* filename)
|
|
{
|
|
// get the current texture
|
|
glwstate_t::TextureInfo* info = _getCurrentTexture(glw_state->serverTU);
|
|
if (info == NULL) return FALSE;
|
|
|
|
// locals
|
|
LPDIRECT3DTEXTURE8 lpThumbTex;
|
|
XprImageHeader XprHeader;
|
|
DWORD dwBytesRead;
|
|
BOOL bSuccess;
|
|
|
|
// See if the image file for this saved game exists
|
|
HANDLE hFile = CreateFile( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING,0, NULL );
|
|
|
|
if( hFile == INVALID_HANDLE_VALUE )
|
|
{
|
|
DWORD err = GetLastError();
|
|
|
|
// If there was a problem, we might want to load the default image for TRC
|
|
// TCR C4-18 Saved Game Representative Image
|
|
// No specific image found; see if the default save image exists
|
|
/*
|
|
hFile = CreateFile( "u:\\default_screen.xbx", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL );
|
|
if( hFile == INVALID_HANDLE_VALUE )
|
|
{
|
|
m_bIsValidImage = FALSE;
|
|
return FALSE;
|
|
}
|
|
*/
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// Read the image header from disk
|
|
bSuccess = ReadFile( hFile, &XprHeader, sizeof( XprImageHeader ), &dwBytesRead, NULL );
|
|
|
|
// Validate the image
|
|
bSuccess &= dwBytesRead == sizeof( XprImageHeader ) &&
|
|
XprHeader.xpr.dwMagic == XPR_MAGIC_VALUE &&
|
|
XprHeader.xpr.dwTotalSize == CSS_IMAGE_HDR_SIZE + CSS_IMAGE_DATA_SIZE &&
|
|
XprHeader.xpr.dwHeaderSize == CSS_IMAGE_HDR_SIZE &&
|
|
XprHeader.dwEndOfHeader == 0xFFFFFFFF;
|
|
|
|
// If image looks good, store the bits in a texture
|
|
if( bSuccess )
|
|
{
|
|
HRESULT hr;
|
|
hr = glw_state->device->CreateTexture( CSS_IMAGE_WH,
|
|
CSS_IMAGE_WH,
|
|
1,
|
|
0,
|
|
D3DFMT_DXT1,
|
|
D3DPOOL(),
|
|
&lpThumbTex );
|
|
bSuccess = SUCCEEDED(hr);
|
|
|
|
if( bSuccess )
|
|
{
|
|
D3DLOCKED_RECT lr;
|
|
lpThumbTex->LockRect( 0, &lr, NULL, D3DLOCK_READONLY );
|
|
|
|
// Copy the bits from the file to the texture
|
|
SetFilePointer( hFile, CSS_IMAGE_HDR_SIZE, NULL, FILE_BEGIN );
|
|
bSuccess = ReadFile( hFile, lr.pBits, CSS_IMAGE_DATA_SIZE, &dwBytesRead, NULL );
|
|
bSuccess &= ( dwBytesRead == CSS_IMAGE_DATA_SIZE );
|
|
lpThumbTex->UnlockRect( 0 );
|
|
|
|
// If everything was ok, then set the texture ptrs
|
|
DWORD refcount;
|
|
if( bSuccess )
|
|
{
|
|
refcount = info->mipmap->Release();
|
|
|
|
assert(refcount == 0);
|
|
|
|
info->mipmap = lpThumbTex;
|
|
info->mipmap->AddRef();
|
|
|
|
refcount = lpThumbTex->Release();
|
|
|
|
assert(refcount == 1);
|
|
}
|
|
else
|
|
{
|
|
refcount = lpThumbTex->Release();
|
|
|
|
assert(refcount == 0);
|
|
}
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
CloseHandle( hFile );
|
|
return bSuccess;
|
|
}
|
|
|
|
bool CreateVertexShader( const CHAR* strFilename, const DWORD* pdwVertexDecl, DWORD* pdwVertexShader )
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Open the vertex shader file
|
|
HANDLE hFile;
|
|
DWORD dwNumBytesRead;
|
|
hFile = CreateFile( strFilename, GENERIC_READ, FILE_SHARE_READ, NULL,
|
|
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL );
|
|
if( hFile == INVALID_HANDLE_VALUE )
|
|
return false;
|
|
|
|
// Allocate memory to read the vertex shader file
|
|
DWORD dwSize = GetFileSize(hFile, NULL);
|
|
BYTE* pData = new BYTE[dwSize+4];
|
|
if( NULL == pData )
|
|
{
|
|
CloseHandle( hFile );
|
|
return false;
|
|
}
|
|
ZeroMemory( pData, dwSize+4 );
|
|
|
|
// Read the pre-compiled vertex shader microcode
|
|
ReadFile(hFile, pData, dwSize, &dwNumBytesRead, 0);
|
|
|
|
// Create the vertex shader
|
|
hr = glw_state->device->CreateVertexShader( pdwVertexDecl, (const DWORD*)pData,
|
|
pdwVertexShader, 0 );
|
|
|
|
// Cleanup and return
|
|
CloseHandle( hFile );
|
|
delete [] pData;
|
|
|
|
if(hr == S_OK)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool CreatePixelShader( const CHAR* strFilename, DWORD* pdwPixelShader )
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Open the pixel shader file
|
|
HANDLE hFile;
|
|
DWORD dwNumBytesRead;
|
|
hFile = CreateFile( strFilename, GENERIC_READ, FILE_SHARE_READ, NULL,
|
|
OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL );
|
|
if( hFile == INVALID_HANDLE_VALUE )
|
|
return false;
|
|
|
|
// Load the pre-compiled pixel shader microcode
|
|
D3DPIXELSHADERDEF_FILE psdf;
|
|
ReadFile( hFile, &psdf, sizeof(D3DPIXELSHADERDEF_FILE), &dwNumBytesRead, NULL );
|
|
|
|
// Make sure the pixel shader is valid
|
|
if( psdf.FileID != D3DPIXELSHADERDEF_FILE_ID )
|
|
{
|
|
CloseHandle( hFile );
|
|
return false;
|
|
}
|
|
|
|
// Create the pixel shader
|
|
if( FAILED( hr = glw_state->device->CreatePixelShader( &(psdf.Psd), pdwPixelShader ) ) )
|
|
{
|
|
CloseHandle( hFile );
|
|
return false;
|
|
}
|
|
|
|
// Cleanup
|
|
CloseHandle( hFile );
|
|
|
|
return true;
|
|
}
|