我一直在努力想办法解决这个问题,并且在淘汰Stack Overflow和Web之后,我一直在抨击我的头,我没有找到任何示例已经为我工作。我终于看到了很接近的代码,所以也许你们(和加尔斯?)可以帮我弄清楚这一点。绘制在OpenGL ES 2D Orthographic(Ortho)模式中的问题
我的第一个问题是,我试图通过将屏幕抓取作为纹理来实现运动模糊,然后使用透明度在下一帧中绘制纹理 - 或者使用更多的帧以获得更多模糊。 (如果任何人有兴趣,这是我遵循的指南:http://www.codeproject.com/KB/openGL/MotionBlur.aspx)
我已经将屏幕保存为纹理工作正常。我遇到的问题是在屏幕顶部的Ortho模式下绘制。经过很多次敲打之后,我终于得到了一张基本的方形图,但是我对OpenGL ES理解的缺乏和一个容易遵循的例子现在让我难以忍受。我需要采取我保存的纹理,并将其绘制到我绘制的方格中。我一直没有做的事情似乎有效。
另外,我的第二个问题是,将更复杂的3D模型绘制成Ortho模式。我似乎无法得到任何模型绘制。我正在使用(稍微定制的)min3d框架(http://code.google.com/p/min3d/),并且我试图在Ortho模式下绘制Object3d,就像我在透视模式下绘制它们一样。据我了解,他们应该画相同的,他们应该没有深度。但我似乎根本看不到他们。
这是我正在使用的代码。我尝试了很多不同的东西,这是我得到的最接近的东西(实际上是在屏幕上绘制可以看到的东西)。我仍然不知道如何在正视图中获得正确的3D模型图。我确信我正在做一些可怕的错误,可能完全误解了OpenGL绘图的一些基本方面。让我知道是否有任何其他代码需要发布。
// Gets called once, before all drawing occurs
//
private void reset()
{
// Reset TextureManager
Shared.textureManager().reset();
// Do OpenGL settings which we are using as defaults, or which we will not be changing on-draw
// Explicit depth settings
_gl.glEnable(GL10.GL_DEPTH_TEST);
_gl.glClearDepthf(1.0f);
_gl.glDepthFunc(GL10.GL_LESS);
_gl.glDepthRangef(0,1f);
_gl.glDepthMask(true);
// Alpha enabled
_gl.glEnable(GL10.GL_BLEND);
_gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
// "Transparency is best implemented using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
// with primitives sorted from farthest to nearest."
// Texture
_gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); // (OpenGL default is GL_NEAREST_MIPMAP)
_gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); // (is OpenGL default)
// CCW frontfaces only, by default
_gl.glFrontFace(GL10.GL_CCW);
_gl.glCullFace(GL10.GL_BACK);
_gl.glEnable(GL10.GL_CULL_FACE);
// Disable lights by default
for (int i = GL10.GL_LIGHT0; i < GL10.GL_LIGHT0 + NUM_GLLIGHTS; i++) {
_gl.glDisable(i);
}
//
// Scene object init only happens here, when we get GL for the first time
//
}
// Called every frame
//
protected void drawScene()
{
if(_scene.fogEnabled() == true) {
_gl.glFogf(GL10.GL_FOG_MODE, _scene.fogType().glValue());
_gl.glFogf(GL10.GL_FOG_START, _scene.fogNear());
_gl.glFogf(GL10.GL_FOG_END, _scene.fogFar());
_gl.glFogfv(GL10.GL_FOG_COLOR, _scene.fogColor().toFloatBuffer());
_gl.glEnable(GL10.GL_FOG);
} else {
_gl.glDisable(GL10.GL_FOG);
}
// Sync all of the object drawing so that updates in the mover
// thread can be synced if necessary
synchronized(Renderer.SYNC)
{
for (int i = 0; i < _scene.children().size(); i++)
{
Object3d o = _scene.children().get(i);
if(o.animationEnabled())
{
((AnimationObject3d)o).update();
}
drawObject(o);
}
}
//
//
//
// Draw the blur
// Set Up An Ortho View
_switchToOrtho();
_drawMotionBlur();
// Switch back to the previous view
_switchToPerspective();
_saveScreenToTexture("blur", 512);
}
private void _switchToOrtho()
{
// Set Up An Ortho View
_gl.glDisable(GL10.GL_DEPTH_TEST);
_gl.glMatrixMode(GL10.GL_PROJECTION); // Select Projection
_gl.glPushMatrix(); // Push The Matrix
_gl.glLoadIdentity(); // Reset The Matrix
_gl.glOrthof(0f, 480f, 0f, 800f, -1f, 1f);
//_gl.glOrthof(0f, 480f, 0f, 800f, -100f, 100f);
_gl.glMatrixMode(GL10.GL_MODELVIEW); // Select Modelview Matrix
_gl.glPushMatrix(); // Push The Matrix
_gl.glLoadIdentity(); // Reset The Matrix
}
private void _switchToPerspective()
{
// Switch back to the previous view
_gl.glEnable(GL10.GL_DEPTH_TEST);
_gl.glMatrixMode(GL10.GL_PROJECTION);
_gl.glPopMatrix();
_gl.glMatrixMode(GL10.GL_MODELVIEW);
_gl.glPopMatrix(); // Pop The Matrix
}
private void _saveScreenToTexture(String $textureId, int $size)
{
// Save the screen as a texture
_gl.glViewport(0, 0, $size, $size);
_gl.glBindTexture(GL10.GL_TEXTURE_2D, _textureManager.getGlTextureId($textureId));
_gl.glCopyTexImage2D(GL10.GL_TEXTURE_2D,0,GL10.GL_RGB,0,0,512,512,0);
_gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
_gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
_gl.glViewport(0, 0, 480, 800);
}
private void _drawMotionBlur()
{
// Vertices
float squareVertices[] = {
-3f, 0f, // Bottom Left
475f, 0f, // Bottom Right
475f, 800f, // Top Right
-3f, 800f // Top Left
};
ByteBuffer vbb = ByteBuffer.allocateDirect(squareVertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
FloatBuffer vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(squareVertices);
vertexBuffer.position(0);
//
//
// Textures
FloatBuffer textureBuffer; // buffer holding the texture coordinates
float texture[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(squareVertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
//
//
//
_gl.glLineWidth(3.0f);
_gl.glTranslatef(5.0f, 0.0f, 0.0f);
_gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
_gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
_gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);
//_gl.glTranslatef(100.0f, 0.0f, 0.0f);
//_gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);
//_gl.glTranslatef(100.0f, 0.0f, 0.0f);
//_gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);
_gl.glEnable(GL10.GL_TEXTURE_2D);
_gl.glEnable(GL10.GL_BLEND);
_gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
_gl.glLoadIdentity();
//
//
//
_gl.glBindTexture(GL10.GL_TEXTURE_2D, _textureManager.getGlTextureId("blur"));
_gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
_gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
//
//
//
_gl.glDisable(GL10.GL_BLEND);
_gl.glDisable(GL10.GL_TEXTURE_2D);
_gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
编辑:这里有一个简单的例子,这一切都在一个功能,不包括任何的屏幕保存到质感的东西。这只是绘制一个3D场景,切换到Ortho,绘制带有纹理的正方形,然后切换回透视。
// Called every frame
//
protected void drawScene()
{
// Draw the 3d models in perspective mode
// This part works (uses min3d) and draws a 3d scene
//
for (int i = 0; i < _scene.children().size(); i++)
{
Object3d o = _scene.children().get(i);
if(o.animationEnabled())
{
((AnimationObject3d)o).update();
}
drawObject(o);
}
// Set Up The Ortho View to draw a square with a texture
// over the 3d scene
//
_gl.glDisable(GL10.GL_DEPTH_TEST);
_gl.glMatrixMode(GL10.GL_PROJECTION); // Select Projection
_gl.glPushMatrix(); // Push The Matrix
_gl.glLoadIdentity(); // Reset The Matrix
_gl.glOrthof(0f, 480f, 0f, 800f, -1f, 1f);
_gl.glMatrixMode(GL10.GL_MODELVIEW); // Select Modelview Matrix
_gl.glPushMatrix(); // Push The Matrix
_gl.glLoadIdentity(); // Reset The Matrix
// Draw A Square With A Texture
// (Assume that the texture "blur" is already created properly --
// it is as I can use it when drawing my 3d scene if I apply it
// to one of the min3d objects)
//
float squareVertices[] = {
-3f, 0f, // Bottom Left
475f, 0f, // Bottom Right
475f, 800f, // Top Right
-3f, 800f // Top Left
};
ByteBuffer vbb = ByteBuffer.allocateDirect(squareVertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
FloatBuffer vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(squareVertices);
vertexBuffer.position(0);
FloatBuffer textureBuffer; // buffer holding the texture coordinates
float texture[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(squareVertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
_gl.glLineWidth(3.0f);
_gl.glTranslatef(5.0f, 0.0f, 0.0f);
_gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer);
_gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
_gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);
_gl.glEnable(GL10.GL_TEXTURE_2D);
_gl.glEnable(GL10.GL_BLEND);
_gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
_gl.glLoadIdentity();
_gl.glBindTexture(GL10.GL_TEXTURE_2D, _textureManager.getGlTextureId("blur"));
_gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
_gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
_gl.glDisable(GL10.GL_BLEND);
_gl.glDisable(GL10.GL_TEXTURE_2D);
_gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Switch Back To The Perspective Mode
//
_gl.glEnable(GL10.GL_DEPTH_TEST);
_gl.glMatrixMode(GL10.GL_PROJECTION);
_gl.glPopMatrix();
_gl.glMatrixMode(GL10.GL_MODELVIEW);
_gl.glPopMatrix(); // Pop The Matrix
}
EDIT2:感谢Christian的回答,我删除了第二glVertexPointer
和_gl.glBlendFunc (GL10.GL_ONE, GL10.GL_ONE);
(我删除了他们从上面的示例代码,以及这样就不会混淆的问题)。我现在有一个纹理渲染,但只在组成方形的一个三角形中。所以我在屏幕的左侧看到一个三角形,它应用了纹理。为什么它不适用于广场的两半?我认为这是因为我只有一个这样的电话:gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
,所以我实际上只画一个三角形。
如果您在使用正交投影时遇到问题,您是否更容易阅读代码示例?所有这些运动模糊相关的方法在这里都很混乱。如果您可以提供更多关于正交投影及其用法的更短代码示例,那么尝试帮助会更容易。 – harism 2011-05-08 21:46:30
添加了更简单的代码版本。 – 2011-05-08 22:41:07