| /* | |
| * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | |
| * | |
| * Use of this source code is governed by a BSD-style license | |
| * that can be found in the LICENSE file in the root of the source | |
| * tree. An additional intellectual property rights grant can be found | |
| * in the file PATENTS. All contributing project authors may | |
| * be found in the AUTHORS file in the root of the source tree. | |
| */ | |
| #include "test/gl/gl_renderer.h" | |
| #include <cstdint> | |
| #include <cstring> | |
| #include "api/video/video_frame.h" | |
| #include "common_video/libyuv/include/webrtc_libyuv.h" | |
| #include "rtc_base/checks.h" | |
| #ifdef WEBRTC_MAC | |
| #include <OpenGL/gl.h> | |
| #else | |
| #include <GL/gl.h> | |
| #endif | |
| namespace webrtc { | |
| namespace test { | |
| GlRenderer::GlRenderer() | |
| : is_init_(false), buffer_(nullptr), width_(0), height_(0) {} | |
| void GlRenderer::Init() { | |
| RTC_DCHECK(!is_init_); | |
| is_init_ = true; | |
| glGenTextures(1, &texture_); | |
| } | |
| void GlRenderer::Destroy() { | |
| if (!is_init_) { | |
| return; | |
| } | |
| is_init_ = false; | |
| delete[] buffer_; | |
| buffer_ = nullptr; | |
| glDeleteTextures(1, &texture_); | |
| } | |
| void GlRenderer::ResizeViewport(size_t width, size_t height) { | |
| // TODO(pbos): Aspect ratio, letterbox the video. | |
| glViewport(0, 0, width, height); | |
| glMatrixMode(GL_PROJECTION); | |
| glLoadIdentity(); | |
| glClearColor(0.0f, 0.0f, 0.0f, 1.0f); | |
| glOrtho(0.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f); | |
| glMatrixMode(GL_MODELVIEW); | |
| } | |
| void GlRenderer::ResizeVideo(size_t width, size_t height) { | |
| RTC_DCHECK(is_init_); | |
| width_ = width; | |
| height_ = height; | |
| buffer_size_ = width * height * 4; // BGRA | |
| delete[] buffer_; | |
| buffer_ = new uint8_t[buffer_size_]; | |
| RTC_DCHECK(buffer_); | |
| memset(buffer_, 0, buffer_size_); | |
| glBindTexture(GL_TEXTURE_2D, texture_); | |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); | |
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); | |
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGRA, | |
| GL_UNSIGNED_INT_8_8_8_8, static_cast<GLvoid*>(buffer_)); | |
| } | |
| void GlRenderer::OnFrame(const VideoFrame& frame) { | |
| RTC_DCHECK(is_init_); | |
| if (static_cast<size_t>(frame.width()) != width_ || | |
| static_cast<size_t>(frame.height()) != height_) { | |
| ResizeVideo(frame.width(), frame.height()); | |
| } | |
| ConvertFromI420(frame, VideoType::kBGRA, 0, buffer_); | |
| glEnable(GL_TEXTURE_2D); | |
| glBindTexture(GL_TEXTURE_2D, texture_); | |
| glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, GL_BGRA, | |
| GL_UNSIGNED_INT_8_8_8_8, buffer_); | |
| glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
| glLoadIdentity(); | |
| glBegin(GL_QUADS); | |
| { | |
| glTexCoord2f(0.0f, 0.0f); | |
| glVertex3f(0.0f, 0.0f, 0.0f); | |
| glTexCoord2f(0.0f, 1.0f); | |
| glVertex3f(0.0f, 1.0f, 0.0f); | |
| glTexCoord2f(1.0f, 1.0f); | |
| glVertex3f(1.0f, 1.0f, 0.0f); | |
| glTexCoord2f(1.0f, 0.0f); | |
| glVertex3f(1.0f, 0.0f, 0.0f); | |
| } | |
| glEnd(); | |
| glBindTexture(GL_TEXTURE_2D, 0); | |
| glFlush(); | |
| } | |
| } // namespace test | |
| } // namespace webrtc |