LIBGDX版NEHE OPENGL- 7. Texture Filters, Lighting & Keyboard Control
2013-04-22 18:30
429 查看
Libgdx的TextureFilter:
首先废话说一说“纹理映射的方式”,一个128*128的图片,在渲染的时候,很可能会被放到一个256*256的方形区域显示,也有可能放到64*64的方形区域显示。所以,图片在缩小时,一些相象就丢失了,在放大时,就需要填充一些像素。
GL_TEXTURE_MIN_FILTER 指的是缩小的情况,而GL_TEXTURE_MAG_FILTER 指的是放大的情况。那OpenGL在这种情况下怎么处理呢?我们称之为纹理过滤方式:
最近点采样 GL_NEAREST-效果最差,速度快
线性纹理过滤(双线性过滤)GL_LINEAR-效果较好,计算量较大
mipmap纹理过滤(三线性过滤) GL_LINEAR_MIPMAP_LINEAR-效果最好,计算量最大
各向异性过滤
更多关于这三种渲染方式的讲解看这里吧,http://blog.csdn.net/kkk328/article/details/7055934,我这只管怎么用就好了,要说一下,Libgdx所实现的OpenGL ES里,只支持前面三种。可以看一下Libgdx中关于TextureFilter的定义:
所以,三种类型的Texture就很好建立了:
通过TextureFilter的定义可以看到,Libgdx可支持最多四种方式的MipMap, 高数好的可能会鄙视我了,Linear&Nearest最多就四种嘛。
MipMap(GL10.GL_LINEAR_MIPMAP_LINEAR), // 此种为默认的MipMap方式。等同于MinMapLinearLinear;
MipMapNearestNearest(GL10.GL_NEAREST_MIPMAP_NEAREST),
MipMapLinearNearest(GL10.GL_LINEAR_MIPMAP_NEAREST),
MipMapNearestLinear(GL10.GL_NEAREST_MIPMAP_LINEAR),
MipMapLinearLinear(GL10.GL_LINEAR_MIPMAP_LINEAR);
我在学习TextureFilter的时候,Google到了一个好网站,名字为
Open GL Super Bible. 大家可以点去看看。当然,全英文。
Libgdx的Lighting:
在OpenGL中,最多支持8个光源。所以,Libgdx的GL10中,只能找到GL_LIGHT0 ~ GL_LIGHT7.
不好意思,我又要转帖了,这篇文章来自大龙的博客,对OpenGL ES的灯光做了不错的解释。
看完了大龙对灯光的介绍,再回来定义我们Libgdx里的光源:
光的问题先略过,等不及加上键盘处理了,这样就可以与画面有一些交互。
使用“L”键来开关灯,使用"F"键来切换filter类型,使用"鼠标滚轮"来放大缩小。
上面代码,下面效果图:
缩小:
放大
放大到箱子里面:
使用mipmap的显示效果。(有点模糊)
首先废话说一说“纹理映射的方式”,一个128*128的图片,在渲染的时候,很可能会被放到一个256*256的方形区域显示,也有可能放到64*64的方形区域显示。所以,图片在缩小时,一些相象就丢失了,在放大时,就需要填充一些像素。
GL_TEXTURE_MIN_FILTER 指的是缩小的情况,而GL_TEXTURE_MAG_FILTER 指的是放大的情况。那OpenGL在这种情况下怎么处理呢?我们称之为纹理过滤方式:
最近点采样 GL_NEAREST-效果最差,速度快
线性纹理过滤(双线性过滤)GL_LINEAR-效果较好,计算量较大
mipmap纹理过滤(三线性过滤) GL_LINEAR_MIPMAP_LINEAR-效果最好,计算量最大
各向异性过滤
更多关于这三种渲染方式的讲解看这里吧,http://blog.csdn.net/kkk328/article/details/7055934,我这只管怎么用就好了,要说一下,Libgdx所实现的OpenGL ES里,只支持前面三种。可以看一下Libgdx中关于TextureFilter的定义:
public enum TextureFilter { Nearest(GL10.GL_NEAREST), Linear(GL10.GL_LINEAR), MipMap(GL10.GL_LINEAR_MIPMAP_LINEAR), MipMapNearestNearest( GL10.GL_NEAREST_MIPMAP_NEAREST), MipMapLinearNearest(GL10.GL_LINEAR_MIPMAP_NEAREST), MipMapNearestLinear( GL10.GL_NEAREST_MIPMAP_LINEAR), MipMapLinearLinear(GL10.GL_LINEAR_MIPMAP_LINEAR); final int glEnum; TextureFilter (int glEnum) { this.glEnum = glEnum; } public boolean isMipMap () { return glEnum != GL10.GL_NEAREST && glEnum != GL10.GL_LINEAR; } public int getGLEnum () { return glEnum; } }
所以,三种类型的Texture就很好建立了:
Texture[] textureArray = new Texture[3]; textureArray[0] = new Texture(imageFileHandle); textureArray[0].setFilter(TextureFilter.Nearest, TextureFilter.Nearest); textureArray[1] = new Texture(imageFileHandle); textureArray[1].setFilter(TextureFilter.Linear, TextureFilter.Linear); textureArray[2] = new Texture(imageFileHandle, true); // true 指明这里要使用mipmap textureArray[2].setFilter(TextureFilter.MipMapLinearNearest, TextureFilter.Linear);
通过TextureFilter的定义可以看到,Libgdx可支持最多四种方式的MipMap, 高数好的可能会鄙视我了,Linear&Nearest最多就四种嘛。
MipMap(GL10.GL_LINEAR_MIPMAP_LINEAR), // 此种为默认的MipMap方式。等同于MinMapLinearLinear;
MipMapNearestNearest(GL10.GL_NEAREST_MIPMAP_NEAREST),
MipMapLinearNearest(GL10.GL_LINEAR_MIPMAP_NEAREST),
MipMapNearestLinear(GL10.GL_NEAREST_MIPMAP_LINEAR),
MipMapLinearLinear(GL10.GL_LINEAR_MIPMAP_LINEAR);
我在学习TextureFilter的时候,Google到了一个好网站,名字为
Open GL Super Bible. 大家可以点去看看。当然,全英文。
Libgdx的Lighting:
在OpenGL中,最多支持8个光源。所以,Libgdx的GL10中,只能找到GL_LIGHT0 ~ GL_LIGHT7.
不好意思,我又要转帖了,这篇文章来自大龙的博客,对OpenGL ES的灯光做了不错的解释。
看完了大龙对灯光的介绍,再回来定义我们Libgdx里的光源:
// Ambient Light 环境光 float[] ambientLight = {0.5f, 0.5f, 0.5f, 1.0f}; // Diffuse Light 漫射光 float[] diffuseLight = {1.0f, 1.0f, 1.0f, 1.0f};
光的问题先略过,等不及加上键盘处理了,这样就可以与画面有一些交互。
使用“L”键来开关灯,使用"F"键来切换filter类型,使用"鼠标滚轮"来放大缩小。
package com.kyugao.screen; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; import com.badlogic.gdx.InputProcessor; import com.badlogic.gdx.Screen; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.GL10; import com.badlogic.gdx.graphics.Mesh; import com.badlogic.gdx.graphics.PerspectiveCamera; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.Texture.TextureFilter; import com.badlogic.gdx.graphics.VertexAttribute; import com.badlogic.gdx.graphics.VertexAttributes.Usage; public class FilterLightingKeyboard implements Screen, InputProcessor { private Mesh squareMesh; private PerspectiveCamera camera; private Texture[] textureArray; private int filter = 0; private float xrot = 0, yrot = 0; private float xspeed = 20, yspeed = 20; // indicator for controlling the light private boolean light; private boolean lp, fp; private float z = -5.0f; // Ambient Light float[] ambientLight = { 0.5f, 0.5f, 0.5f, 1.0f }; // Diffuse Light float[] diffuseLight = { 1.0f, 1.0f, 1.0f, 1.0f }; // Light Position float[] position = { 0.0f, 0.0f, 2.0f, 1.0f }; @Override public void render(float delta) { camera.update(); camera.apply(Gdx.graphics.getGL10()); Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); Gdx.gl.glEnable(GL10.GL_DEPTH_TEST); Gdx.gl.glEnable(GL10.GL_TEXTURE_2D); drawGLScene(); xrot += xspeed * delta; // 每秒钟转20度,计算在每一次render的时间差里,要转的角度。比如0.5秒,那就应该转10度。 xrot %= 360; yrot += yspeed * delta; yrot %= 360; } private boolean drawGLScene() { Gdx.gl10.glPushMatrix(); Gdx.gl10.glLoadIdentity(); Gdx.gl10.glTranslatef(0.0f, 0.0f, z); Gdx.gl10.glRotatef(xrot, 1.0f, 0.0f, 0.0f); Gdx.gl10.glRotatef(yrot, 0.0f, 1.0f, 0.0f); textureArray[filter].bind(); for (int i = 0; i < squareMesh.getMaxVertices() / 4; i++) { squareMesh.render(GL10.GL_TRIANGLE_FAN, i * 4, 4); // 正方形的6个面分别画出. } Gdx.gl10.glPopMatrix(); return true; } @Override public void show() { // init mesh squareMesh = new Mesh(true, 24, 24, new VertexAttribute(Usage.Position, 3, "b_position"), new VertexAttribute(Usage.TextureCoordinates, 2, "b_texture")); squareMesh.setVertices(new float[] { // Front face: -1f, 1.0f, 1.0f, 0f, 0f, // TL -1f, -1.0f, 1.0f, 0f, 1f, // BL 1f, -1.0f, 1.0f, 1f, 1f, // BR 1f, 1.0f, 1.0f, 1f, 0f, // TR // Top face: -1f, 1.0f, -1.0f, 0f, 0f, // LR -1f, 1.0f, 1.0f, 0f, 1f, // LN 1f, 1.0f, 1.0f, 1f, 1f, // RN 1f, 1.0f, -1.0f, 1f, 0f, // RR // Rear face 1f, 1.0f, -1f, 0f, 0f, // TR 1f, -1.0f, -1f, 0f, 1f, // BR -1f, -1.0f, -1f, 1f, 1f, // BL -1f, 1.0f, -1f, 1f, 0f, // TL // Bottom face -1f, -1.0f, 1f, 0f, 0f, // LN 1f, -1.0f, 1f, 0f, 1f,// RN 1f, -1.0f, -1f, 1f, 1f, // RR -1f, -1.0f, -1f, 1f, 0f, // LR // Left face -1f, 1.0f, -1f, 0f, 0f, // TR -1f, 1.0f, 1f, 0f, 1f, // TN -1f, -1.0f, 1f, 1f, 1f, // BN -1f, -1.0f, -1f, 1f, 0f, // BR // Right face 1f, 1.0f, 1f, 0f, 0f, // TN 1f, 1.0f, -1f, 1f, 0f, // TR 1f, -1.0f, -1f, 1f, 1f, // BR 1f, -1.0f, 1f, 0f, 1f // BN }); squareMesh.setIndices(new short[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }); // init texture FileHandle imageFileHandle = Gdx.files.internal("data/Crate.bmp"); textureArray = new Texture[3]; textureArray[0] = new Texture(imageFileHandle); textureArray[0].setFilter(TextureFilter.Nearest, TextureFilter.Nearest); textureArray[1] = new Texture(imageFileHandle); textureArray[1].setFilter(TextureFilter.Linear, TextureFilter.Linear); textureArray[2] = new Texture(imageFileHandle, true); textureArray[2].setFilter(TextureFilter.MipMap, TextureFilter.Linear); // init light Gdx.gl.glEnable(GL10.GL_LIGHT1); Gdx.gl10.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, ambientLight, 0); Gdx.gl10.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, diffuseLight, 0); Gdx.gl10.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, position, 0); // Set input processor Gdx.input.setInputProcessor(this); } @Override public void hide() { } @Override public void pause() { } @Override public void resume() { } @Override public void dispose() { } @Override public void resize(int width, int height) { float aspectRatio = (float) width / (float) height; camera = new PerspectiveCamera(45, 2f * aspectRatio, 2f); } @Override public boolean keyDown(int keycode) { if (keycode == Input.Keys.L && !lp) { lp = true; light = !light; if (light) { Gdx.gl.glEnable(GL10.GL_LIGHTING); } else { Gdx.gl.glDisable(GL10.GL_LIGHTING); } } else if (keycode == Input.Keys.F && !fp) { fp = true; filter = (filter + 1) % 3; } return false; } @Override public boolean keyUp(int keycode) { if (keycode == Input.Keys.L && lp) { lp = false; } else if (keycode == Input.Keys.F && fp) { fp = false; } return false; } @Override public boolean keyTyped(char character) { return false; } @Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { return false; } @Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { return false; } @Override public boolean touchDragged(int screenX, int screenY, int pointer) { return false; } @Override public boolean mouseMoved(int screenX, int screenY) { return false; } @Override public boolean scrolled(int amount) { z += amount; return false; } }
上面代码,下面效果图:
缩小:
放大
放大到箱子里面:
使用mipmap的显示效果。(有点模糊)
相关文章推荐
- LIBGDX版NEHE OPENGL- 7. Texture Filters, Lighting & Keyboard Control
- LIBGDX版NEHE OPENGL- 8. Blend & 加载模型和帖图
- LIBGDX版NEHE OPENGL- 2. Your First Polygon
- LIBGDX版NEHE OPENGL- 5. 3D Shapes
- OpenGL Lighting & Color feature
- LIBGDX版NEHE OPENGL- 5. 3D Shapes
- LIBGDX版NEHE OPENGL- 4. Rotation
- NEHE的OpenGL-Lesson 07 Texture Filters, Lightning & Keyboard Control
- LIBGDX版NEHE OPENGL- 4. Rotation
- NeHe OpenGL Lesson07 - Texture filtering, lighting & keyboard control
- MANAGED & UNMANAGED (DYNAMIC )TEXTURES IN LIBGDX (OPENGL CONTEXT LOSS)
- “NeHe's OpenGL 程序框架”编译成功
- NeHe OpenGL Lesson26 – Clipping & Reflections Using The Stencil Buffer
- LIBGDX版NEHE OPENGL- 2. Your First Polygon
- NeHe OpenGL Lesson25 – Morphing & Loading Objects From A File
- NeHe OpenGL教程 第六课:纹理映射
- NeHe OpenGL教程 第十六课:雾
- NeHe OpenGL教程 第四十八课:轨迹球
- Android OpenGL 坐标系 <2>
- OpenGL 练习11.2 Lighting