opengl中的棋盘

Chessboard in opengl

本文关键字:opengl      更新时间:2023-10-16

我正在OpenGL中创建5x5棋盘。我已经能够设计5x6和8x8,但代码不适用于5x5。有人能看看代码,也许指出我的错误在哪里,因为宽度不会变为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();
            }
        }
    }
}

如果列数为奇数,则黑色与白色的"奇数与偶数"将与偶数不同。我认为最简单的方法是对所有Squares执行一个循环,并在每个循环结束时保留一个设置为white_or_black = !white_or_blackbool white_or_black变量。

还有大量重复的代码,通过使用一个循环而不是两个循环可以使其变得更简单。

[我不能100%确定你的代码出了什么问题,所以我不确定这是否真的能解决问题,但我相信这是一个值得改进的地方]。

首先了解您的问题。你必须画奇数和偶数的黑色和白色的板,这意味着在第一行,如果你画奇数的白色板,那么你必须画偶数的黑色板,在下一行,画偶数的白色板和奇数的黑色板。对于完成白色和黑色棋盘的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();
}

我怀疑通过"宽度不会变为5",您观察到的宽度是4或6。这是正确的吗?在这种情况下,很可能是由于双精度算术造成的错误。

你看,你假设循环中的精度是无限的,但可以想象,5*1.51.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();
}

这可能在第一次尝试时不起作用,但它应该给你一个起点。