示例#1
0
 void compileTo(VertexArrays& vas)
 {
     if (!glBlocks.empty())
         throw std::logic_error("Custom code cannot be recorded into a macro");
     
     std::stable_sort(ops.begin(), ops.end());
     for (DrawOps::const_iterator op = ops.begin(), end = ops.end(); op != end; ++op)
         op->compileTo(vas);
 }
示例#2
0
 // I really wish I would trust ADL. :|
 void swap(DrawOpQueue& other)
 {
     clipRectStack.swap(other.clipRectStack);
     std::swap(effectiveRect, other.effectiveRect);
     std::swap(haveEffectiveRect, other.haveEffectiveRect);
     ops.swap(other.ops);
     code.swap(other.code);
 }
示例#3
0
 void clear()
 {
     // Not sure if Graphics::begin() should implicitly do that.
     //clipRectStack.clear();
     //effectiveRect.reset();
     code.clear();
     ops.clear();
 }
示例#4
0
 void performDrawOpsAndCode()
 {
     // Allows us to make some assumptions.
     if (ops.empty())
     {
         for (CodeMap::iterator it = code.begin(), end = code.end(); it != end; ++it)
             it->second();
         return;
     }
     
     // Apply Z-Ordering.
     std::stable_sort(ops.begin(), ops.end());
     
     // We will loop: Drawing DrawOps, execute custom code.
     // This means if there is no code, we just draw one batch
     // of DrawOps, so no performance is sacrified.
     DrawOps::const_iterator current = ops.begin(), last = ops.begin();
     CodeMap::const_iterator it = code.begin();
     
     while (true)
     {
         if (it == code.end())
             // Last or only batch of DrawOps:
             // Just draw everything.
             last = ops.end() - 1;
         else
         {
             // There is code waiting:
             // Only draw up to this Z level.
             while (last != ops.end() - 1 && (last + 1)->z < it->first)
                 ++last;
         }
         
         if (current <= last)
         {
             // Draw DrawOps until next code is due
             RenderState renderState;
             while (current < last)
             {
                 DrawOps::const_iterator next = current + 1;
                 current->perform(renderState, &*next);
                 current = next;
             }
             last->perform(renderState, 0);
             ++current;
         }
         
         // Draw next code, or break if there is none
         if (it == code.end())
             break;
         else
         {
             it->second();
             ++it;
         }
     }
 }
示例#5
0
 void clear()
 {
     absoluteTransforms.resize(1);
     // Important!! Due to all the swapping, the first entry in the list is not necessarily
     // the base matrix. We need to restore it.
     absoluteTransforms.front() = scale(1);
     individualTransforms.resize(1);
     clipRectStack.clear();
     glBlocks.clear();
     ops.clear();
 }
示例#6
0
 void scheduleDrawOp(DrawOp op)
 {
     if (clipRectStack.clippedWorldAway())
         return;
     
     #ifdef GOSU_IS_IPHONE
     // No triangles, no lines supported
     assert (op.verticesOrBlockIndex == 4);
     #endif
     
     op.renderState.transform = &currentTransform();
     if (const ClipRect* cr = clipRectStack.maybeEffectiveRect())
         op.renderState.clipRect = *cr;
     ops.push_back(op);
 }
示例#7
0
 void scheduleGL(std::tr1::function<void()> glBlock, ZPos z)
 {
     // TODO: Document this case: Clipped-away GL blocks are *not* being run.
     if (clipRectStack.clippedWorldAway())
         return;
     
     int complementOfBlockIndex = ~(int)glBlocks.size();
     glBlocks.push_back(glBlock);
     
     DrawOp op;
     op.verticesOrBlockIndex = complementOfBlockIndex;
     op.renderState.transform = &currentTransform();
     if (const ClipRect* cr = clipRectStack.maybeEffectiveRect())
         op.renderState.clipRect = *cr;
     op.z = z;
     ops.push_back(op);
 }
示例#8
0
 void scheduleDrawOp(DrawOp op, ZPos z)
 {
     #ifdef GOSU_IS_IPHONE
     // No triangles, no lines supported
     assert (op.usedVertices == 4);
     #endif
     
     if (haveEffectiveRect)
     {
         op.clipX      = effectiveRect.x;
         op.clipY      = effectiveRect.y;
         op.clipWidth  = effectiveRect.width;
         op.clipHeight = effectiveRect.height;
     }
     else if (!clipRectStack.empty())
         // When we have no effect rect but the stack is not empty, we have clipped
         // the whole world away and don't need to render things.
         return;
     
     op.z = z;
     ops.push_back(op);
 }
示例#9
0
 void performDrawOpsAndCode()
 {
     // Apply Z-Ordering.
     std::stable_sort(ops.begin(), ops.end());
     
     RenderStateManager manager;
     #ifdef GOSU_IS_IPHONE
     if (ops.empty())
         return;
     
     DrawOps::const_iterator current = ops.begin(), last = ops.end() - 1;
     for (; current != last; ++current)
     {
         manager.setRenderState(current->renderState);
         current->perform(&*(current + 1));
     }
     manager.setRenderState(last->renderState);
     last->perform(0);
     #else
     for (DrawOps::const_iterator current = ops.begin(), last = ops.end();
         current != last; ++current)
     {
         manager.setRenderState(current->renderState);
         if (current->verticesOrBlockIndex >= 0)
             current->perform(0);
         else
         {
             // GL code
             int blockIndex = ~current->verticesOrBlockIndex;
             assert (blockIndex >= 0);
             assert (blockIndex < glBlocks.size());
             glBlocks[blockIndex]();
             manager.enforceAfterUntrustedGL();
         }
     }
     #endif
 }
示例#10
0
 // This retains the current stack of transforms and clippings.
 void clearQueue()
 {
     glBlocks.clear();
     ops.clear();
 }