+void R_DrawDecal_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
+{
+ int surfacelistindex;
+ int batchstart, batchcount;
+ const decal_t *d;
+ pblend_t blendmode;
+ rtexture_t *texture;
+ float *v3f, *t2f, *c4f;
+
+ r_refdef.stats.decals += numsurfaces;
+ R_Mesh_Matrix(&identitymatrix);
+ R_Mesh_ResetTextureState();
+ R_Mesh_VertexPointer(particle_vertex3f, 0, 0);
+ R_Mesh_TexCoordPointer(0, 2, particle_texcoord2f, 0, 0);
+ R_Mesh_ColorPointer(particle_color4f, 0, 0);
+ GL_DepthMask(false);
+ GL_DepthRange(0, 1);
+ GL_PolygonOffset(0, 0);
+ GL_DepthTest(true);
+ GL_CullFace(GL_NONE);
+
+ // first generate all the vertices at once
+ for (surfacelistindex = 0, v3f = particle_vertex3f, t2f = particle_texcoord2f, c4f = particle_color4f;surfacelistindex < numsurfaces;surfacelistindex++, v3f += 3*4, t2f += 2*4, c4f += 4*4)
+ {
+ particletexture_t *tex;
+ const float *org;
+ float right[3], up[3], fog, cr, cg, cb, ca, size;
+
+ d = cl.decals + surfacelist[surfacelistindex];
+
+ //blendmode = particletype[d->typeindex].blendmode;
+
+ cr = d->color[0] * (1.0f / 255.0f) * r_refdef.view.colorscale;
+ cg = d->color[1] * (1.0f / 255.0f) * r_refdef.view.colorscale;
+ cb = d->color[2] * (1.0f / 255.0f) * r_refdef.view.colorscale;
+ ca = d->alpha * (1.0f / 255.0f);
+ //if (blendmode == PBLEND_MOD)
+ {
+ cr *= ca;
+ cg *= ca;
+ cb *= ca;
+ cr = min(cr, 1);
+ cg = min(cg, 1);
+ cb = min(cb, 1);
+ ca = 1;
+ }
+ ca *= cl_particles_alpha.value;
+ if (r_refdef.fogenabled)
+ {
+ fog = FogPoint_World(d->org);
+ cr = cr * fog;
+ cg = cg * fog;
+ cb = cb * fog;
+ //if (blendmode == PBLEND_ALPHA)
+ //{
+ // fog = 1 - fog;
+ // cr += r_refdef.fogcolor[0] * fog;
+ // cg += r_refdef.fogcolor[1] * fog;
+ // cb += r_refdef.fogcolor[2] * fog;
+ //}
+ }
+ c4f[0] = c4f[4] = c4f[8] = c4f[12] = cr;
+ c4f[1] = c4f[5] = c4f[9] = c4f[13] = cg;
+ c4f[2] = c4f[6] = c4f[10] = c4f[14] = cb;
+ c4f[3] = c4f[7] = c4f[11] = c4f[15] = ca;
+
+ size = d->size * cl_particles_size.value;
+ org = d->org;
+ tex = &particletexture[d->texnum];
+
+ // PARTICLE_ORIENTED_DOUBLESIDED
+ VectorVectors(d->normal, right, up);
+ VectorScale(right, size, right);
+ VectorScale(up, size, up);
+ v3f[ 0] = org[0] - right[0] - up[0];
+ v3f[ 1] = org[1] - right[1] - up[1];
+ v3f[ 2] = org[2] - right[2] - up[2];
+ v3f[ 3] = org[0] - right[0] + up[0];
+ v3f[ 4] = org[1] - right[1] + up[1];
+ v3f[ 5] = org[2] - right[2] + up[2];
+ v3f[ 6] = org[0] + right[0] + up[0];
+ v3f[ 7] = org[1] + right[1] + up[1];
+ v3f[ 8] = org[2] + right[2] + up[2];
+ v3f[ 9] = org[0] + right[0] - up[0];
+ v3f[10] = org[1] + right[1] - up[1];
+ v3f[11] = org[2] + right[2] - up[2];
+ t2f[0] = tex->s1;t2f[1] = tex->t2;
+ t2f[2] = tex->s1;t2f[3] = tex->t1;
+ t2f[4] = tex->s2;t2f[5] = tex->t1;
+ t2f[6] = tex->s2;t2f[7] = tex->t2;
+ }
+
+ // now render batches of particles based on blendmode and texture
+ blendmode = PBLEND_ADD;
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ texture = particletexture[63].texture;
+ R_Mesh_TexBind(0, R_GetTexture(texture));
+ GL_LockArrays(0, numsurfaces*4);
+ batchstart = 0;
+ batchcount = 0;
+ for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
+ {
+ d = cl.decals + surfacelist[surfacelistindex];
+
+ if (blendmode != particletype[d->typeindex].blendmode)
+ {
+ if (batchcount > 0)
+ R_Mesh_Draw(batchstart * 4, batchcount * 4, batchcount * 2, particle_element3i + batchstart * 6, 0, 0);
+ batchcount = 0;
+ batchstart = surfacelistindex;
+ blendmode = particletype[d->typeindex].blendmode;
+ if (blendmode == PBLEND_ALPHA)
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ else if (blendmode == PBLEND_ADD)
+ GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+ else //if (blendmode == PBLEND_MOD)
+ GL_BlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
+ }
+ if (texture != particletexture[d->texnum].texture)
+ {
+ if (batchcount > 0)
+ R_Mesh_Draw(batchstart * 4, batchcount * 4, batchcount * 2, particle_element3i + batchstart * 6, 0, 0);
+ batchcount = 0;
+ batchstart = surfacelistindex;
+ texture = particletexture[d->texnum].texture;
+ R_Mesh_TexBind(0, R_GetTexture(texture));
+ }
+
+ batchcount++;
+ }
+ if (batchcount > 0)
+ R_Mesh_Draw(batchstart * 4, batchcount * 4, batchcount * 2, particle_element3i + batchstart * 6, 0, 0);
+ GL_LockArrays(0, 0);
+}
+