Я пытаюсь создать 5×5 шахматную доску в OpenGL. Мне удалось спроектировать 5×6 и 8×8, но код для 5×5 просто не будет работать.
Может кто-нибудь просмотреть код и, возможно, указать, где моя ошибка, поскольку ширина просто не изменится на 5?
Вот часть кода, с которой у меня проблема:
void drawScene()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-2.5*1.5, 0.0, 2.5*1.5);
for(double j=0.0;j>(-5*1.5);j-=1.5)
{
k++;
for(i=0.0;i<(2.5*3.0);i+=3.0)
{
if(k%2!=0)
{
glPushMatrix();
glTranslatef(i,0.0,j);
glCallList(_displayListId_blackArea);
glPopMatrix();
}
else
{
glPushMatrix();
glTranslatef(i+1.5,0.0,j);
glCallList(_displayListId_blackArea);
glPopMatrix();
}
}
}
for(double j=0.0;j>(-5*1.5);j-=1.5)
{
k++;
for(i=0.0;i<(2.5*3.0);i+=3.0)
{
if(k%2!=0)
{
glPushMatrix();
glTranslatef(i,0.0,j);
glCallList(_displayListId_whiteArea);
glPopMatrix();
}
else
{
glPushMatrix();
glTranslatef(i+1.5,0.0,j);
glCallList(_displayListId_whiteArea);
glPopMatrix();
}
}
}
}
Сначала поймите свою проблему. Вы должны рисовать нечетное против четного для черного против белой доски, что означает, что в первом ряду вы рисуете нечетную белую доску, тогда вы должны рисовать четную черную доску, а в следующем ряду четную белую доску и нечетную черную доску. Для заполнения шахматной фигуры 5 * 5 для белых и черных досок ряд ниже приведен:
3*2
2*3
3*2
2*3
3*2
Но код, который вы предоставляете, предназначен для равного количества белой и черной доски, поэтому вы должны изменить логику. Вот часть кода, где я использовал свою логику, чтобы нарисовать 5 * 5 шахматную доску, и она отлично работает.
for(float j=0.0;j>(-5*1.5);j-=1.5)
{
k++;
//for(i=0.0;i<(4*3.0);i+=3.0)
//{
if(k%2==0)
{
for(i=0.0;i<(3*3.0);i+=3.0){
glPushMatrix();
glTranslatef(i,0.0,j);
glCallList(_displayListId_blackArea);
glPopMatrix();
}
}
else
{
for(i=0.0;i<(2*3.0);i+=3.0){
glPushMatrix();
glTranslatef(i+1.5,0.0,j);
glCallList(_displayListId_blackArea);
glPopMatrix();
}
}
//}
}
k=0;
for(float j=0.0;j>(-5*1.5);j-=1.5)
{
k++;
//for(i=0.0;i<(4*3.0);i+=3.0)
//{
if(k%2!=0)
{
for(i=0.0;i<(3*3.0);i+=3.0){
glPushMatrix();
glTranslatef(i,0.0,j);
glCallList(_displayListId_whiteArea);
glPopMatrix();
}
}
else
{
for(i=0.0;i<(2*3.0);i+=3.0){
glPushMatrix();
glTranslatef(i+1.5,0.0,j);
glCallList(_displayListId_whiteArea);
glPopMatrix();
}
}
}
k=0;
glutSwapBuffers();
}
Если у вас есть нечетное количество столбцов, ваш «нечетный против четного» для черного против белого будет отличаться от того, если у вас есть четное число. Я думаю, что самый простой способ — сделать один цикл для всех квадратов и сохранить bool white_or_black
переменная, которая установлена в white_or_black = !white_or_black
в конце каждого цикла.
Существует также большое количество дублированного кода, который можно сделать намного проще, если использовать один цикл вместо двух.
[Я не уверен на 100%, что идет не так в твоем коде, поэтому я не уверен, что это на самом деле решит проблему — но я считаю, что это заслуживает улучшения].Я подозреваю, что «ширина не изменится на 5», вы наблюдаете ширину 4 или 6. Это было бы правильно? Вполне вероятно, что в этом случае будет ошибка из-за арифметики двойной точности.
Видите ли, вы предполагаете бесконечную точность в своих циклах, но вполне возможно, что 5*1.5
это не то же самое, что добавление 1.5
пять раз.
Что вам действительно нужно сделать, так это создать целочисленный цикл от 1 до 5 (или от 0 до 4), а затем умножить это значение на размер квадрата, чтобы получить координату. Обычно не стоит зацикливаться на двойниках, если вы не знаете, что делаете и что может произойти.
Еще одна вещь, которую вы должны сделать, это использовать константы вместо литералов. Вместо того, чтобы засунуть свой код с номером 5
почему бы не определить:
const int BoardWidth = 5;
const int BoardHeight = 5;
Тогда это будет намного легче изменить.
Забудьте этот код, у него плохой потенциал, вы должны использовать int как счетчик для создания доски. Например:
const unsigned BOARD_SIZE = 5;
for(unsigned i = 0; i < BOARD_SIZE; ++i){
for(unsigned j = 0; j < BOARD_SIZE; ++j){
drawBoardCell(i,j, (i*BOARD_SIZE + j) % 2 == 0);
}
}
void drawBoardCell(const int row, const int col, const bool isBlack){
glPushMatrix();
glTranslatef(col+1.5,0.0,row);
const int callId = isBlack ? _displayListId_blackArea : _displayListId_whiteArea;
glCallList(callId);
glPopMatrix();
}
Это может не сработать с первого раза, но это должно дать вам отправную точку.