quaternion_t quaternion_t::operator* ( const quaternion_t& quat) const
 {
     return quaternion_t(
                         q[3]*quat.q[0] + q[0]*quat.q[3] + q[1]*quat.q[2] - q[2]*quat.q[1],
                         q[3]*quat.q[1] + q[1]*quat.q[3] + q[2]*quat.q[0] - q[0]*quat.q[2],
                         q[3]*quat.q[2] + q[2]*quat.q[3] + q[0]*quat.q[1] - q[1]*quat.q[0],
                         q[3]*quat.q[3] - q[0]*quat.q[0] - q[1]*quat.q[1] - q[2]*quat.q[2]
                         );
 }
Exemplo n.º 2
0
// gets called every frame to draw the scene
void CRenderer::Update(const float dt, const uint32_t ticks)
{
    CObj* obj, *localctrl;
    int localctrlid;
    OBJITER iter;
    matrix_t m;
    vec3_t dir, up, side;
    CFrustum frustum;
    CWorld* world;

    localctrl = m_world->GetLocalController();
    localctrlid = m_world->GetLocalObj()->GetID();
    world = m_world->GetInterpWorld();

    const vec3_t campos = localctrl->GetOrigin();
    const quaternion_t camrot = localctrl->GetRot();

    m.SetCamTransform(campos, camrot);
    m.GetVec3Cam(&dir, &up, &side);
    dir = -dir;
    frustum.Setup(campos, dir, up, side,
                  RENDERER_FOV, (float)m_width/(float)m_height,
                  PLANE_NEAR,
                  PLANE_FAR);

    // light floating above the players head
    const vec3_t lightpos0(campos + vec3_t(0,25.0f,0));
    const quaternion_t lightrot0(quaternion_t(vec3_t::xAxis, -90.0f*lynxmath::DEGTORAD));
    const float lightpos0_4f[4] = {lightpos0.x, lightpos0.y, lightpos0.z, 1};
    glLightfv(GL_LIGHT0, GL_POSITION, lightpos0_4f);
    if(m_shaderactive)
    {
        if(m_useShadows)
        {
            glUseProgram(0); // draw shadowmap with fixed function pipeline
            PrepareShadowMap(lightpos0,
                    lightrot0,
                    world,
                    localctrlid); // the player is the light
        }
        glUseProgram(m_program); // activate shader
    }

    glMatrixMode(GL_MODELVIEW);
    glLoadMatrixf(m.pm);

    glClear(GL_DEPTH_BUFFER_BIT);
    glClear(GL_COLOR_BUFFER_BIT);

    glActiveTexture(GL_TEXTURE0); // normal texture channel

    if(m_shaderactive)
    {
        glUniform1i(m_tex, 0); // good old textures: GL_TEXTURE0
        glUniform1i(m_normalMap, 1); // normal maps are GL_TEXTURE1
        glUniform1i(m_lightmap, 2); // lightmap

        if(m_useShadows)
        {
            glUniform1i(m_shadowMapUniform, 7);
            glActiveTexture(GL_TEXTURE7); // shadow mapping texture GL_TEXTURE7
            glBindTexture(GL_TEXTURE_2D, m_depthTextureId);
            glActiveTexture(GL_TEXTURE0);
        }

#ifdef DRAW_NORMALS
        glUseProgram(0); // use fixed pipeline for this debug mode
#endif
    }

    // Main drawing
    DrawScene(frustum, world, localctrlid, false);

    if(m_shaderactive)
        glUseProgram(0); // don't use shader for particles

    // Particle Draw
    glDisable(GL_LIGHTING);
    glDepthMask(false);
    for(iter=world->ObjBegin();iter!=world->ObjEnd();++iter)
    {
        obj = (*iter).second;

        if(obj->GetMesh())
        {
            // Animate mesh is done in the particle loop
            // and not in DrawScene, because DrawScene
            // can be called multiple times per frame
            obj->GetMesh()->Animate(obj->GetMeshState(), dt);
        }

        if(obj->GetID() == localctrlid || !obj->GetParticleSystem())
            continue;

        // Update/animate the particles, depending on dt and the current position.
        obj->GetParticleSystem()->Update(dt, ticks, obj->GetOrigin());

        // Draw the particles. FIXME: this should use a frustum test
        obj->GetParticleSystem()->Render(side, up, dir);
    }
    glDepthMask(true);
    glColor4f(1,1,1,1);
    glEnable(GL_LIGHTING);

#ifdef DRAW_NORMALS
    // Draw vertex normals of level geometry (not face normals)
    if(world && world->GetBSP())
    {
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_LIGHTING);
        world->GetBSP()->RenderNormals();
        glEnable(GL_LIGHTING);
        glEnable(GL_DEPTH_TEST);
    }
#endif

    // Draw weapon
    if(m_shaderactive) // use shader for weapon
        glUseProgram(m_program);

    CModelMD5* viewmodel;
    md5_state_t* viewmodelstate;
    m_world->m_hud.GetModel(&viewmodel, &viewmodelstate);
    glDisable(GL_LIGHTING);
    if(viewmodel)
    {
        glClear(GL_DEPTH_BUFFER_BIT);
        glPushMatrix();
          glLoadIdentity();
          viewmodel->Render(viewmodelstate);
          viewmodel->Animate(viewmodelstate, dt);
        glPopMatrix();
    }
    glEnable(GL_LIGHTING);

    // Draw HUD
    if(m_shaderactive)
        glUseProgram(0); // no shader for HUD

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_LIGHTING);
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    glOrtho(0, m_width, m_height, 0, 0, 1);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glColor4f(1,1,1,1);
    glBindTexture(GL_TEXTURE_2D, m_crosshair);

    // Draw center crosshair
    glBegin(GL_QUADS);
        glTexCoord2d(0,1);
        glVertex3f((m_width-m_crosshair_width)*0.5f, (m_height-m_crosshair_height)*0.5f,0.0f);
        glTexCoord2d(0,0);
        glVertex3f((m_width-m_crosshair_width)*0.5f, (m_height+m_crosshair_height)*0.5f,0.0f);
        glTexCoord2d(1,0);
        glVertex3f((m_width+m_crosshair_width)*0.5f, (m_height+m_crosshair_height)*0.5f,0.0f);
        glTexCoord2d(1,1);
        glVertex3f((m_width+m_crosshair_width)*0.5f, (m_height-m_crosshair_height)*0.5f,0.0f);
    glEnd();

    // draw HUD text: score, health...
    char hudtextbuf[64];
    sprintf(hudtextbuf, "Frags: %i", m_world->m_hud.score);
    m_font.DrawGL(10.0f, m_height - 30.0f, 0.0f, hudtextbuf);
    sprintf(hudtextbuf, "%i", m_world->m_hud.health);
    m_font.DrawGL(10.0f, m_height - 35.0f - (float)m_font.GetHeight(), 0.0f, hudtextbuf);

#ifdef DRAW_SHADOWMAP // draw a small window with the scene from the light POV
    if(m_shaderactive)
    {
        //glBindTexture(GL_TEXTURE_2D, m_depthTextureId);
        glBindTexture(GL_TEXTURE_2D, g_fboShadowCamColor);
        const float shadowmap_debug_width = 200.0f;
        const float shadowmap_debug_height = shadowmap_debug_width*(float)m_height/(float)m_width;
        glBegin(GL_QUADS);
            glTexCoord2d(0,1); // upper left
            glVertex3f(0.0f, 0.0f, 0.0f);
            glTexCoord2d(0,0); //lower left
            glVertex3f(0.0f, shadowmap_debug_height, 0.0f);
            glTexCoord2d(1,0); //lower right
            glVertex3f(shadowmap_debug_width, shadowmap_debug_height, 0.0f);
            glTexCoord2d(1,1); // upper right
            glVertex3f(shadowmap_debug_width, 0.0f, 0.0f);
        glEnd();
    }
#endif

    glBindTexture(GL_TEXTURE_2D, 0);
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
    glEnable(GL_LIGHTING);
    glEnable(GL_DEPTH_TEST);
}
 quaternion_t quaternion_t::operator/ ( double val) const
 {
     val = 1.0/val;
     return quaternion_t( q[0]*val, q[1]*val, q[2]*val, q[3]*val);
 }
 quaternion_t quaternion_t::conj() const
 {
     return quaternion_t(-q[0], -q[1], -q[2], q[3]);
 }
 quaternion_t quaternion_t::operator/ ( const quaternion_t& quat) const
 {
     return quaternion_t((*this)*(quat.conj()));
 }
 quaternion_t quaternion_t::operator * ( double val) const
 {
     return quaternion_t( q[0]*val, q[1]*val, q[2]*val, q[3]*val);
 }
 quaternion_t quaternion_t::operator-() //Negation
 {
     return quaternion_t(-q[0], -q[1], -q[2], -q[3]);
 }
 quaternion_t quaternion_t::operator- ( const quaternion_t& quat) const
 {
     return quaternion_t( q[0]-quat.q[0], q[1]-quat.q[1], q[2]-quat.q[2], q[3]-quat.q[3]);
 }
 quaternion_t quaternion_t::operator+ ( const quaternion_t& quat) const
 {
     return quaternion_t( q[0]+quat.q[0], q[1]+quat.q[1], q[2]+quat.q[2], q[3]+quat.q[3]);
 }