#include "adapter_texture.h" #include #include "device/dvc_render_target.h" #include "math/dvc_math_util.h" AdapterTexture::AdapterTexture() : m_canvasTexture(0) , m_canvasWidth(0) , m_canvasHeight(0) , m_textureWidth(0) , m_textureHeight(0) , m_textureBuff(nullptr) { } AdapterTexture::~AdapterTexture() { if (m_textureBuff != nullptr) { delete[] m_textureBuff; m_textureBuff = nullptr; } } void AdapterTexture::init(int32_t canvasWidth, int32_t canvasHeight) { // load and create a texture glGenTextures(1, &m_canvasTexture); glBindTexture(GL_TEXTURE_2D, m_canvasTexture); // set texture filtering parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //create texture buff resize(canvasWidth, canvasHeight); } void AdapterTexture::resize(int32_t canvasWidth, int32_t canvasHeight) { m_canvasWidth = canvasWidth; m_canvasHeight = canvasHeight; //upbound to 4 int32_t textureWidth = canvasWidth; if ((textureWidth & 3) != 0) { textureWidth = (textureWidth & (~3)) + 4; } int32_t textureHeight = canvasHeight; if ((textureHeight & 3) != 0) { textureHeight = (textureHeight & (~3)) + 4; } //same texture size? if (m_textureWidth == textureWidth && m_textureHeight == textureHeight) { return; } m_textureWidth = textureWidth; m_textureHeight = textureHeight; if (m_textureBuff != nullptr) { delete[] m_textureBuff; } //alloc new texture memory buf m_textureBuff = new uint8_t[textureWidth * textureHeight * 3]; memset(m_textureBuff, 0, textureWidth * textureHeight * 3); } void AdapterTexture::updateTexture(void) { if (m_textureBuff == nullptr || m_textureWidth == 0 || m_textureHeight == 0) { //not ready? return; } //fill as blank texture const int32_t BLOCK_SIZE = 10; for (int32_t i = 0; i < m_canvasHeight; i++) { uint8_t* p = m_textureBuff + i * m_textureWidth * 3; for (int32_t j = 0; j < m_canvasWidth; j++) { int ii = i / BLOCK_SIZE; int jj = j / BLOCK_SIZE; bool i_odd = (ii & 1) != 0; bool j_odd = (jj & 1) != 0; if (i_odd != j_odd) { *p++ = (uint8_t)(1 * 255); *p++ = (uint8_t)(1 * 255); *p++ = (uint8_t)(1 * 255); } else { *p++ = (uint8_t)(1 * 220); *p++ = (uint8_t)(1 * 220); *p++ = (uint8_t)(1 * 220); } } } glBindTexture(GL_TEXTURE_2D, m_canvasTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_textureWidth, m_textureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, m_textureBuff); } void AdapterTexture::updateTexture(int32_t start_x, int32_t start_y, const davinci::PixelBuffer& buffer) { int32_t width = buffer.getWidth(); int32_t height = buffer.getHeight(); for (int32_t i = 0; i < height; i++) { int32_t y = start_y + i; if (y >= m_canvasHeight) break; uint8_t* ps = m_textureBuff + y * m_textureWidth * 3; for (int32_t j = 0; j < width; j++) { int32_t x = start_x + j; if (x >= m_canvasWidth) break; uint8_t* p = ps + 3 * x; const davinci::fVector4 color = buffer.getPixel(j, i); *p++ = (uint8_t)(255 * color.x); *p++ = (uint8_t)(255 * color.y); *p++ = (uint8_t)(255 * color.z); } } glBindTexture(GL_TEXTURE_2D, m_canvasTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_textureWidth, m_textureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, m_textureBuff); } void AdapterTexture::updateTexture(int32_t start_x, int32_t start_y, const davinci::PixelBuffer& buffer) { int32_t width = buffer.getWidth(); int32_t height = buffer.getHeight(); for (int32_t i = 0; i < height; i++) { int32_t y = start_y + i; if (y >= m_canvasHeight) break; uint8_t* ps = m_textureBuff + y * m_textureWidth * 3; for (int32_t j = 0; j < width; j++) { int32_t x = start_x + j; if (x >= m_canvasWidth) break; uint8_t* p = ps + 3 * x; const float32_t color = davinci::MathUtil::saturate(buffer.getPixel(j, i)); *p++ = (uint8_t)(255 * color); *p++ = (uint8_t)(255 * color); *p++ = (uint8_t)(255 * color); } } glBindTexture(GL_TEXTURE_2D, m_canvasTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_textureWidth, m_textureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, m_textureBuff); } void AdapterTexture::draw(void) { glBindTexture(GL_TEXTURE_2D, getTextureID()); glBegin(GL_QUADS); float top_pos = (float)m_textureHeight*2.0f / (float)m_canvasHeight-1.0f; float right_pos = (float)m_textureWidth*2.0f / (float)m_canvasWidth-1.0f; glTexCoord2f(0.0, 0.0); glVertex3f(-1.0f, -1.0f, 0); glTexCoord2f(1.0, 0.0); glVertex3f(right_pos, -1.0f, 0); glTexCoord2f(1.0, 1.0); glVertex3f(right_pos, top_pos, 0); glTexCoord2f(0.0, 1.0); glVertex3f(-1.0f, top_pos, 0); glEnd(); }