宽度增加后宽度会缩小。高度是OpenGL C ++的2倍

时间:2015-02-04 03:55:00

标签: android c++ opengl-es opengl-es-2.0

我正在通过openGL在GLSurfaceView上呈现视频。 openGL部分是在C ++中以原生部分编写的。这是我的渲染例程:

void VideoRenderOpenGL2::Render(const unsigned char *pData)
{
    ......................
    // GL_OPERATION is a macro, nothing special
    GL_OPERATION(glUseProgram(m_program))

    UpdateTextures(pData); // other routine, I will post the function if needed

    bool bClear = true;
    float vpx = 0.0f;
    float vpy = 0.0f;
    float vpw = 1.0f;
    float vph = 1.0f;
    int nOrientation = 0;

    float uLeft, uRight, vTop, vBottom;
    uLeft = vBottom = 0.0f;
    uRight = m_uvx;
    vTop = m_uvy;

    GLfloat squareUvs[] = {
            uLeft, vTop,
            uRight, vTop,
            uLeft, vBottom,
            uRight, vBottom
    };

    if (bClear) {
        GL_OPERATION(glViewport(0, 0, m_nDisplayWidth, m_nDisplayHeight))
        GL_OPERATION(glClearColor(0, 0, 0, 1))
        GL_OPERATION(glClear(GL_COLOR_BUFFER_BIT))
    }

    GLfloat squareVertices[8];

    // drawing surface dimensions
    int screenW = m_nDisplayWidth;
    int screenH = m_nDisplayHeight;
    if (nOrientation == 90 || nOrientation == 270) {
        screenW = m_nDisplayHeight;
        screenH = m_nDisplayWidth;
    }

    int x,y,w,h;
    // Fill the smallest dimension, then compute the other one using the image ratio
    if (screenW <= screenH) {
        float ratio = m_nTextureHeight / (float)m_nTextureWidth;
        w = screenW * vpw;
        h = w * ratio;
        if (h > screenH) {
            w *= screenH /(float) h;
            h = screenH;
        }
        x = vpx * m_nDisplayWidth;
        y = vpy * m_nDisplayHeight;
    } else {
        float ratio = m_nTextureWidth / (float)m_nTextureHeight;
        h = screenH * vph;
        w = h * ratio;
        if (w > screenW) {
            h *= screenW / (float)w;
            w = screenW;
        }
        x = vpx * screenW;
        y = vpy * screenH;
    }
    // here m_nDisplayWidth = 5536, m_nDisplayHeight = 3114, w = 5536, h = 3114, x = 0, y = 0, screenW = 5536, screenH = 3114, m_nTextureWidth = 1280, m_nTextureHeight = 720
    squareVertices[0] = (x - w * 0.5) / screenW - 0.;
    squareVertices[1] = (y - h * 0.5) / screenH - 0.;
    squareVertices[2] = (x + w * 0.5) / screenW - 0.;
    squareVertices[3] = (y - h * 0.5) / screenH - 0.;
    squareVertices[4] = (x - w * 0.5) / screenW - 0.;
    squareVertices[5] = (y + h * 0.5) / screenH - 0.;
    squareVertices[6] = (x + w * 0.5) / screenW - 0.;
    squareVertices[7] = (y + h * 0.5) / screenH - 0.;

    GL_OPERATION(glViewport(0, 0, m_nDisplayWidth, m_nDisplayHeight))

    GLfloat mat[16];
#define VP_SIZE 1.0f
    float vpDim = VP_SIZE / (2 * m_scaleFactor);

#define ENSURE_RANGE_A_INSIDE_RANGE_B(a, aSize, bMin, bMax) \
        if (2 * aSize >= (bMax - bMin)) \
        a = 0; \
        else if ((a - aSize < bMin) || (a + aSize > bMax)) { \
            float diff; \
            if (a - aSize < bMin) diff = bMin - (a - aSize); \
            else diff = bMax - (a + aSize); \
            a += diff; \
        }

    float zoom_cx = 0.0f;
    float zoom_cy = 0.0f;

    ENSURE_RANGE_A_INSIDE_RANGE_B(zoom_cx, vpDim, squareVertices[0], squareVertices[2])
    ENSURE_RANGE_A_INSIDE_RANGE_B(zoom_cy, vpDim, squareVertices[1], squareVertices[7])

    LoadOrthographicMatrix(
            zoom_cx - vpDim,
            zoom_cx + vpDim,
            zoom_cy - vpDim,
            zoom_cy + vpDim,
            0, 0.5, mat);

    GL_OPERATION(glUniformMatrix4fv(m_uniforms[UNIFORM_PROJ_MATRIX], 1, GL_FALSE, mat))

#define degreesToRadians(d) (2.0 * 3.14157 * d / 360.0)
    float rad = degreesToRadians(nOrientation);

    GL_OPERATION(glUniform1f(m_uniforms[UNIFORM_ROTATION], rad))

    GL_OPERATION(glActiveTexture(GL_TEXTURE0))
    GL_OPERATION(glBindTexture(GL_TEXTURE_2D, m_textures[Y]))
    GL_OPERATION(glUniform1i(m_uniforms[UNIFORM_TEXTURE_Y], 0))
    GL_OPERATION(glActiveTexture(GL_TEXTURE1))
    GL_OPERATION(glBindTexture(GL_TEXTURE_2D, m_textures[U]))
    GL_OPERATION(glUniform1i(m_uniforms[UNIFORM_TEXTURE_U], 1))
    GL_OPERATION(glActiveTexture(GL_TEXTURE2))
    GL_OPERATION(glBindTexture(GL_TEXTURE_2D, m_textures[V]))
    GL_OPERATION(glUniform1i(m_uniforms[UNIFORM_TEXTURE_V], 2))

    GL_OPERATION(glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices))
    GL_OPERATION(glEnableVertexAttribArray(ATTRIB_VERTEX))
    GL_OPERATION(glVertexAttribPointer(ATTRIB_UV, 2, GL_FLOAT, 1, 0, squareUvs))
    GL_OPERATION(glEnableVertexAttribArray(ATTRIB_UV))

    GL_OPERATION(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4))
}

这是LoadOrthographicMatrix

void VideoRenderOpenGL2::LoadOrthographicMatrix(float left, float right, float bottom, float top, float near, float far, float* mat)
{
    float r_l = right - left;
    float t_b = top - bottom;
    float f_n = far - near;
    float tx = - (right + left) / (right - left);
    float ty = - (top + bottom) / (top - bottom);
    float tz = - (far + near) / (far - near);

    mat[0] = (2.0f / r_l);
    mat[1] = mat[2] = mat[3] = 0.0f;

    mat[4] = 0.0f;
    mat[5] = (2.0f / t_b);
    mat[6] = mat[7] = 0.0f;

    mat[8] = mat[9] = 0.0f;
    mat[10] = -2.0f / f_n;
    mat[11] = 0.0f;

    mat[12] = tx;
    mat[13] = ty;
    mat[14] = tz;
    mat[15] = 1.0f;
}

假设我的设备维度为1080 x 1557,我正在尝试在{{2768 x 1557上呈现1280 x 720(高度等于设备高度和相应的宽度,保持纵横比与GLSurfaceView)大小的视频1}}。到目前为止一切正常,Render(const unsigned char *pData)正确渲染,glViewport(0, 0, m_nDisplayWidth, m_nDisplayHeight)工作正常。

但是,当我想加载两倍大小2768 x 1557的视频时,我的意思是5536 x 3114视频在X轴上闪烁/拥塞(未截断)。 Render(...)正在绘制视频的全部内容,但未使用完整画布。我无法弄清楚这里有什么问题。为什么视频在X轴上拥挤? 需要注意的是,当我增加宽度和宽度时,视频会变得更加拥挤。身高超过2倍。可以直到2768 x 1557

1 个答案:

答案 0 :(得分:2)

您可能超出了OpenGL实施的限制。特别是,最大纹理尺寸和最大视口尺寸可以发挥作用。

要查询最大纹理大小,请使用:

GLint maxTexSize = 0;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);

并且对于最大视口尺寸:

GLint viewportDims[2] = {0};
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewportDims);

对于当前的低端设备,这些限制的典型值低至2K,对于旧设备而言甚至可能更低。 4K和8K在当前主流设备中非常普遍。最近的高端移动GPU支持最大16K的大小。

因此,在尝试超过4K的尺寸之前,您一定要检查这些限制。您的5536x3114尺寸很可能会超出一些最新设备的限制。