/* * 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 #include "../renderer/tr_local.h" #include "glw_win_dx8.h" #include "win_local.h" #ifdef _XBOX #include #include "win_lighteffects.h" #include "win_highdynamicrange.h" #ifndef FINAL_BUILD #include #endif #endif #include 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 0 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 ( * 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) y = 0; else if (y > glConfig.vidHeight) y = glConfig.vidHeight; if (width < 0) width = 0; // 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(glw_state->vertexPointer)); glw_state->vertexPointer = glw_state->vertexPointerBack; if (glw_state->normalArrayState) { Z_Free(const_cast(glw_state->normalPointer)); glw_state->normalPointer = glw_state->normalPointerBack; } if (glw_state->colorArrayState) { Z_Free(const_cast(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(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 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_TEXTURE_SIZE: params[0] = (T)256; break; case GL_MAX_ACTIVE_TEXTURES_ARB: params[0] = GLW_MAX_TEXTURE_STAGES; break; case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: params[0] = 4; 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_HACK() { _updateDrawStride(glw_state->normalArrayState, glw_state->texCoordArrayState[0] ? 1 : 0, glw_state->texCoordArrayState[1] ? 1 : 0); _updateShader(glw_state->normalArrayState, glw_state->texCoordArrayState[0] ? 1 : 0, glw_state->texCoordArrayState[1] ? 1 : 0); _updateTextures(); _updateMatrices(); 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); } } void renderObject_Light() { //glw_state->drawStride = 11; //glw_state->primitiveMode = D3DPT_TRIANGLESTRIP; // //// get the necessary draw function //drawelemfunc_t func = _drawElementsLightShader; //int stride = glw_state->drawStride; ///*if(tess.currentPass == 0) // buildStrips(glw_state->strip_lengths, &glw_state->num_strip_lengths, glw_state->strip_dest, // &tess.numIndexes, &tess.indexes[0]);*/ //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); //} // start the draw mode assert(!glw_state->inDrawBlock); glw_state->inDrawBlock = true; glw_state->primitiveMode = D3DPT_TRIANGLELIST; glw_state->drawStride = 11; // set vertex counters glw_state->numVertices = 0; glw_state->totalVertices = tess.numIndexes; glw_state->maxVertices = _getMaxVerts(); // open a draw packet //int num_packets = ((tess.numIndexes * glw_state->drawStride) / GLW_MAX_DRAW_PACKET_SIZE) + 1; int num_packets; if(tess.numIndexes == 0) { num_packets = 1; } else { num_packets = (tess.numIndexes / glw_state->maxVertices) + (!!(tess.numIndexes % glw_state->maxVertices)); } int cmd_size = num_packets * 3; int vert_size = glw_state->drawStride * tess.numIndexes; glw_state->device->BeginPush(vert_size + cmd_size + 2, &glw_state->drawArray); glw_state->drawArray = _restartDrawPacket( glw_state->drawArray, glw_state->maxVertices); // get the draw function we need drawelemfunc_t func = _drawElementsLightShader; // loop taking care not to draw too much at a time int inc = glw_state->maxVertices; for (int start = 0; ; start += inc) { // draw glw_state->maxVertices amount of geometry func(glw_state->maxVertices, &(((GLushort*)tess.indexes)[start])); // 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); } // finish up the draw qglEnd(); } void renderObject_Bump() { // start the draw mode assert(!glw_state->inDrawBlock); glw_state->inDrawBlock = true; glw_state->primitiveMode = D3DPT_TRIANGLELIST; glw_state->drawStride = 13; // set vertex counters glw_state->numVertices = 0; glw_state->totalVertices = tess.numIndexes; glw_state->maxVertices = _getMaxVerts(); // open a draw packet //int num_packets = ((tess.numIndexes * glw_state->drawStride) / GLW_MAX_DRAW_PACKET_SIZE) + 1; int num_packets; if(tess.numIndexes == 0) { num_packets = 1; } else { num_packets = (tess.numIndexes / glw_state->maxVertices) + (!!(tess.numIndexes % glw_state->maxVertices)); } int cmd_size = num_packets * 3; int vert_size = glw_state->drawStride * tess.numIndexes; glw_state->device->BeginPush(vert_size + cmd_size + 2, &glw_state->drawArray); glw_state->drawArray = _restartDrawPacket( glw_state->drawArray, glw_state->maxVertices); // get the draw function we need drawelemfunc_t func = _drawElementsBumpShader; // loop taking care not to draw too much at a time int inc = glw_state->maxVertices; for (int start = 0; ; start += inc) { // draw glw_state->maxVertices amount of geometry func(glw_state->maxVertices, &(((GLushort*)tess.indexes)[start])); // 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); } // finish up the draw qglEnd(); } void renderObject_Env() { //glw_state->drawStride = 7; //_updateTextures(); //glw_state->primitiveMode = D3DPT_TRIANGLESTRIP; // //// get the necessary draw function //drawelemfunc_t func = _drawElementsVCN; //int stride = glw_state->drawStride; //if(tess.currentPass == 0) //{ // buildStrips(glw_state->strip_lengths, &glw_state->num_strip_lengths, glw_state->strip_dest, // &tess.numIndexes, &tess.indexes[0]); //} //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); //} // start the draw mode assert(!glw_state->inDrawBlock); glw_state->inDrawBlock = true; glw_state->primitiveMode = D3DPT_TRIANGLELIST; glw_state->drawStride = 7; _updateTextures(); // set vertex counters glw_state->numVertices = 0; glw_state->totalVertices = tess.numIndexes; glw_state->maxVertices = _getMaxVerts(); // open a draw packet //int num_packets = ((tess.numIndexes * glw_state->drawStride) / GLW_MAX_DRAW_PACKET_SIZE) + 1; int num_packets; if(tess.numIndexes == 0) { num_packets = 1; } else { num_packets = (tess.numIndexes / glw_state->maxVertices) + (!!(tess.numIndexes % glw_state->maxVertices)); } int cmd_size = num_packets * 3; int vert_size = glw_state->drawStride * tess.numIndexes; glw_state->device->BeginPush(vert_size + cmd_size + 2, &glw_state->drawArray); glw_state->drawArray = _restartDrawPacket( glw_state->drawArray, glw_state->maxVertices); // get the draw function we need drawelemfunc_t func = _drawElementsVCN; // loop taking care not to draw too much at a time int inc = glw_state->maxVertices; for (int start = 0; ; start += inc) { // draw glw_state->maxVertices amount of geometry func(glw_state->maxVertices, &(((GLushort*)tess.indexes)[start])); // 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); } // finish up the draw qglEnd(); } #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) { #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 } 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) { assert(format == GL_RGBA && 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(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; int bpp; 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_RGB_SWIZZLE_EXT: f = D3DFMT_R5G6B5; bpp = 2; break; case GL_LIN_RGB8: f = D3DFMT_X8R8G8B8; bpp = 4; break; default: assert(0); } _d3d_check(glw_state->device->CreateImageSurface(width, height, f, &pSurf), "CreateImageSurface"); _d3d_check(D3DXLoadSurfaceFromMemory(pSurf, NULL, NULL, (LPCVOID)pixels, f, width * bpp, 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_RGBA8: case 4: f = D3DFMT_A8R8G8B8; break; case GL_LIN_RGB8: f = D3DFMT_LIN_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); // Only 16-bit textures supported for now! D3DXLoadSurfaceFromMemory(surf, NULL, &dr, pixels, D3DFMT_R5G6B5, width * 2, 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 ) { Com_Printf ("...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; qglCopyBackBufferToTexEXT = NULL; qglCopyBackBufferToTex = 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; width = 720; 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 CG_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; CG_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->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; } #if defined (_TAKESCREENS) void QGL_SaveScreenshot(void) { LPDIRECT3DSURFACE8 screenShot = 0; glw_state->device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &screenShot); // Copy over the screen shot to the new image that is 64x64 LPDIRECT3DSURFACE8 compressedSaveGameImage = 0; glw_state->device->CreateImageSurface( 64, 64, 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 XGWriteSurfaceOrTextureToXPR( compressedSaveGameImage, "u:\\saveimage.xbx", TRUE ); // Free the compressed 64x64 image if ( compressedSaveGameImage ) compressedSaveGameImage->Release(); } #endif 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; }