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()); }
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(); } }
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(); } }
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; } } }
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; } }