Я использую EGL в Android, где я в основном пытаюсь повернуть все буферы изображения, отображаемые на экране, на 90 градусов. когда я инициализирую свой объект Renderer, я передаю ссылку на объект NativeWindow и пытаюсь использовать ANativeWindow_setBuffersTransform, чтобы повернуть все буферы на 90 градусов (используя флаг ANATIVEWINDOW_TRANSFORM_ROTATE_90), однако это, похоже, не работает вообще.
Может кто-нибудь сказать мне, возможно ли настроить все кадры так, чтобы они поворачивались на 90 градусов по умолчанию или мне нужно манипулировать каждым кадром, который я получаю, перед его рисованием?
bool Renderer::initialize()
{
const EGLint attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_NONE
};
EGLDisplay display;
EGLConfig config;
EGLint numConfigs;
EGLint format;
EGLSurface surface;
EGLContext context;
GLfloat ratio;
LOG_INFO("Initializing context");
if ((display = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY)
{
LOG_ERROR("eglGetDisplay() returned error %d", eglGetError());
return false;
}
if (!eglInitialize(display, 0, 0))
{
LOG_ERROR("eglInitialize() returned error %d", eglGetError());
return false;
}
if (!eglChooseConfig(display, attribs, &config, 1, &numConfigs))
{
LOG_ERROR("eglChooseConfig() returned error %d", eglGetError());
destroy();
return false;
}
if (!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format))
{
LOG_ERROR("eglGetConfigAttrib() returned error %d", eglGetError());
destroy();
return false;
}
ANativeWindow_setBuffersGeometry(_window, 0, 0, format);
ANativeWindow_setBuffersTransform(_window,ANATIVEWINDOW_TRANSFORM_ROTATE_90);
if (!(surface = eglCreateWindowSurface(display, config, _window, 0)))
{
LOG_ERROR("eglCreateWindowSurface() returned error %d", eglGetError());
destroy();
return false;
}
EGLint ctxattr[] = {
0x3098, 2,
0x30FB, 0,
EGL_NONE
};
if (!(context = eglCreateContext(display, config, 0, ctxattr)))
{
LOG_ERROR("eglCreateContext() returned error %d", eglGetError());
destroy();
return false;
}
if (!eglMakeCurrent(display, surface, surface, context))
{
LOG_ERROR("eglMakeCurrent() returned error %d", eglGetError());
destroy();
return false;
}
if (!eglQuerySurface(display, surface, EGL_WIDTH, &mWidth) ||
!eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight))
{
LOG_ERROR("eglQuerySurface() returned error %d", eglGetError());
destroy();
return false;
}
_display = display;
_surface = surface;
_context = context;
if (Shader::load(vertexSource, fragmentSource, mProgram))
{
// Create a new texture from the camera frame data, display that using the shaders
glGenTextures(1, &mVideoFrameTexture);
glErrorCheck();
glBindTexture(GL_TEXTURE_2D, mVideoFrameTexture);
glErrorCheck();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// This is necessary for non-power-of-two textures
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Using BGRA extension to pull in video frame data directly
//GL_API void GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei) mWidth, (GLsizei) mHeight, 0, GL_RGBA,
GL_UNSIGNED_BYTE, nullptr);
glErrorCheck();
GLint videoFrame = glGetUniformLocation(mProgram, "videoFrame");
uniforms[UNIFORM_VIDEOFRAME] = videoFrame;
setupVertexBuffer(mVao, mVertexBuffer, mIndexBuffer);
return true;
}
return false;
}