186 lines
4.6 KiB
C++
186 lines
4.6 KiB
C++
#include "adapter_texture.h"
|
|
#include <SDL3/SDL_opengl.h>
|
|
|
|
#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<davinci::fVector4>& 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<float32_t>& 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();
|
|
}
|