+ qglBindTexture(GL_TEXTURE_CUBE_MAP, unit->tcubemap);CHECKGLERROR
+ }
+ break;
+ case RENDERPATH_D3D9:
+#ifdef SUPPORTD3D
+ {
+ extern cvar_t gl_texture_anisotropy;
+ if (!tex)
+ {
+ tex = r_texture_white;
+ // not initialized enough yet...
+ if (!tex)
+ return;
+ }
+ // upload texture if needed
+ R_GetTexture(tex);
+ if (unit->texture == tex)
+ return;
+ unit->texture = tex;
+ IDirect3DDevice9_SetTexture(vid_d3d9dev, unitnum, (IDirect3DBaseTexture9*)tex->d3dtexture);
+ //IDirect3DDevice9_SetRenderState(vid_d3d9dev, d3drswrap[unitnum], (tex->flags & TEXF_CLAMP) ? (D3DWRAPCOORD_0 | D3DWRAPCOORD_1 | D3DWRAPCOORD_2) : 0);
+ IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSU, tex->d3daddressu);
+ IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSV, tex->d3daddressv);
+ if (tex->d3daddressw)
+ IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_ADDRESSW, tex->d3daddressw);
+ IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAGFILTER, tex->d3dmagfilter);
+ IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MINFILTER, tex->d3dminfilter);
+ IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPFILTER, tex->d3dmipfilter);
+ IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MIPMAPLODBIAS, tex->d3dmipmaplodbias);
+ IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXMIPLEVEL, tex->d3dmaxmiplevelfilter);
+ IDirect3DDevice9_SetSamplerState(vid_d3d9dev, unitnum, D3DSAMP_MAXANISOTROPY, gl_texture_anisotropy.integer);
+ }
+#endif
+ break;
+ case RENDERPATH_D3D10:
+ Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_D3D11:
+ Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_SOFT:
+ if (!tex)
+ {
+ tex = r_texture_white;
+ // not initialized enough yet...
+ if (!tex)
+ return;
+ }
+ texnum = R_GetTexture(tex);
+ if (unit->texture == tex)
+ return;
+ unit->texture = tex;
+ DPSOFTRAST_SetTexture(unitnum, texnum);
+ break;
+ }
+}
+
+void R_Mesh_TexMatrix(unsigned int unitnum, const matrix4x4_t *matrix)
+{
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES1:
+ case RENDERPATH_GLES2:
+#ifdef GL_MODELVIEW
+ if (matrix && matrix->m[3][3])
+ {
+ gltextureunit_t *unit = gl_state.units + unitnum;
+ // texmatrix specified, check if it is different
+ if (!unit->texmatrixenabled || memcmp(&unit->matrix, matrix, sizeof(matrix4x4_t)))
+ {
+ float glmatrix[16];
+ unit->texmatrixenabled = true;
+ unit->matrix = *matrix;
+ CHECKGLERROR
+ Matrix4x4_ToArrayFloatGL(&unit->matrix, glmatrix);
+ GL_ActiveTexture(unitnum);
+ qglMatrixMode(GL_TEXTURE);CHECKGLERROR
+ qglLoadMatrixf(glmatrix);CHECKGLERROR
+ qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
+ }
+ }
+ else
+ {
+ // no texmatrix specified, revert to identity
+ gltextureunit_t *unit = gl_state.units + unitnum;
+ if (unit->texmatrixenabled)
+ {
+ unit->texmatrixenabled = false;
+ unit->matrix = identitymatrix;
+ CHECKGLERROR
+ GL_ActiveTexture(unitnum);
+ qglMatrixMode(GL_TEXTURE);CHECKGLERROR
+ qglLoadIdentity();CHECKGLERROR
+ qglMatrixMode(GL_MODELVIEW);CHECKGLERROR
+ }
+ }
+#endif
+ break;
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ break;
+ case RENDERPATH_SOFT:
+ break;
+ }
+}
+
+void R_Mesh_TexCombine(unsigned int unitnum, int combinergb, int combinealpha, int rgbscale, int alphascale)
+{
+#if defined(GL_TEXTURE_ENV) && !defined(USE_GLES2)
+ gltextureunit_t *unit = gl_state.units + unitnum;
+ CHECKGLERROR
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES2:
+ // do nothing
+ break;
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
+ // GL_ARB_texture_env_combine
+ if (!combinergb)
+ combinergb = GL_MODULATE;
+ if (!combinealpha)
+ combinealpha = GL_MODULATE;
+ if (!rgbscale)
+ rgbscale = 1;
+ if (!alphascale)
+ alphascale = 1;
+ if (combinergb != combinealpha || rgbscale != 1 || alphascale != 1)
+ {
+ if (combinergb == GL_DECAL)
+ combinergb = GL_INTERPOLATE;
+ if (unit->combine != GL_COMBINE)
+ {
+ unit->combine = GL_COMBINE;
+ GL_ActiveTexture(unitnum);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);CHECKGLERROR
+ qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);CHECKGLERROR // for GL_INTERPOLATE mode
+ }
+ if (unit->combinergb != combinergb)
+ {
+ unit->combinergb = combinergb;
+ GL_ActiveTexture(unitnum);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, unit->combinergb);CHECKGLERROR
+ }
+ if (unit->combinealpha != combinealpha)
+ {
+ unit->combinealpha = combinealpha;
+ GL_ActiveTexture(unitnum);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, unit->combinealpha);CHECKGLERROR
+ }
+ if (unit->rgbscale != rgbscale)
+ {
+ unit->rgbscale = rgbscale;
+ GL_ActiveTexture(unitnum);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, unit->rgbscale);CHECKGLERROR
+ }
+ if (unit->alphascale != alphascale)
+ {
+ unit->alphascale = alphascale;
+ GL_ActiveTexture(unitnum);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, unit->alphascale);CHECKGLERROR
+ }
+ }
+ else
+ {
+ if (unit->combine != combinergb)
+ {
+ unit->combine = combinergb;
+ GL_ActiveTexture(unitnum);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
+ }
+ }
+ break;
+ case RENDERPATH_GL11:
+ // normal GL texenv
+ if (!combinergb)
+ combinergb = GL_MODULATE;
+ if (unit->combine != combinergb)
+ {
+ unit->combine = combinergb;
+ GL_ActiveTexture(unitnum);
+ qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->combine);CHECKGLERROR
+ }
+ break;
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ break;
+ case RENDERPATH_SOFT:
+ break;
+ }
+#endif
+}
+
+void R_Mesh_ResetTextureState(void)
+{
+ unsigned int unitnum;
+
+ BACKENDACTIVECHECK
+
+ for (unitnum = 0;unitnum < vid.teximageunits;unitnum++)
+ R_Mesh_TexBind(unitnum, NULL);
+ for (unitnum = 0;unitnum < vid.texarrayunits;unitnum++)
+ R_Mesh_TexCoordPointer(unitnum, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES2:
+ case RENDERPATH_D3D9:
+ case RENDERPATH_D3D10:
+ case RENDERPATH_D3D11:
+ case RENDERPATH_SOFT:
+ break;
+ case RENDERPATH_GL11:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
+ for (unitnum = 0;unitnum < vid.texunits;unitnum++)
+ {
+ R_Mesh_TexCombine(unitnum, GL_MODULATE, GL_MODULATE, 1, 1);
+ R_Mesh_TexMatrix(unitnum, NULL);
+ }
+ break;
+ }
+}
+
+
+
+#ifdef SUPPORTD3D
+//#define r_vertex3f_d3d9fvf (D3DFVF_XYZ)
+//#define r_vertexgeneric_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
+//#define r_vertexmesh_d3d9fvf (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX5 | D3DFVF_TEXCOORDSIZE1(3) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE3(3))
+
+D3DVERTEXELEMENT9 r_vertex3f_d3d9elements[] =
+{
+ {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ D3DDECL_END()
+};
+
+D3DVERTEXELEMENT9 r_vertexgeneric_d3d9elements[] =
+{
+ {0, (int)((size_t)&((r_vertexgeneric_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, (int)((size_t)&((r_vertexgeneric_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ {0, (int)((size_t)&((r_vertexgeneric_t *)0)->texcoord2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ D3DDECL_END()
+};
+
+D3DVERTEXELEMENT9 r_vertexmesh_d3d9elements[] =
+{
+ {0, (int)((size_t)&((r_vertexmesh_t *)0)->vertex3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
+ {0, (int)((size_t)&((r_vertexmesh_t *)0)->color4f ), D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
+ {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordtexture2f ), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
+ {0, (int)((size_t)&((r_vertexmesh_t *)0)->svector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
+ {0, (int)((size_t)&((r_vertexmesh_t *)0)->tvector3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2},
+ {0, (int)((size_t)&((r_vertexmesh_t *)0)->normal3f ), D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3},
+ {0, (int)((size_t)&((r_vertexmesh_t *)0)->texcoordlightmap2f), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4},
+ {0, (int)((size_t)&((r_vertexmesh_t *)0)->skeletalindex4ub ), D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 6},
+ {0, (int)((size_t)&((r_vertexmesh_t *)0)->skeletalweight4ub ), D3DDECLTYPE_UBYTE4N, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 7},
+ D3DDECL_END()
+};
+
+IDirect3DVertexDeclaration9 *r_vertex3f_d3d9decl;
+IDirect3DVertexDeclaration9 *r_vertexgeneric_d3d9decl;
+IDirect3DVertexDeclaration9 *r_vertexmesh_d3d9decl;
+#endif
+
+static void R_Mesh_InitVertexDeclarations(void)
+{
+#ifdef SUPPORTD3D
+ r_vertex3f_d3d9decl = NULL;
+ r_vertexgeneric_d3d9decl = NULL;
+ r_vertexmesh_d3d9decl = NULL;
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GL20:
+ case RENDERPATH_GL13:
+ case RENDERPATH_GL11:
+ case RENDERPATH_GLES1:
+ case RENDERPATH_GLES2:
+ break;
+ case RENDERPATH_D3D9:
+ IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertex3f_d3d9elements, &r_vertex3f_d3d9decl);
+ IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexgeneric_d3d9elements, &r_vertexgeneric_d3d9decl);
+ IDirect3DDevice9_CreateVertexDeclaration(vid_d3d9dev, r_vertexmesh_d3d9elements, &r_vertexmesh_d3d9decl);
+ break;
+ case RENDERPATH_D3D10:
+ Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_D3D11:
+ Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__);
+ break;
+ case RENDERPATH_SOFT:
+ break;
+ }
+#endif
+}
+
+static void R_Mesh_DestroyVertexDeclarations(void)
+{
+#ifdef SUPPORTD3D
+ if (r_vertex3f_d3d9decl)
+ IDirect3DVertexDeclaration9_Release(r_vertex3f_d3d9decl);
+ r_vertex3f_d3d9decl = NULL;
+ if (r_vertexgeneric_d3d9decl)
+ IDirect3DVertexDeclaration9_Release(r_vertexgeneric_d3d9decl);
+ r_vertexgeneric_d3d9decl = NULL;
+ if (r_vertexmesh_d3d9decl)
+ IDirect3DVertexDeclaration9_Release(r_vertexmesh_d3d9decl);
+ r_vertexmesh_d3d9decl = NULL;
+#endif
+}
+
+void R_Mesh_PrepareVertices_Vertex3f(int numvertices, const float *vertex3f, const r_meshbuffer_t *vertexbuffer, int bufferoffset)
+{
+ // upload temporary vertexbuffer for this rendering
+ if (!gl_state.usevbo_staticvertex)
+ vertexbuffer = NULL;
+ if (!vertexbuffer && gl_state.usevbo_dynamicvertex)
+ vertexbuffer = R_BufferData_Store(numvertices * sizeof(float[3]), (void *)vertex3f, R_BUFFERDATA_VERTEX, &bufferoffset);
+ switch(vid.renderpath)
+ {
+ case RENDERPATH_GL20:
+ case RENDERPATH_GLES2:
+ if (vertexbuffer)
+ {
+ R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, bufferoffset);
+ R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
+ }
+ else
+ {
+ R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
+ R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(2, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(3, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(4, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(5, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(6, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(7, 4, GL_UNSIGNED_BYTE, sizeof(unsigned char[4]), NULL, NULL, 0);
+ }
+ break;
+ case RENDERPATH_GL13:
+ case RENDERPATH_GLES1:
+ if (vertexbuffer)
+ {
+ R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, bufferoffset);
+ R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ }
+ else
+ {
+ R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, 0);
+ R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(1, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);
+ }
+ break;
+ case RENDERPATH_GL11:
+ if (vertexbuffer)
+ {
+ R_Mesh_VertexPointer(3, GL_FLOAT, sizeof(float[3]), vertex3f, vertexbuffer, bufferoffset);
+ R_Mesh_ColorPointer(4, GL_FLOAT, sizeof(float[4]), NULL, NULL, 0);
+ R_Mesh_TexCoordPointer(0, 2, GL_FLOAT, sizeof(float[2]), NULL, NULL, 0);