+ *index++ = j * 33 + i + 1;
+ *index++ = (j + 1) * 33 + i + 1;
+ *index++ = (j + 1) * 33 + i;
+ }
+ i++;
+ }
+}
+
+static void skyspherearrays(float *vert, float *tex, float *tex2, float *source, float s, float s2)
+{
+ float *v, *t, *t2;
+ int i;
+ v = vert;
+ t = tex;
+ t2 = tex2;
+ for (i = 0;i < (33*33);i++)
+ {
+ *t++ = source[0] + s;
+ *t++ = source[1] + s;
+ *t2++ = source[0] + s2;
+ *t2++ = source[1] + s2;
+ *v++ = source[2] + r_origin[0];
+ *v++ = source[3] + r_origin[1];
+ *v++ = source[4] + r_origin[2];
+ *v++ = 0;
+ source += 5;
+ }
+}
+
+static void R_SkySphere(void)
+{
+ float speedscale, speedscale2;
+ float vert[33*33*4], tex[33*33*2], tex2[33*33*2];
+ static qboolean skysphereinitialized = false;
+ if (!skysphereinitialized)
+ {
+ skysphereinitialized = true;
+ skyspherecalc(skysphere, 1024, 1024, 1024 / 3);
+ }
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(0);
+ glDisable (GL_BLEND);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ if (lighthalf)
+ glColor3f(0.5,0.5,0.5);
+ else
+ glColor3f(1,1,1);
+ speedscale = cl.time*8.0/128.0;
+ speedscale -= (int)speedscale;
+ speedscale2 = cl.time*16.0/128.0;
+ speedscale2 -= (int)speedscale2;
+ skyspherearrays(vert, tex, tex2, skysphere, speedscale, speedscale2);
+ glVertexPointer(3, GL_FLOAT, sizeof(float) * 4, vert);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ // do not lock the texcoord array, because it will be switched
+ GL_LockArray(0, 32*32*6);
+ glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, tex);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ if (r_mergesky.value)
+ {
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(mergeskytexture)); // both layers in one texture
+ glDrawElements(GL_TRIANGLES, 32*32*6, GL_UNSIGNED_INT, &skysphereindices[0]);
+ }
+ else
+ {
+ // LordHavoc: note that this combine operation does not use the color,
+ // so it has to use alternate textures in lighthalf mode
+ if (skyrendercombine)
+ {
+ // upper clouds
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(lighthalf ? solidskytexture_half : solidskytexture));
+
+ // set up the second texcoord array
+ // switch texcoord array selector to TMU 1
+ qglClientActiveTexture(GL_TEXTURE1_ARB);
+ glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, tex2);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+
+ // render both layers as one pass using GL_ARB_texture_env_combine
+ // TMU 0 is already selected, the TMU 0 texcoord array is already
+ // set up, the texture is bound, and texturing is already enabled,
+ // so just set up COMBINE
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0);
+ glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0);
+
+ // set up TMU 1
+ qglActiveTexture(GL_TEXTURE1_ARB);
+ // lower clouds
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(lighthalf ? alphaskytexture_half : alphaskytexture));
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0);
+ glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0);
+ glEnable(GL_TEXTURE_2D);
+
+ // draw it
+ glDrawElements(GL_TRIANGLES, 32*32*6, GL_UNSIGNED_INT, &skysphereindices[0]);
+
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisable(GL_TEXTURE_2D);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ qglActiveTexture(GL_TEXTURE0_ARB);
+ // switch texcoord array selector back to TMU 0
+ qglClientActiveTexture(GL_TEXTURE0_ARB);
+ // the TMU 0 texcoord array is disabled by the code below
+ }
+ else
+ {
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(solidskytexture)); // upper clouds
+ glDrawElements(GL_TRIANGLES, 32*32*6, GL_UNSIGNED_INT, &skysphereindices[0]);
+
+ if (skyrendertwolayers)
+ {
+ glEnable (GL_BLEND);
+ glBindTexture(GL_TEXTURE_2D, R_GetTexture(alphaskytexture)); // lower clouds
+ glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 2, tex2);
+ glDrawElements(GL_TRIANGLES, 32*32*6, GL_UNSIGNED_INT, &skysphereindices[0]);
+ glDisable (GL_BLEND);