Bootstrap

OpenGL ES查询是否支持float浮点数据类型纹理格式

一、前言

项目开发中发现之前可用的代码换了一台设备后结果一直错误,后来发现是因为使用了 float 浮点数据类型创建的纹理导致的,查阅得知 OpenGL ES 中硬件可能不支持特定的纹理格式和数据类型。

通常情况下,OpenGL ES 实现至少应该支持 GL_UNSIGNED_BYTE 类型的纹理,因为它是最基本的纹理数据类型之一,但是对于其他类型(如 GL_FLOAT)的支持可能因硬件而异。如果需要在 OpenGL ES 中使用 GL_FLOAT 类型的纹理,应该提前确保目标平台的硬件和驱动程序支持该功能,如果目标平台不支持 GL_FLOAT 类型的纹理,则需要考虑使用其他方式来处理纹理数据。

二、查询方法

1. 思路

通过 OpenGL 提供的 glGetString(GL_EXTENSIONS) 可以获得其支持的扩展列表,再查询这其中是否包含 GL_EXT_texture_floatGL_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;
}

;