Ejemplo n.º 1
0
  void DrawFill(const RasterPoint *points, unsigned start) const {
    /* triangulate the polygon */
    AllocatedArray<GLushort> triangle_buffer;

    unsigned idx_count = PolygonToTriangles(points + start, size,
                                            triangle_buffer);
    if (idx_count == 0)
      return;

    /* add offset to all vertex indices */
    for (unsigned i = 0; i < idx_count; ++i)
      triangle_buffer[i] += start;

    glDrawElements(GL_TRIANGLES, idx_count, GL_UNSIGNED_SHORT,
                   triangle_buffer.begin());
  }
Ejemplo n.º 2
0
void
Canvas::DrawPolygon(const RasterPoint *points, unsigned num_points)
{
  if (brush.IsHollow() && !pen.IsDefined())
    return;

#ifdef USE_GLSL
  OpenGL::solid_shader->Use();
#endif

  ScopeVertexPointer vp(points);

  if (!brush.IsHollow() && num_points >= 3) {
    brush.Bind();
    
    std::unique_ptr<const GLBlend> blend; 
    if(!brush.IsOpaque()) {
      blend = std::make_unique<const GLBlend>(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    }
    
    static AllocatedArray<GLushort> triangle_buffer;
    unsigned idx_count = PolygonToTriangles(points, num_points,
                                            triangle_buffer);
    if (idx_count > 0)
      glDrawElements(GL_TRIANGLES, idx_count, GL_UNSIGNED_SHORT,
                     triangle_buffer.begin());
  }

  if (IsPenOverBrush()) {
    pen.Bind();

    if (pen.GetWidth() <= 2) {
      glDrawArrays(GL_LINE_LOOP, 0, num_points);
    } else {
      unsigned vertices = LineToTriangles(points, num_points, vertex_buffer,
                                          pen.GetWidth(), true);
      if (vertices > 0) {
        vp.Update(vertex_buffer.begin());
        glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices);
      }
    }

    pen.Unbind();
  }
}
Ejemplo n.º 3
0
void
Canvas::DrawPolygon(const RasterPoint *points, unsigned num_points)
{
  if (brush.IsHollow() && !pen.IsDefined())
    return;

  glVertexPointer(2, GL_VALUE, 0, points);

  if (!brush.IsHollow() && num_points >= 3) {
    brush.Set();

    static AllocatedArray<GLushort> triangle_buffer;
    unsigned idx_count = PolygonToTriangles(points, num_points,
                                            triangle_buffer);
    if (idx_count > 0)
      glDrawElements(GL_TRIANGLES, idx_count, GL_UNSIGNED_SHORT,
                     triangle_buffer.begin());
  }

  if (pen_over_brush()) {
    pen.Bind();

    if (pen.GetWidth() <= 2) {
      glDrawArrays(GL_LINE_LOOP, 0, num_points);
    } else {
      unsigned vertices = LineToTriangles(points, num_points, vertex_buffer,
                                          pen.GetWidth(), true);
      if (vertices > 0) {
        glVertexPointer(2, GL_VALUE, 0, vertex_buffer.begin());
        glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices);
      }
    }

    pen.Unbind();
  }
}
Ejemplo n.º 4
0
void Flasher::RenderSetup(RenderDevice* pd3dDevice)
{
   std::vector<RenderVertex> vvertex;
   GetRgVertex(vvertex);

   numVertices = (unsigned int)vvertex.size();

   std::vector<WORD> vtri;
   
   {
   std::vector<unsigned int> vpoly(numVertices);
   for (unsigned int i = 0; i < numVertices; i++)
      vpoly[i] = i;

   PolygonToTriangles(vvertex, vpoly, vtri);
   }

   numPolys = (int)(vtri.size()/3);
   if (numPolys == 0)
   {
      // no polys to render leave vertex buffer undefined 
      return;
   }

   if (dynamicIndexBuffer)
      dynamicIndexBuffer->release();
   pd3dDevice->CreateIndexBuffer(numPolys * 3, 0, IndexBuffer::FMT_INDEX16, &dynamicIndexBuffer);
   NumVideoBytes += numPolys * 3 * sizeof(WORD);

   WORD* bufi;
   dynamicIndexBuffer->lock(0, 0, (void**)&bufi, 0);
   memcpy(bufi, vtri.data(), vtri.size()*sizeof(WORD));
   dynamicIndexBuffer->unlock();

   if (dynamicVertexBuffer)
      dynamicVertexBuffer->release();
   pd3dDevice->CreateVertexBuffer(numVertices, USAGE_DYNAMIC, MY_D3DFVF_TEX, &dynamicVertexBuffer);
   NumVideoBytes += (int)(numVertices*sizeof(Vertex3D_TexelOnly));

   if (vertices)
      delete[] vertices;
   vertices = new Vertex3D_TexelOnly[numVertices];

   Pin3D * const ppin3d = &g_pplayer->m_pin3d;

   minx = FLT_MAX;
   miny = FLT_MAX;
   maxx = -FLT_MAX;
   maxy = -FLT_MAX;

   for (unsigned int i = 0; i < numVertices; i++)
   {
      const RenderVertex * const pv0 = &vvertex[i];

      vertices[i].x = pv0->x;
      vertices[i].y = pv0->y;
      vertices[i].z = 0;

      if (pv0->x > maxx) maxx = pv0->x;
      if (pv0->x < minx) minx = pv0->x;
      if (pv0->y > maxy) maxy = pv0->y;
      if (pv0->y < miny) miny = pv0->y;
   }

   const float inv_width = 1.0f / (maxx - minx);
   const float inv_height = 1.0f / (maxy - miny);
   const float inv_tablewidth = 1.0f / (m_ptable->m_right - m_ptable->m_left);
   const float inv_tableheight = 1.0f / (m_ptable->m_bottom - m_ptable->m_top);
   m_d.m_vCenter.x = minx + ((maxx - minx)*0.5f);
   m_d.m_vCenter.y = miny + ((maxy - miny)*0.5f);

   for (unsigned int i = 0; i < numVertices; i++)
   {
      if (m_d.m_imagealignment == ImageModeWrap)
      {
         vertices[i].tu = (vertices[i].x - minx)*inv_width;
         vertices[i].tv = (vertices[i].y - miny)*inv_height;
      }
      else
      {
         vertices[i].tu = vertices[i].x*inv_tablewidth;
         vertices[i].tv = vertices[i].y*inv_tableheight;
      }
   }
}
Ejemplo n.º 5
0
bool
XShape::BuildIndices(unsigned thinning_level, unsigned min_distance)
{
  assert(indices[thinning_level] == NULL);

  unsigned short *idx, *idx_count;
  unsigned num_points = 0;

  for (unsigned i=0; i < num_lines; i++)
    num_points += lines[i];

  if (type == MS_SHAPE_LINE) {
    if (num_points <= 2)
      return false;  // line cannot be simplified, so don't create indices
    index_count[thinning_level] = idx_count =
      new GLushort[num_lines + num_points];
    indices[thinning_level] = idx = idx_count + num_lines;

    const unsigned short *end_l = lines + num_lines;
    const ShapePoint *p = points;
    unsigned i = 0;
    for (const unsigned short *l = lines; l < end_l; l++) {
      assert(*l >= 2);
      const ShapePoint *end_p = p + *l - 1;
      // always add first point
      *idx++ = i;
      p++; i++;
      const unsigned short *after_first_idx = idx;
      // add points if they are not too close to the previous point
      for (; p < end_p; p++, i++)
        if (manhattan_distance(points[idx[-1]], *p) >= min_distance)
          *idx++ = i;
      // remove points from behind if they are too close to the end point
      while (idx > after_first_idx &&
             manhattan_distance(points[idx[-1]], *p) < min_distance)
        idx--;
      // always add last point
      *idx++ = i;
      p++; i++;
      *idx_count++ = idx - after_first_idx + 1;
    }
    // TODO: free memory saved by thinning (use malloc/realloc or some class?)
    return true;
  } else if (type == MS_SHAPE_POLYGON) {
    index_count[thinning_level] = idx_count =
      new GLushort[1 + 3*(num_points-2) + 2*(num_lines-1)];
    indices[thinning_level] = idx = idx_count + 1;

    *idx_count = 0;
    const ShapePoint *pt = points;
    for (unsigned i=0; i < num_lines; i++) {
      unsigned count = PolygonToTriangles(pt, lines[i], idx + *idx_count,
                                          min_distance);
      if (i > 0) {
        const GLushort offset = pt - points;
        const unsigned max_idx_count = *idx_count + count;
        for (unsigned j=*idx_count; j < max_idx_count; j++)
          idx[j] += offset;
      }
      *idx_count += count;
      pt += lines[i];
    }
    *idx_count = TriangleToStrip(idx, *idx_count, num_points, num_lines);
    // TODO: free memory saved by thinning (use malloc/realloc or some class?)
    return true;
  } else {
    assert(false);
    return false;
  }
}