Vuforia 6.0.117 渲染纹理时出现 0x501 错误

Vuforia 6.0.117 0x501 error when rendering texture

我正在尝试让 Vuforia 6.0.117 在我的 Android 应用程序中运行。我正在使用这个特定版本,因为它是支持 FrameMarkers 的最后一个版本。 FrameMarkers 的检测工作正常,但是当我尝试在 phone 上的 FrameMarker 上渲染纹理时,我收到一条错误消息:

运行 FrameMarkers 渲染帧后出现 glError 0x501

我的 renderFrame 方法:

// Clear color and depth buffer
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

    // Get the state from Vuforia and mark the beginning of a rendering
    // section
    State state = Renderer.getInstance().begin();

    // Explicitly render the Video Background
    Renderer.getInstance().drawVideoBackground();

    GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    GLES20.glEnable(GLES20.GL_BLEND);
    GLES20.glBlendEquation(GLES20.GL_FUNC_ADD);

// GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);

    // We must detect if background reflection is active and adjust the
    // culling direction.
    // If the reflection is active, this means the post matrix has been
    // reflected as well,
    // therefore standard counter clockwise face culling will result in
    // "inside out" models.
    GLES20.glEnable(GLES20.GL_CULL_FACE);
    GLES20.glCullFace(GLES20.GL_BACK);
    if (Renderer.getInstance().getVideoBackgroundConfig().getReflection() == VIDEO_BACKGROUND_REFLECTION.VIDEO_BACKGROUND_REFLECTION_ON) {
        GLES20.glFrontFace(GLES20.GL_CW);  // Front camera
    } else {
        GLES20.glFrontFace(GLES20.GL_CCW);   // Back camera
    }

    // Did we find any trackables this frame?
    if (mActivity.isHelpVisible() || state.getNumTrackableResults() == 0) {
        // no marker scanned
        mActivity.hideInfoButton();
    } else {
        // Get the trackable:
        TrackableResult trackableResult = state.getTrackableResult(0);
        float[] modelViewMatrix = Tool.convertPose2GLMatrix(trackableResult.getPose()).getData();

        // Check the type of the trackable:
        MarkerResult markerResult = (MarkerResult) trackableResult;
        Marker marker = (Marker) markerResult.getTrackable();

        if (markerId != marker.getMarkerId()) {
            markerId = marker.getMarkerId();
            tag = DataManager.getInstance().getTagByMarkerId(markerId);
            if (tag != null) {
                texture = Texture.loadTexture(tag.getTexture());
                setupTexture(texture);
                tag.addToDB();
            }
        }

        if (tag != null) {
            String poiReference = tag.getPoiReference();
            if (!poiReference.isEmpty()) {
                mActivity.showInfoButton(poiReference);
            }

            // Select which model to draw:
            Buffer vertices = planeObject.getVertices();
            Buffer normals = planeObject.getNormals();
            Buffer indices = planeObject.getIndices();
            Buffer texCoords = planeObject.getTexCoords();
            int numIndices = planeObject.getNumObjectIndex();

            float[] modelViewProjection = new float[16];

            float scale = (float) tag.getScale();
            Matrix.scaleM(modelViewMatrix, 0, scale, scale, scale);

            Matrix.multiplyMM(modelViewProjection, 0, vuforiaAppSession.getProjectionMatrix().getData(), 0, modelViewMatrix, 0);

            GLES20.glUseProgram(shaderProgramID);

            GLES20.glVertexAttribPointer(vertexHandle, 3, GLES20.GL_FLOAT, false, 0, vertices);
            GLES20.glVertexAttribPointer(normalHandle, 3, GLES20.GL_FLOAT, false, 0, normals);
            GLES20.glVertexAttribPointer(textureCoordHandle, 2, GLES20.GL_FLOAT, false, 0, texCoords);

            GLES20.glEnableVertexAttribArray(vertexHandle);
            GLES20.glEnableVertexAttribArray(normalHandle);
            GLES20.glEnableVertexAttribArray(textureCoordHandle);

            GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture.mTextureID[0]);
            GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, modelViewProjection, 0);
            GLES20.glUniform1i(texSampler2DHandle, 0);
            GLES20.glDrawElements(GLES20.GL_TRIANGLES, numIndices, GLES20.GL_UNSIGNED_SHORT, indices);

            GLES20.glDisableVertexAttribArray(vertexHandle);
            GLES20.glDisableVertexAttribArray(normalHandle);
            GLES20.glDisableVertexAttribArray(textureCoordHandle);

            SampleUtils.checkGLError("FrameMarkers render frame");
        }
    }

    GLES20.glDisable(GLES20.GL_DEPTH_TEST);

    Renderer.getInstance().end();

}

我正在加载大小为 640x482 的纹理,加载方式如下:

public class Texture {

public int mWidth;          // The width of the texture.
public int mHeight;         // The height of the texture.
public int mChannels;       // The number of channels.
public ByteBuffer mData;    // The pixel data.
public int[] mTextureID = new int[1];
public boolean mSuccess = false;

public static Texture loadTexture(String fileName) {

    try {
        InputStream inputStream = new FileInputStream(fileName);
        BufferedInputStream bufferedStream = new BufferedInputStream(inputStream);

        Bitmap bitMap = BitmapFactory.decodeStream(bufferedStream);

        bufferedStream.close();
        inputStream.close();

        int[] data = new int[bitMap.getWidth() * bitMap.getHeight()];
        bitMap.getPixels(data, 0, bitMap.getWidth(), 0, 0, bitMap.getWidth(), bitMap.getHeight());

        return loadTextureFromIntBuffer(data, bitMap.getWidth(), bitMap.getHeight());
    } catch (IOException e) {
        Log.e(Constants.DEBUG, "Failed to load texture '" + fileName + "' from APK");
        Log.i(Constants.DEBUG, e.getMessage());
        return null;
    }
}

public static Texture loadTextureFromIntBuffer(int[] data, int width, int height) {
    // Convert:
    int numPixels = width * height;
    byte[] dataBytes = new byte[numPixels * 4];

    for (int p = 0; p < numPixels; ++p) {
        int colour = data[p];
        dataBytes[p * 4] = (byte) (colour >>> 16); // R
        dataBytes[p * 4 + 1] = (byte) (colour >>> 8); // G
        dataBytes[p * 4 + 2] = (byte) colour; // B
        dataBytes[p * 4 + 3] = (byte) (colour >>> 24); // A
    }

    Texture texture = new Texture();
    texture.mWidth = width;
    texture.mHeight = height;
    texture.mChannels = 4;

    texture.mData = ByteBuffer.allocateDirect(dataBytes.length).order(ByteOrder.nativeOrder());
    int rowSize = texture.mWidth * texture.mChannels;
    for (int r = 0; r < texture.mHeight; r++) {
        texture.mData.put(dataBytes, rowSize * (texture.mHeight - 1 - r), rowSize);
    }

    texture.mData.rewind();

    texture.mSuccess = true;

    return texture;
}

}

有人知道为什么我会收到此错误以及如何修复它吗?

我现在无法检查您的全部代码,即使可以,我也不确定它是否有帮助。你首先需要缩小问题范围,所以我先给你方法,希望在其他情况下对你也有帮助。

您设法发现存在错误 - 但您只是在渲染函数结束时才检查它。您需要做的是将 checkGLError 调用放置在呈现代码中的多个位置(打印不同的文本消息),直到您可以精确定位首次出现错误的确切行。然后,如果您无法理解问题,请在此处评论有问题的行,我会尽力提供帮助。

更新:

查看着色器代码后,根据您报告 normalHandle 为 -1,我得出以下结论:

错误表明在着色器中找不到变量 vertexNormal,可能是因为这个变量可能在着色器编译期间被优化掉了,因为它并不是真正需要的。

说明:在顶点着色器(CUBE_MESH_VERTEX_SHADER)中,vertexNormal 被分配给一个名为 normal 的变量(传递给片段着色器的变量)。在片段着色器中,这个 varying 被声明但没有被使用。 因此,您实际上可以从着色器中删除变量 vertexNormal 和 normal,并且可以删除代码中所有 'normalHandle' 的用法。

这应该可以消除错误。