2012-06-28 3 views
0

OpenGL 내부의 x 축 주위로 회전하는 데 약간의 문제가 있습니다. 내가 가지고있는 것은 조명 계산을위한 법선과 함께 셰이더 내부에서 렌더링되는 기본 큐브입니다. 큐브의 변환은 투영 행렬에 모델 행렬을 곱한 것입니다. 이 연결은 쉐이더 내부에서 이루어지며, 회전 및 변환 계산은 필자가 작성한 Matrix 클래스에서 수행됩니다. 어떤 회전이 y 축 중심이 완료되면, 모든 것이이 그림 같이 예상 회전 할 때 : 다음과 같이 어떤 회전은 x 축 주위에 발생하는 경우OpenGL 회전 왜곡 된 문제

Render Result Render Result

문제점 시작 :

Render Result Render Result

은 분명히 x 축 회전이 장면을 왜곡하고 균형이 맞지 표시 할 모든 원인이됩니다.

glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 

viewMatrix.setIdentity(); 
viewMatrix.translate(new Vector4(translation)); 
viewMatrix.rotate(1, 0, 0, -rotateX); 
viewMatrix.rotate(0, 1, 0, rotateY); 
Matrix4 mvMatrix = new Matrix4(viewMatrix); 

Matrix4 pMatrix = new Matrix4(projectionMatrix); 

lightShader.useShader();   
lightShader.setUniformVector("vColor", new Vector4(.4f,0,0,1f)); 
lightShader.setUniformMatrix("mvMatrix", mvMatrix); 
lightShader.setUniformMatrix("pMatrix", pMatrix); 
triangleBatch.draw(lightShader.getAttributes()); 

Display.update(); 

셰이더 코드는 다음과 같다 :

uniform mat4 mvMatrix; 
uniform mat4 pMatrix; 
uniform vec4 vColor; 
varying vec4 outFragColor; 
attribute vec4 inVertex; 
attribute vec4 inNormal; 
void main(void) { 
    vec3 newNorm = vec3(inNormal); 
    mat3 mNormalMatrix; 
    mNormalMatrix[0] = mvMatrix[0].xyz; 
    mNormalMatrix[1] = mvMatrix[1].xyz; 
    mNormalMatrix[2] = mvMatrix[2].xyz; 
    vec3 vNorm = normalize(mNormalMatrix * newNorm); 
    vec3 vLightDir = vec3(0.0, 0.0, 1.0); 
    float fDot = max(0.0, dot(vNorm, vLightDir)); 
    outFragColor.rgb = vColor.rgb * fDot; 
    outFragColor.a = vColor.a; 
    mat4 mvpMatrix; 
    mvpMatrix = pMatrix * mvMatrix; 
    gl_Position = mvpMatrix * inVertex; 
} 

마지막 회전에 대한 매트릭스 수학 코드로 여기 코드 행렬 계산하며 전달하기 셰이더이 렌더링 될 때마다 인 다음과 같습니다 :

public Matrix4 rotate(Vector4 a, float radians){ 
    Matrix4 temp = new Matrix4().setToRotate(a, radians); 
    this.multiply(temp); 
    return this; 
} 

public Matrix4 setToRotate(Vector4 a, float radians){ 
    a = new Vector4(a).normalise(); 
    float c = GameMath.cos(radians); 
    float s = GameMath.sin(radians); 
    float t = 1-c; 
    float x = a.x; 
    float y = a.y; 
    float z = a.z; 
    float x2 = a.x*a.x; 
    float y2 = a.y*a.y; 
    float z2 = a.z*a.z; 
    this.setIdentity(); 
    this.matrix[0] = c + t*x2; 
    this.matrix[1] = t*x*y + s*z; 
    this.matrix[2] = t*x*z - s*y; 
    this.matrix[4] = t*x*y - s*z; 
    this.matrix[5] = c + t*y2; 
    this.matrix[6] = t*y*z + s*x; 
    this.matrix[8] = t*x*z + s*y; 
    this.matrix[9] = t*y*z + s*x; 
    this.matrix[10] = c + t*z2; 
    return this; 
} 

매트릭스는 주요 열에 저장됩니다.

+1

투영 매트릭스의 매개 변수는 무엇입니까? – Tim

+0

비행기 근처 : 1, 원거리 비행기 : 100, 시야 : 45, 화면 비율 : 640/480 – dagronlund

+1

화면의 정수가 아닌지 확인 했습니까? 그것은 흔한 실수입니다. – Tim

답변

0

문제점이 무엇인지 알아 냈습니다. 분명히 setToRotate()의 연산 중 하나가 더하기에서 뺄셈으로 변경되어야합니다. 그것은 예상대로 작동합니다.