在opengl中绕z轴旋转线遇到问题?
我画了一条具有顶点 (0.2f, 0.2f, 0.0f) 和 (0.2f, 0.2f, 0.0f) 的线OpenGL 中的(-0.2f、-0.2f、0.0f)。由于缺少线坐标的 z 分量,这意味着该线位于 XY 平面中。现在我尝试使用 glRotatef 函数绕 z 轴旋转线。理想情况下,线旋转应该采用圆形路径(至少当旋转 1 到 360 时,它应该看起来像一个圆),但不知何故,它看起来更像一个椭圆,更多地向 y 轴拉伸(我的猜测是,可能是因为深度效应)。但由于我的线完全在 XY 平面上(由于线坐标中缺少 Z 分量),为什么我会得到这样的深度效果?我已在此问题中发布了我的代码。请指出正确的方向?
GLSurfaceViewActivity 代码文件:
package com.mobi.trials.gldemo;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class GLSurfaceViewActivity extends Activity {
SimpleGLSurfaceView glView = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("GLDemo", "In the activity");
glView = new SimpleGLSurfaceView(this);
setContentView(glView);
}
@Override
protected void onPause() {
super.onPause();
glView.onPause();
}
@Override
protected void onResume() {
super.onResume();
glView.onResume();
}
}
SimpleGLSurfaceView 代码文件:
package com.mobi.trials.gldemo;
import android.content.Context;
import android.opengl.GLSurfaceView;
public class SimpleGLSurfaceView extends GLSurfaceView {
public SimpleGLSurfaceView(Context context) {
super(context);
final DrawGLSurfaceCanvasView renderer = new DrawGLSurfaceCanvasView(this);
setFocusable(true);
setFocusableInTouchMode(true);
setRenderer(renderer);
}
}
DrawGLSurfaceCanvasView 代码文件:
package com.mobi.trials.gldemo;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView;
public class DrawGLSurfaceCanvasView implements GLSurfaceView.Renderer {
SimpleLine line;
private float rotationAngle = 0.0f;
float lineVertices[] = { 0.2f, 0.2f, 0f,
-0.2f, -0.2f, 0f };
public DrawGLSurfaceCanvasView(GLSurfaceView view) {
}
@Override
public void onDrawFrame(GL10 gl) {
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
gl.glRotatef(rotationAngle, 0.0f, 0.0f, 1.0f);
if(rotationAngle <= -360.0f)
{
rotationAngle = 0.0f;
}
rotationAngle -= 1f;
line.draw(gl);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
line = new SimpleLine(lineVertices);
}
}
SimpleLine 代码文件:
package com.mobi.trials.gldemo;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
public class SimpleLine {
float vertices[];
private FloatBuffer vertexBuffer;
public SimpleLine(float[] vertices) {
super();
this.vertices = vertices;
}
public void draw(GL10 gl)
{
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
// Update : Added orthographic projection matrix.
// Update II : Corrected the values of orthgraphic projection matrix.
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glDrawArrays(GL10.GL_LINES, 0, 2);
}
}
I have drawn one line having vertices (0.2f, 0.2f, 0.0f) & (-0.2f, -0.2f, 0.0f) in OpenGL. As z component of line co-ordinates is missing it implies that line is in XY plane. Now i am trying to rotate the line around the z axis using glRotatef function. Ideally line rotation should have taken a circular path(at least it should have looked like a circle when rotated it by 1 to 360) but somehow it is looking more like a ellipse, more stretched towards y-axis (my guess is that, may be because of depth effect). but as my line is completely in XY plane(As Z component is missing in line co-ordinates) why am i getting such depth effect? I have posted my code herewith this question. Please point me to the right direction?
GLSurfaceViewActivity code file:
package com.mobi.trials.gldemo;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
public class GLSurfaceViewActivity extends Activity {
SimpleGLSurfaceView glView = null;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("GLDemo", "In the activity");
glView = new SimpleGLSurfaceView(this);
setContentView(glView);
}
@Override
protected void onPause() {
super.onPause();
glView.onPause();
}
@Override
protected void onResume() {
super.onResume();
glView.onResume();
}
}
SimpleGLSurfaceView code file:
package com.mobi.trials.gldemo;
import android.content.Context;
import android.opengl.GLSurfaceView;
public class SimpleGLSurfaceView extends GLSurfaceView {
public SimpleGLSurfaceView(Context context) {
super(context);
final DrawGLSurfaceCanvasView renderer = new DrawGLSurfaceCanvasView(this);
setFocusable(true);
setFocusableInTouchMode(true);
setRenderer(renderer);
}
}
DrawGLSurfaceCanvasView code file:
package com.mobi.trials.gldemo;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView;
public class DrawGLSurfaceCanvasView implements GLSurfaceView.Renderer {
SimpleLine line;
private float rotationAngle = 0.0f;
float lineVertices[] = { 0.2f, 0.2f, 0f,
-0.2f, -0.2f, 0f };
public DrawGLSurfaceCanvasView(GLSurfaceView view) {
}
@Override
public void onDrawFrame(GL10 gl) {
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
gl.glRotatef(rotationAngle, 0.0f, 0.0f, 1.0f);
if(rotationAngle <= -360.0f)
{
rotationAngle = 0.0f;
}
rotationAngle -= 1f;
line.draw(gl);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
line = new SimpleLine(lineVertices);
}
}
SimpleLine code file :
package com.mobi.trials.gldemo;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
public class SimpleLine {
float vertices[];
private FloatBuffer vertexBuffer;
public SimpleLine(float[] vertices) {
super();
this.vertices = vertices;
}
public void draw(GL10 gl)
{
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
// Update : Added orthographic projection matrix.
// Update II : Corrected the values of orthgraphic projection matrix.
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glDrawArrays(GL10.GL_LINES, 0, 2);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不认为你观察到的是深度效应。只是您没有设置任何投影矩阵(导致选择默认值:身份)。因此,将模型视图矩阵设置为恒等式后,最终会得到代表窗口范围的 [-1:1]。
[-.2,.2] 最终代表窗口的 20%。我假设你的窗口不是方形的,所以你最终会画一个具有偏心率的长宽比的椭圆。
您需要查看解释投影矩阵通常如何设置的教程(它通常涉及窗口的大小和/或它的纵横比)。
I don't think what you're observing is a depth effect. It's just that you did not set any projection matrix (resulting in picking up the default: the identity). So with a modelview matrix set as identity, you end up with [-1:1] representing the extents of your window.
[-.2,.2] ends up representing 20% of your window. I assume your window is not square, so you end up drawing an ellipse with an eccentricity of your aspect ratio.
You need to look at tutorials that explain how the projection matrix is typically set (it typically involves the size of your window and or its aspect ratio).