Я пытаюсь создать движок рендеринга в стиле дум, используя SDL2, но у меня немного проблем с производительностью. Я использую его на своем ноутбуке, который использует AMD Radeon R7 M260X, но я едва могу поддерживать стабильную скорость работы программы со скоростью 60 кадров в секунду, и программа использует около 40% графического процессора. окно, в которое я рендеринг, - 1067/600.
на данный момент камера использует фиксированный угол наклона камеры
void drawWall(XY p1, XY p2, XY p3, XY p4, float dis1, float dis2)
{
float dx1 = 0;
float dx2 = 0;
float dDis = 0;
float y1 = p1.Y;
float y2 = p3.Y;
float dis = dis1;
int xLen = p2.X - p1.X;
if (p2.X - p1.X != 0)
dx1 = (p2.Y - p1.Y) / (p2.X - p1.X);
if (p4.X - p3.X != 0)
dx2 = (p4.Y - p3.Y) / (p4.X - p3.X);
if (dis2 - dis1 != 0)
dDis = (dis2 - dis1) / (p2.X - p1.X);
float du = 0;
if (p1.X < 0)
{
int d1 = - p1.X;
du = d1;
p1.X = 0;
y1 += dx1*d1;
y2 += dx2*d1;
dis += dDis*d1;
}
float o = 100*(1/(dis));
for (int x1 = p1.X; x1 <= p2.X && x1 < SCREEN_WIDTH; x1++, y1 += dx1, y2 += dx2, dis += dDis, du++)
{
SDL_Rect r1 = { (du / (xLen+1))*gField4.getWidth(), 0, 1, gField4.getHeight()};
SDL_Rect r2 = {x1, y2, 1, y1-y2};
//float shade = 252 - dis;
//gField4.setColorMod(shade, shade, shade);
gField4.render(0, 0, &r1, &r2);
}
}
void drawFloor(XY Camera, float height)
{
float fowHalf = M_PI / 4;
float farP = height;
float nearP = 0;
XY far1 = {Camera.X + cosf(-M_PI/2 - fowHalf)*farP, Camera.Y + sinf(-M_PI / 2 - fowHalf)*farP };
XY near1 = { Camera.X + cosf(-M_PI / 2 - fowHalf)*nearP, Camera.Y + sinf(-M_PI / 2 - fowHalf)*nearP };
XY far2 = { Camera.X + cosf(-M_PI / 2 + fowHalf)*farP, Camera.Y + sinf(-M_PI / 2 + fowHalf)*farP };
XY near2 = { Camera.X + cosf(-M_PI / 2 + fowHalf)*nearP, Camera.Y + sinf(-M_PI / 2 + fowHalf)*nearP };
for (int i = 1; i < SCREEN_HEIGHT/2; i++)
{
float sampleDept = (float)i / ((float)SCREEN_HEIGHT / 2.0f);
XY start = {(far1.X - near1.X)/sampleDept + near1.X, (far1.Y - near1.Y)/sampleDept + near1.Y };
XY end = { (far2.X - near2.X)/sampleDept + near2.X, (far2.Y - near2.Y)/sampleDept + near2.Y };
SDL_Rect r1 = {start.X*gField3.getWidth(),start.Y*gField3.getHeight(), end.X*gField3.getWidth()- start.X*gField3.getWidth() , 1 };
SDL_Rect r2 = {0, i+ SCREEN_HEIGHT / 2, SCREEN_WIDTH, 1 };
if (r1.x < 0)
{
float d = -(float)r1.x / (float)r1.w;
r2.x = SCREEN_WIDTH*d;
r2.w = SCREEN_WIDTH - SCREEN_WIDTH*d;
}
if (r1.x+ r1.w > gField3.getWidth())
{
float d = ((float)r1.x + (float)r1.w - (float)gField3.getWidth())/ (float)r1.w;
r2.w = r2.w - r2.w*d;
}
gField3.render(0, 0, &r1, &r2);
}
}
void drawWalls(XY Camera, double height)
{
for (Wall wall : walls)
{
XY xy1 = wall.xy1;
XY xy2 = wall.xy2;
if (wall.xy1.X < wall.xy2.X)
{
xy2 = wall.xy1;
xy1 = wall.xy2;
}
XY l1 = { xy1.X - Camera.X, xy1.Y - Camera.Y };
XY l2 = { xy2.X - Camera.X, xy2.Y - Camera.Y };
double Zdis1 = l1.Y;
double Xdis1 = l1.X;
double Zdis2 = l2.Y;
double Xdis2 = l2.X;
XY point1 = { -Xdis1 * (SCREEN_WIDTH / 2) / Zdis1, 10*SCREEN_WIDTH / Zdis1 };
XY point2 = { -Xdis2 * (SCREEN_WIDTH / 2) / Zdis2, 10*SCREEN_WIDTH / Zdis2 };
XY p1 = { SCREEN_WIDTH / 2 + point1.X, SCREEN_HEIGHT / 2 - (wall.h1 - height)*point1.Y };
XY p2 = { SCREEN_WIDTH / 2 + point2.X, SCREEN_HEIGHT / 2 - (wall.h1 - height)*point2.Y };
XY p3 = { SCREEN_WIDTH / 2 + point1.X, SCREEN_HEIGHT / 2 - (wall.h2 - height)*point1.Y };
XY p4 = { SCREEN_WIDTH / 2 + point2.X, SCREEN_HEIGHT / 2 - (wall.h2 - height)*point2.Y };
if (!((p1.X < 0 && p2.X < 0) || (p1.X > SCREEN_WIDTH && p2.X > SCREEN_WIDTH)))
{
drawWall( p1, p2, p3, p4, l1.Y, l2.Y);
}
}
}
метод .render () для полей g рендеринга фрагмента текстуры с использованием SDL_RenderCopyEx ()
Я пытался закомментировать вызовы метода gfields.render (), что снижает использование графического процессора до 40%, поэтому я предполагаю, что это потому, что я вызываю SDL_RenderCopyEx () пару раз по 1000 раз за кадр, что вызывая проблему с производительностью.
Но я на самом деле не знаю, что я могу сделать, чтобы это исправить, так как я должен отрисовывать каждую линию стены и пола по отдельности, кто-нибудь знает, как я могу повысить производительность здесь?