void Starfield::Draw(Graphics::Renderer *renderer) { if (AreShadersEnabled()) { glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); } else { glDisable(GL_POINT_SMOOTH); //too large if smoothing is on glPointSize(1.0f); } // XXX would be nice to get rid of the Pi:: stuff here if (!Pi::game || Pi::player->GetFlightState() != Ship::HYPERSPACE) { renderer->DrawStaticMesh(m_model); } else { /* HYPERSPACING!!!!!!!!!!!!!!!!!!! */ /* all this j**z isn't really necessary, since the player will * be in the root frame when hyperspacing... */ matrix4x4d m, rot; Frame::GetFrameTransform(Pi::game->GetSpace()->GetRootFrame(), Pi::player->GetFrame(), m); m.ClearToRotOnly(); Pi::player->GetRotMatrix(rot); m = rot.InverseOf() * m; vector3d pz(m[2], m[6], m[10]); // roughly, the multiplier gets smaller as the duration gets larger. // the time-looking bits in this are completely arbitrary - I figured // it out by tweaking the numbers until it looked sort of right double mult = 0.0015 / (Pi::player->GetHyperspaceDuration() / (60.0*60.0*24.0*7.0)); double hyperspaceProgress = Pi::game->GetHyperspaceProgress(); //XXX this is a lot of lines if (m_hyperVtx == 0) { m_hyperVtx = new vector3f[BG_STAR_MAX * 2]; m_hyperCol = new Color[BG_STAR_MAX * 2]; } VertexArray *va = m_model->GetSurface(0)->GetVertices(); for (int i=0; i<BG_STAR_MAX; i++) { vector3f v(va->position[i]); v += vector3f(pz*hyperspaceProgress*mult); m_hyperVtx[i*2] = va->position[i] + v; m_hyperCol[i*2] = va->diffuse[i]; m_hyperVtx[i*2+1] = v; m_hyperCol[i*2+1] = va->diffuse[i]; } Pi::renderer->DrawLines(BG_STAR_MAX*2, m_hyperVtx, m_hyperCol); } if (AreShadersEnabled()) { glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); } }
/** * So if we are using the z-hack VPROG_POINTSPRITE then this still works. * Desired texture should already be bound on calling PutPointSprites() */ void PutPointSprites(int num, vector3f *v, float size, const float modulationCol[4], int stride) { glEnable(GL_BLEND); glDisable(GL_LIGHTING); glDepthMask(GL_FALSE); // float quadratic[] = { 0.0f, 0.0f, 0.00001f }; // glPointParameterfv( GL_POINT_DISTANCE_ATTENUATION, quadratic ); // glPointParameterf(GL_POINT_SIZE_MIN, 1.0 ); // glPointParameterf(GL_POINT_SIZE_MAX, 10000.0 ); glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glColor4fv(modulationCol); glBlendFunc(GL_SRC_ALPHA, GL_ONE); // XXX point sprite thing needs some work. remember to enable point // sprite shader in LmrModel.cpp if (AreShadersEnabled()) { // this is a bit dumb since it doesn't care how many lights // the scene has, and this is a constant... State::UseProgram(billboardShader); billboardShader->set_some_texture(0); } // /*if (Shader::IsVtxProgActive())*/ glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); if (0) {//GLEW_ARB_point_sprite) { glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE); glEnable(GL_POINT_SPRITE_ARB); glPointSize(size); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 0, v); glDrawArrays(GL_POINTS, 0, num); glDisableClientState(GL_VERTEX_ARRAY); glPointSize(1); glDisable(GL_POINT_SPRITE_ARB); glDisable(GL_TEXTURE_2D); } else { // quad billboards matrix4x4f rot; glGetFloatv(GL_MODELVIEW_MATRIX, &rot[0]); rot.ClearToRotOnly(); rot = rot.InverseOf(); const float sz = 0.5f*size; const vector3f rotv1 = rot * vector3f(sz, sz, 0.0f); const vector3f rotv2 = rot * vector3f(sz, -sz, 0.0f); const vector3f rotv3 = rot * vector3f(-sz, -sz, 0.0f); const vector3f rotv4 = rot * vector3f(-sz, sz, 0.0f); glBegin(GL_QUADS); for (int i=0; i<num; i++) { vector3f pos(*v); vector3f vert; vert = pos+rotv4; glTexCoord2f(0.0f,0.0f); glVertex3f(vert.x, vert.y, vert.z); vert = pos+rotv3; glTexCoord2f(0.0f,1.0f); glVertex3f(vert.x, vert.y, vert.z); vert = pos+rotv2; glTexCoord2f(1.0f,1.0f); glVertex3f(vert.x, vert.y, vert.z); vert = pos+rotv1; glTexCoord2f(1.0f,0.0f); glVertex3f(vert.x, vert.y, vert.z); v = reinterpret_cast<vector3f*>(reinterpret_cast<char*>(v)+stride); } glEnd(); } // /*if (Shader::IsVtxProgActive())*/ glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); // quadratic[0] = 1; quadratic[1] = 0; // glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic ); glDisable(GL_TEXTURE_2D); glDepthMask(GL_TRUE); glEnable(GL_LIGHTING); glDisable(GL_BLEND); }