Да, можно делать то, что вы хотите.Это, вероятно, не будет простым переходом из-за того, что код, который вы разместили, использует очень старые устаревшие функции OpenGL.Кроме того, вам может быть лучше использовать CoreGraphics для простого рисования, которое вы делаете.(Похоже, нарисовано несколько сплошных квадратов. Это очень просто и достаточно эффективно в CoreGraphics.) Металл кажется излишним для этой работы.Тем не менее, вот несколько идей.
Metal - это по сути Objective-C API, поэтому вам нужно будет обернуть код Metal в какую-то оболочку.Есть несколько способов написать такую обертку.Вы можете создать класс Objective-C, который будет рисовать, и вызвать его из своего класса C ++ / Qt.(Вам нужно поместить ваш класс Qt в файл .mm, чтобы компилятор обрабатывал его как Objective-C ++ для вызова кода Objective-C.) Или вы можете сделать свой класс Qt абстрактным классом, который имеет указатель реализации накласс, который делает реальную работу.В Windows и Linux он может указывать на объект, который выполняет рисование OpenGL.В macOS это будет указывать на ваш класс Objective C ++, который использует Metal для рисования.
Этот пример смешивания OpenGL и Metal может быть информативным для понимания того, как эти 2 похожи и где они различаются,Вместо того, чтобы иметь контекст, в котором вы устанавливаете состояние и делаете вызовы рисования, как в OpenGL, в Metal вы создаете буфер команд с командами рисования, а затем отправляете их для рисования.Как и в более современном программировании OpenGL, где у вас есть массивы вершин и вы применяете вершинный и фрагментный шейдеры к каждому фрагменту геометрии, в Metal вы также будете отправлять вершины и использовать фрагмент и вершинный шейдер для рисования.
Если честноТем не менее, это звучит как большая работа.(Но это, безусловно, возможно.) Если бы вы делали это в CoreGraphics, это выглядело бы примерно так:
virtual void paintCG()
{
const float meterWidth = [...];
const float top = [...];
CGRect backgroundRect = CGRectMake(...);
CGContextClearRect(ctx, backgroundRect);
float x = 0.0f;
for (int i=0; i<numMeters; i++)
{
const float y = _meterHeight[i];
CGContextSetRGBFillColor(ctx, _meterColorRed[i], _meterColorGreen[i], _meterColorBlue[i]);
CGRect meterRect = CGRectMake(x, y, meterWidth, _meterHeight[i]);
CGContextFillRect(ctx, meterRect);
x += meterWidth;
}
glEnd();
}
Это просто требует, чтобы у вас был CGContextRef
, который, я полагаю, вы можете получить отв любое окно, в которое вы входите.Если окно NSWindow
, то вы можете позвонить:
NSGraphicsContext* nsContext = [window graphicsContext];
CGContextRef ctx = nsContext.CGContext;
Это кажется более простым в написании и обслуживании, чем использование Metal в этом случае.