コード例 #1
0
ファイル: discoball.c プロジェクト: MaddTheSane/xscreensaver
ENTRYPOINT void 
init_ball (ModeInfo *mi)
{
  ball_configuration *bp;
  int wire = MI_IS_WIREFRAME(mi);

  MI_INIT (mi, bps);

  bp = &bps[MI_SCREEN(mi)];

  bp->glx_context = init_GL(mi);

  if (! wire)
    build_texture (mi);

  reshape_ball (mi, MI_WIDTH(mi), MI_HEIGHT(mi));

  bp->th = 180 - frand(360);

  if (MI_COUNT(mi) < 10)
    MI_COUNT(mi) = 10;
  if (MI_COUNT(mi) > 200)
    MI_COUNT(mi) = 200;

  {
    double spin_speed   = 0.1;
    double wander_speed = 0.003;
    double spin_accel   = 1;

    bp->rot = make_rotator (do_spin ? spin_speed : 0,
                            do_spin ? spin_speed : 0,
                            do_spin ? spin_speed : 0,
                            spin_accel,
                            do_wander ? wander_speed : 0,
                            False);
    bp->trackball = gltrackball_init (True);
  }

  build_ball (mi);

  if (!wire)
    {
      GLfloat color[4] = {0.5, 0.5, 0.5, 1};
      GLfloat cspec[4] = {1, 1, 1, 1};
      static const GLfloat shiny = 10;

      static GLfloat pos0[4] = { 0.5, -1, -0.5, 0};
      static GLfloat pos1[4] = {-0.75, -1, 0, 0};
      static GLfloat amb[4] = {0, 0, 0, 1};
      static GLfloat dif[4] = {1, 1, 1, 1};
      static GLfloat spc[4] = {1, 1, 1, 1};

      glEnable(GL_LIGHTING);
      glEnable(GL_LIGHT0);
      glEnable(GL_LIGHT1);
      glEnable(GL_DEPTH_TEST);
      glEnable(GL_CULL_FACE);

      color[0] += frand(0.2);
      color[1] += frand(0.2);
      color[2] += frand(0.2);

      cspec[0] -= frand(0.2);
      cspec[1] -= frand(0.2);
      cspec[2] -= frand(0.2);

      glLightfv(GL_LIGHT0, GL_POSITION, pos0);
      glLightfv(GL_LIGHT0, GL_AMBIENT,  amb);
      glLightfv(GL_LIGHT0, GL_DIFFUSE,  dif);
      glLightfv(GL_LIGHT0, GL_SPECULAR, spc);

      glLightfv(GL_LIGHT1, GL_POSITION, pos1);
      glLightfv(GL_LIGHT1, GL_AMBIENT,  amb);
      glLightfv(GL_LIGHT1, GL_DIFFUSE,  dif);
      glLightfv(GL_LIGHT1, GL_SPECULAR, spc);

      glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
      glMaterialfv (GL_FRONT, GL_SPECULAR,  cspec);
      glMateriali  (GL_FRONT, GL_SHININESS, shiny);
    }
}
コード例 #2
0
ファイル: figure.cpp プロジェクト: jonigata/yamadumi
    //
    // MQO
    //
    void build_from_mqo(
        mqo_reader::document_type& doc, float scale, const Color& color) {

        // マテリアル
        for (const auto& ms: doc.materials) {
            Piece m;
            m.vbo       = 0;
            m.ibo       = 0;
#ifdef JSTEXTURE
            m.texture   = "";
#else
            m.texture   = 0;
#endif
            m.color.rgba[0] = ms.color.red;
            m.color.rgba[1] = ms.color.green;
            m.color.rgba[2] = ms.color.blue;
            m.color.rgba[3] = ms.color.alpha;
            if (ms.texture != "") {
#ifdef JSTEXTURE
                m.texture = ms.texture;
                loadTexture(m.texture.c_str());
#else
                m.texture = build_texture(ms.texture.c_str());
#endif
            }

            pieces_.push_back(m);
        }
        {
            // default material
            Piece m;
            m.vbo       = 0;
            m.ibo       = 0;
#ifdef JSTEXTURE
            m.texture   = "";
#else
            m.texture   = 0;
#endif
            m.color     = color;
            pieces_.push_back(m);
        }

        // 頂点, 面
        for (const auto& pair: doc.objects) {
            const mqo_reader::object_type& obj = pair.second;

            // dictionary:
            //  (source vertex index, uv ) => destination vertex index
            struct VertexKey {
                int     index;
                float   u;
                float   v;

                VertexKey(){}
                VertexKey(int aindex, float au, float av)
                    : index(aindex), u(au), v(av) {}

                bool operator<(const VertexKey& a) const {
                    if (index < a.index) { return true; }
                    if (a.index < index) { return false; }
                    if (u < a.u) { return true; }
                    if (a.u < u) { return false; }
                    return v < a.v;
                }
            };

            std::vector<std::map<VertexKey, int>> used_vertices;
            used_vertices.resize(pieces_.size());

            // マテリアルごとに使用頂点を分類
            for (const auto& face: obj.faces) {
                int material_index = face.material_index;
                if (material_index == -1) {
                    material_index = int(pieces_.size() - 1);
                }
                int i0 = face.vertex_indices[0];
                int i1 = face.vertex_indices[1];
                int i2 = face.vertex_indices[2];
                                
                std::map<VertexKey, int>& c = used_vertices[material_index];
                c[VertexKey(i0, face.uv[0].u, face.uv[0].v)] = -1; 
                c[VertexKey(i1, face.uv[1].u, face.uv[1].v)] = -1; 
                c[VertexKey(i2, face.uv[2].u, face.uv[2].v)] = -1; 
            }
                        
            // マテリアルごとに使われている頂点を追加
            size_t n = pieces_.size();
            for (size_t i = 0 ; i < n ; i++) {
                Piece& m = pieces_[i];
                std::map<VertexKey, int>& c = used_vertices[i];

                int no = int(m.vertex_source.size());
                for (auto& j: c) {
                    const auto& src = obj.vertices[j.first.index];

                    Piece::Vertex dst;
                    dst.position = Vector(
                        src.x * scale,
                        src.y * scale,
                        src.z * -scale);
                    dst.normal = Vector(0, 0, 0);
                    dst.diffuse = m.color;
                    dst.u = j.first.u;
                    dst.v = j.first.v;
                    m.vertex_source.push_back(dst);

                    j.second = no++;
                }
            }

            // マテリアルごとに面を追加
            for (const auto& face: obj.faces) {
                int material_index = face.material_index;
                if (material_index == -1) {
                    material_index = int(pieces_.size()- 1);
                }
                                
                int i0 = face.vertex_indices[0];
                int i1 = face.vertex_indices[1];
                int i2 = face.vertex_indices[2];

                std::map<VertexKey, int>& c = used_vertices[material_index];
                int k0 = c[VertexKey(i0, face.uv[0].u, face.uv[0].v)];
                int k1 = c[VertexKey(i1, face.uv[1].u, face.uv[1].v)];
                int k2 = c[VertexKey(i2, face.uv[2].u, face.uv[2].v)];

                Piece& m = pieces_[material_index];
                m.index_source.push_back(k0);
                m.index_source.push_back(k1);
                m.index_source.push_back(k2);

                Piece::Vertex& v0 = m.vertex_source[k0];
                Piece::Vertex& v1 = m.vertex_source[k1];
                Piece::Vertex& v2 = m.vertex_source[k2];
                Vector normal = cross(
                    v1.position - v0.position,
                    v2.position - v0.position);
                v0.normal += normal;
                v1.normal += normal;
                v2.normal += normal;
            }
        }

        // 法線後処理
        for (Piece& m: pieces_) {
            for (auto& v: m.vertex_source) {
                normalize_f(v.normal);
            }
        }

        build_pieces();
    }