2012-05-29 1 views
2
public Cube(int x, int y, int z, int x2, int y2, int z2){ 
    int tmpX = x; 
    int tmpY = y; 
    int tmpZ = z; 

    if(x > x2){x = x2; x2 = tmpX;} 
    if(y > y2){y = y2; y2 = tmpY;} 
    if(z > z2){z = z2; z2 = tmpZ;} 

    int centerX = x2 - x; 
    int centerY = y2 - y; 
    int centerZ = z2 - z; 

    GL11.glTranslatef(centerX, centerY, centerZ); 
    GL11.glRotatef(rot, 0f, 0f, 1f); 
    GL11.glBegin(GL11.GL_QUADS); 

     //front 
     color(255, 0, 0); 
     v3d(x, y, z); 
     v3d(x, y2, z); 
     v3d(x2, y2, z); 
     v3d(x2, y, z); 

     //top 
     color(0, 255, 0); 
     v3d(x, y, z); 
     v3d(x2, y, z); 
     v3d(x2, y, z2); 
     v3d(x, y, z2); 

     //back 
     color(0, 0, 255); 
     v3d(x2, y2, z2); 
     v3d(x, y2, z2); 
     v3d(x, y, z2); 
     v3d(x2, y, z2); 

     //bottom 
     color(255, 255, 0); 
     v3d(x, y2, z); 
     v3d(x2, y2, z); 
     v3d(x2, y2, z2); 
     v3d(x, y2, z2); 

     //left 
     color(255, 0, 255); 
     v3d(x, y, z); 
     v3d(x, y2, z); 
     v3d(x, y2, z2); 
     v3d(x, y, z2); 

     //right 
     color(0, 255, 255); 
     v3d(x2, y, z); 
     v3d(x2, y2, z); 
     v3d(x2, y2, z2); 
     v3d(x2, y, z2); 

    GL11.glEnd(); 
    GL11.glRotatef(-rot, 0f, 0f, 1f); 
    GL11.glTranslatef(-centerX, -centerY, -centerZ); 

    rot += 0.75f; 
    if(rot > 360){ 
     rot -= 360; 
    } 
} 

Я не понимаю, почему это не вращается вокруг оси Z непосредственно вокруг самого объекта куба, вместо этого оно просто поворачивается вокруг 0,0,0 в матрице.Почему этот код JOGL не переводится правильно?

Я также попытался это для центрирования кода:

 int xWidth = x2 - x; 
    int yWidth = y2 - y; 
    int zWidth = z2 - z; 

    int centerX = x + (xWidth/2); 
    int centerY = y + (yWidth/2); 
    int centerZ = z + (zWidth/2); 

Но первый один больше смысла после тестирования некоторой математики (15 - 5 = 10, 15 + 7,5 = 12,5). Любые идеи?

+0

Я не знаю, если с моим решением вы получите желаемый результат (я не совсем понял ваш запрос), но вы должны попробовать в первом источнике без дополнительных изменений обменять вызов на glTranslate и вызов glRotate. Потому что в OpenGL порядок преобразований имеет значение. Надеюсь, это вам поможет. (В общем, вы должны закодировать преобразования с glRotate, glTranslate, glScale в обратном порядке желаемых преобразований.) Кроме того, чтобы сохранить/восстановить преобразования, посмотрите glPushMatrix() и glPopMatrix(). – loloof64

ответ

1

Я думаю, что вы, возможно, пытаетесь перенести свое изучение математических преобразований слишком прямо в OpenGL. Интерпретируя то, что вы написали буквально, вы переводите с места происхождения, применяя поворот, а затем пытаетесь отменить оба из них в направлении снизу, в обратном порядке. Похоже, вы пытаетесь «отменить» преобразования для некоторых других преобразований, которые произойдут позже.

Когда мы говорим об преобразованиях математически, это имеет смысл, но в коде есть хороший ярлык в glPushMatrix() и glPopMatrix(), где вы можете использовать оба варианта, чтобы «обернуть» ваши преобразования в определенной области. Это очень похоже на область функций или область цикла - любые преобразования, происходящие в этом блоке, не будут влиять на что-либо вне этой области.

Хорошо:

GL11.glTranslatef(centerX, centerY, centerZ); 
GL11.glRotatef(rot, 0f, 0f, 1f); 

Это относится ваши преобразования к CenterX, centerY и centerZ, а затем применяет ваше вращение вокруг оси.

Плохая:

GL11.glRotatef(-rot, 0f, 0f, 1f); 
GL11.glTranslatef(-centerX, -centerY, -centerZ); 

glRotatef и glTranslatef здесь не нужны и могут быть закомментированы или удалены.

Это, как вы бы определить объем одного «объекта» с помощью кода:

GL11.glPushMatrix(); 
// Apply transformations here 
GL11.glBegin(GL11.GL_QUADS); 

    // Draw object here 

GL11.glEnd(); 
GL11.glPopMatrix(); 

Так что, если вы хотите, чтобы включить другие объекты, которые не будут зависеть от преобразования и вращения вашего куб, вы бы обернули эти преобразования в блок Push/Pop. Вот еще question, который охватывает толкание и выскакивание немного лучше, чем у меня здесь.