Android 宽度在增加宽度&;高度为openGL C和x2B的2倍+;
我正在openGL的Android 宽度在增加宽度&;高度为openGL C和x2B的2倍+;,android,c++,opengl-es,opengl-es-2.0,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)) UpdateText
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))
}
假设我的设备尺寸是1080 x 1557
,我试图在GLSurfaceView
上渲染2768 x 1557
(高度等于设备高度和相应的宽度保持纵横比,带有1280 x 720
)大小的视频。到目前为止,一切工作正常,Render(const unsigned char*pData)
正在正确渲染,glViewport(0,0,m\u nDisplayWidth,m\u nDisplayHeight)
工作正常
但当我想加载两倍于2768x1557大小的视频时,我的意思是5536x114
视频在x轴上闪烁/拥挤(未被截断)。渲染(…)
正在绘制视频的完整内容,但未使用完整画布。我想不出这里出了什么问题。为什么视频在X轴上拥挤?
需要注意的是,当我将宽度和高度增加2倍以上时,视频渲染会更加拥挤。在2768 x 1557之前,一切正常。您可能已经超出了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大小很可能超出了某些较新设备的限制。您可能超出了某些大小限制。例如,使用
glGetIntegerv()
@RetoKoradi查询GL\u MAX\u纹理大小
和GL\u最大视口大小
的值,我检查了GL\u纹理大小
和GL\u最大视口大小
,并为我的设备提供了4096
。我试图将我的视口放大为5536 x 3114
,因此它肯定超出了限制。现在我知道了最大限制,并根据允许的因子放大视口的宽度和高度,使其不会超过限制。请将此评论作为答案发布,以便我可以接受并投票。先生,非常感谢您为我节省了几天时间
GLint viewportDims[2] = {0};
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewportDims);