Конвертировать текстуру с IOS-поверхностью в GL_TEXTURE_2D
Я хочу сделать IOSurface
текстура с мипмапингом.
Я генерирую OpenGL
текстура из IOSurface
вот так:
let error = CGLTexImageIOSurface2D(context.cglContextObj!,
GLenum(GL_TEXTURE_RECTANGLE_ARB),GLenum(GL_RGBA), GLsizei(width), GLsizei(height),
GLenum(GL_BGRA), GLenum(GL_UNSIGNED_INT_8_8_8_8_REV), surface!, 0)
И рендеринг с помощью простого фрагментного шейдера:
#version 120
uniform sampler2DRect texture;
varying vec2 texCoord;
uniform vec2 size;
void main(){
vec4 tex = texture2DRect(texture, texCoord*size);
gl_FragColor = tex;
}
Это отлично работает. Но, к сожалению, текстура не имеет растрового изображения и очень зернистая / пиксельная при просмотре в меньшем размере. После дальнейших исследований выясняется, что IOSurface
поддерживаемые текстуры ограничены GL_TEXTURE_RECTANGLE_ARB
target, они также не поддерживают mipmapping.
Отлично. Так что моя лучшая альтернатива здесь:
- Скопируйте
GL_TEXTURE_RECTANGLE_ARB
текстура кGL_TEXTURE_2D
текстура - Создайте мипмапы для этой новой текстуры
Обратите внимание, что я занимаюсь разработкой на Mac, который не поддерживает OpenGL 4.3, поэтому я не могу использовать удобный glCopyImageSubData
Вот. Вместо этого я основываю свой подход к шагу 1 здесь на следующем ответе: Как эффективно скопировать texture1 в texture2?
Мой полный код теперь выглядит так:
if !hasCreatedTexture {
glGenTextures(1, &texture);
glGenTextures(1, &arbTexture);
glGenFramebuffers(1, &fbo)
hasCreatedTexture = true
}
glEnable(GLenum(GL_TEXTURE_RECTANGLE_ARB))
glBindTexture(GLenum(GL_TEXTURE_RECTANGLE_ARB), arbTexture)
let error = CGLTexImageIOSurface2D(context.cglContextObj!, GLenum(GL_TEXTURE_RECTANGLE_ARB), GLenum(GL_RGBA), GLsizei(width), GLsizei(height), GLenum(GL_BGRA), GLenum(GL_UNSIGNED_INT_8_8_8_8_REV), surface!, 0)
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), fbo);
glFramebufferTexture2D(GLenum(GL_READ_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0),
GLenum(GL_TEXTURE_RECTANGLE_ARB), arbTexture, 0);
glFramebufferTexture2D(GLenum(GL_DRAW_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT1),
GLenum(GL_TEXTURE_2D), texture, 0);
glDrawBuffer(GLenum(GL_COLOR_ATTACHMENT1));
glBlitFramebuffer(0, 0, GLint(width), GLint(height), 0, 0, GLint(width), GLint(height), GLbitfield(GL_COLOR_BUFFER_BIT), GLenum(GL_NEAREST));
glBindTexture(GLenum(GL_TEXTURE_2D), texture)
И я изменил свой шейдер для поддержки GL_TEXTURE_2D
:
#version 120
uniform sampler2D texture;
varying vec2 texCoord;
void main(){
vec4 tex = texture2D(texture, texCoord);
gl_FragColor = tex;
}
И вот где я застрял. Изображение полностью черное, и я понятия не имею, почему он не работает.
Я пытался смотреть на данные пикселей так:
var pixelData = UnsafeMutablePointer<GLubyte>(allocatingCapacity: Int(width * height * 4))
glGetTexImage(GLenum(GL_TEXTURE_2D), 0, GLenum(GL_BGRA),
GLenum(GL_UNSIGNED_INT_8_8_8_8_REV), pixelData)
print(NSData(bytes: pixelData, length: 50000).description)
И это все нули. Это что-то не так с моим подходом или проблема может быть связана с IOSurface
поддерживаемые текстуры?
1 ответ
Наконец-то все заработало, используя следующее:
func createMipTexture() {
guard let surface = self.surface else { return }
glBindTexture(GLenum(GL_TEXTURE_2D), texture);
glEnable(GLenum(GL_TEXTURE_2D))
guard let address = IOSurfaceGetBaseAddress(surface) as UnsafeMutableRawPointer? else { return }
IOSurfaceLock(surface, .readOnly, nil)
glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGBA, GLsizei(width), GLsizei(height), 0, GLenum(GL_BGRA), GLenum(GL_UNSIGNED_INT_8_8_8_8_REV), address)
IOSurfaceUnlock(surface, .readOnly, nil);
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAX_LEVEL), 100)
glHint(GLenum(GL_GENERATE_MIPMAP_HINT), GLenum(GL_NICEST));
glGenerateMipmap(GLenum(GL_TEXTURE_2D))
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S), GL_REPEAT);
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T), GL_REPEAT);
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), GL_LINEAR);
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_LINEAR_MIPMAP_LINEAR);
}