一、前言
项目开发中发现之前可用的代码换了一台设备后结果一直错误,后来发现是因为使用了 float 浮点数据类型创建的纹理导致的,查阅得知 OpenGL ES 中硬件可能不支持特定的纹理格式和数据类型。
通常情况下,OpenGL ES 实现至少应该支持 GL_UNSIGNED_BYTE 类型的纹理,因为它是最基本的纹理数据类型之一,但是对于其他类型(如 GL_FLOAT)的支持可能因硬件而异。如果需要在 OpenGL ES 中使用 GL_FLOAT 类型的纹理,应该提前确保目标平台的硬件和驱动程序支持该功能,如果目标平台不支持 GL_FLOAT 类型的纹理,则需要考虑使用其他方式来处理纹理数据。
二、查询方法
1. 思路
通过 OpenGL 提供的 glGetString(GL_EXTENSIONS)
可以获得其支持的扩展列表,再查询这其中是否包含 GL_EXT_texture_float 或 GL_OES_texture_float 即可,前者是普通的纹理,后者通常是指外部纹理如相机的纹理。
2. Java代码示例
import android.content.Context;
import android.opengl.GLES30;
import android.opengl.GLSurfaceView;
import android.util.AttributeSet;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class MyGLSurfaceView extends GLSurfaceView {
public MyGLSurfaceView(Context context) {
super(context);
init();
}
public MyGLSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setEGLContextClientVersion(3);
setRenderer(new MyRenderer());
}
private static class MyRenderer implements GLSurfaceView.Renderer {
private boolean checkFloatTextureSupport() {
String extensions = GLES30.glGetString(GLES30.GL_EXTENSIONS);
return extensions != null && extensions.contains("GL_EXT_texture_float");
}
private boolean checkOESFloatTextureSupport() {
String extensions = GLES30.glGetString(GLES30.GL_EXTENSIONS);
return extensions != null && (extensions.contains("GL_OES_texture_float"));
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// 检查是否支持 float 类型的纹理
boolean isFloatTextureSupported = checkFloatTextureSupport();
// 输出结果
if (isFloatTextureSupported) {
Log.i(TAG, "Device supports FLOAT textures");
} else {
Log.e(TAG, "Device does not support FLOAT textures");
}
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// 省略
}
@Override
public void onDrawFrame(GL10 gl) {
// 省略
}
}
}
3. C++代码示例
#include <GLES3/gl3.h>
bool isFloatTextureSupported() {
// 获取OpenGL ES的扩展列表
const char* extensions = (const char*) glGetString(GL_EXTENSIONS);
if (extensions != nullptr) {
// 检查是否存在GL_EXT_texture_float扩展
if (strstr(extensions, "GL_EXT_texture_float") != nullptr) {
return true;
}
}
return false;
}
bool isOESFloatTextureSupported() {
// 获取OpenGL ES的扩展列表
const char* extensions = (const char*) glGetString(GL_EXTENSIONS);
if (extensions != nullptr) {
// 检查是否存在GL_OES_texture_float扩展
if (strstr(extensions, "GL_OES_texture_float") != nullptr) {
return true;
}
}
return false;
}