Моя игра в C # использует OpenTK, который является оболочкой для OpenGL. Я рендерил свою мини-карту, как показано ниже. Проблема в том, что объекты не обрезаны по краям, поэтому они кровоточат. Я мог бы сделать более толстую границу, чтобы скрыть ее, но это не идеально, и это не будет работать для более крупных объектов. Там могут быть линии траектории и другие вещи, которые также выходят за пределы. Я просто отрисовываю их, используя базовые примитивы.
Как я могу обрезать этот регион? Есть ли способ сделать это на скрытом холсте, а затем скопировать только круговую область?
1012 * РЕШЕНИЕ *
@ BDL ответил на вопрос, но мне пришлось настроить еще несколько вещей, чтобы заставить его работать, поэтому вот полное решение на тот случай, если кто-нибудь найдет его полезным:
Включить буфер трафарета в параметре GraphicsMode конструктора GameWindow.
private static OpenTK.Graphics.GraphicsMode GraphicsMode {
get {
var defaultMode = OpenTK.Graphics.GraphicsMode.Default;
var custom = new OpenTK.Graphics.GraphicsMode(
defaultMode.ColorFormat,
defaultMode.Depth,
1, // enable stencil buffer
defaultMode.Samples,
defaultMode.ColorFormat,
defaultMode.Buffers,
defaultMode.Stereo);
return custom;
}
}
public BaseHelioUI(int windowWidth, int windowHeight)
: base(
windowWidth,
windowHeight,
BaseHelioUI.GraphicsMode,
"",
GameWindowFlags.Default )
{
Затем используйте этот блок, чтобы нарисовать трафарет, который в моем случае представляет собой круг:
GL.Enable(EnableCap.StencilTest);
GL.StencilFunc(StencilFunction.Always, 1, 0xFF);
GL.StencilOp( StencilOp.Keep, StencilOp.Keep, StencilOp.Replace );
GL.Clear(ClearBufferMask.StencilBufferBit);
// draw background & outline
this.Renderer.DrawCircle(
this.MinimapScreenCenter,
SENSOR_RANGE_IN_METERS * this.GameMetersToMinimapUnitsFactor,
Colors.ReduceAlpha( Colors.Black, MINIMAP_BACKGROUND_OPACITY )
//Colors.ReduceAlpha( Colors.DarkGrey, MINIMAP_BACKGROUND_OUTLINE_OPACITY),
//MINI_MAP_BORDER_WIDTH
);
GL.Enable(EnableCap.StencilTest);
GL.StencilFunc(StencilFunction.Equal, 1, 0xFF);
GL.StencilOp(StencilOp.Keep, StencilOp.Keep, StencilOp.Keep);
Затем нарисуйте все, что вы хотите в этом регионе, которые являются элементами на миникарте в моем случае.
Затем, когда вы закончите с использованием трафарета, просто очистите его, чтобы все остальное отображалось нормально. В моем случае это конец метода RenderMinimap.
// disable stencil
GL.Clear(ClearBufferMask.StencilBufferBit);
GL.Disable(EnableCap.StencilTest);
Вот полученная миникарта, правильно обрезающая предметы по краю круга. Выглядит отлично. (корабль находится в игровом пространстве, а не на миникарте)