- }
-}
-
-#define SHADOWSPHERE_SEGMENTS 16
-
-shadowmesh_t *shadowsphere;
-void R_CreateShadowSphere(void)
-{
- int i, j;
- vec3_t angles, angles2, angles3, angles4;
- float verts[12];
- shadowsphere = Mod_ShadowMesh_Begin(zonemempool);
- for (i = 0;i < SHADOWSPHERE_SEGMENTS;i++)
- {
- for (j = 0;j < SHADOWSPHERE_SEGMENTS;j++)
- {
- angles[0] = i * 360.0f / SHADOWSPHERE_SEGMENTS;
- angles[1] = j * 360.0f / SHADOWSPHERE_SEGMENTS;
- angles[2] = 0;
- VectorCopy(angles, angles2);
- VectorCopy(angles, angles3);
- VectorCopy(angles, angles4);
- angles2[1] += 360.0f / SHADOWSPHERE_SEGMENTS;
- angles3[0] += 360.0f / SHADOWSPHERE_SEGMENTS;
- angles3[1] += 360.0f / SHADOWSPHERE_SEGMENTS;
- angles4[0] += 360.0f / SHADOWSPHERE_SEGMENTS;
- AngleVectorsFLU(angles, verts, NULL, NULL);
- AngleVectorsFLU(angles2, verts + 9, NULL, NULL);
- AngleVectorsFLU(angles3, verts + 6, NULL, NULL);
- AngleVectorsFLU(angles4, verts + 3, NULL, NULL);
- VectorScale(&verts[0], 64.0f, &verts[0]);
- VectorScale(&verts[3], 64.0f, &verts[3]);
- VectorScale(&verts[6], 64.0f, &verts[6]);
- VectorScale(&verts[9], 64.0f, &verts[9]);
- Mod_ShadowMesh_AddPolygon(zonemempool, shadowsphere, 4, verts);
- AngleVectorsFLU(angles, verts, NULL, NULL);
- AngleVectorsFLU(angles2, verts + 3, NULL, NULL);
- AngleVectorsFLU(angles3, verts + 6, NULL, NULL);
- AngleVectorsFLU(angles4, verts + 9, NULL, NULL);
- VectorScale(&verts[0], 128.0f, &verts[0]);
- VectorScale(&verts[3], 128.0f, &verts[3]);
- VectorScale(&verts[6], 128.0f, &verts[6]);
- VectorScale(&verts[9], 128.0f, &verts[9]);
- Mod_ShadowMesh_AddPolygon(zonemempool, shadowsphere, 4, verts);
- }
- }
- shadowsphere = Mod_ShadowMesh_Finish(zonemempool, shadowsphere);
-}
-
-
-void R_DrawShadowSphere(vec3_t origin, float radius, int visiblevolume)
-{
- int i;
- float *v;
- shadowmesh_t *mesh;
- //matrix4x4_t matrix;
- if (!shadowsphere)
- R_CreateShadowSphere();
- //Matrix4x4_CreateTranslate(&matrix, origin[0], origin[1], origin[2]);
- //Matrix4x4_ConcatScale(&matrix, radius);
- //R_Mesh_Matrix(&matrix);
- R_Mesh_Matrix(&r_identitymatrix);
- for (mesh = shadowsphere;mesh;mesh = mesh->next)
- {
- memcpy(varray_vertex, mesh->verts, mesh->numverts * sizeof(float[4]));
- for (i = 0, v = varray_vertex;i < mesh->numverts;i++, v += 4)
- VectorMA(origin, radius, v, v);
- R_Shadow_RenderVolume(mesh->numverts, mesh->numtriangles, mesh->elements, visiblevolume);
- }
-}
-
-void R_ShadowVolumeLighting (void)
-{
- int i;
- entity_render_t *ent;
- int lnum;
- float f;
- vec3_t mins, maxs, relativelightorigin, lightcolor;
- mlight_t *sl;
- rdlight_t *rd;
-
- R_Shadow_Stage_Depth();
- ent = &cl_entities[0].render;
- if (ent->model && ent->model->DrawDepth)
- {
- R_Mesh_Matrix(&ent->matrix);
- ent->model->DrawDepth(ent);
- }
- if (r_drawentities.integer)
- {
- for (i = 0;i < r_refdef.numentities;i++)
+ // copy the blurred bloom view to a texture
+ GL_ActiveTexture(0);
+ qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, r_view_x, vid.realheight - (r_view_y + bloomheight), bloomwidth, bloomheight);
+ c_bloomcopies++;
+ c_bloomcopypixels += bloomwidth * bloomheight;
+ // go back to full view area
+ qglViewport(r_view_x, vid.realheight - (r_view_y + r_view_height), r_view_width, r_view_height);
+ // put the original screen image back in place and blend the bloom
+ // texture on it
+ memset(&m, 0, sizeof(m));
+ m.pointer_vertex = varray_vertex3f;
+ m.tex[0] = R_GetTexture(r_bloom_texture_screen);
+ m.pointer_texcoord[0] = varray_texcoord2f[0];
+#if 0
+ dobloomblend = false;
+#else
+ // do both in one pass if possible
+ if (r_textureunits.integer >= 2 && gl_combine.integer)