Moved texture upload to context.

This commit is contained in:
Leonardo Zide
2021-11-21 18:25:17 -08:00
parent a9ab7c0c64
commit 408dc6ff97
4 changed files with 154 additions and 124 deletions
+119
View File
@@ -668,6 +668,125 @@ void lcContext::ClearTextureCubeMap()
mTextureCubeMap = 0;
}
void lcContext::UploadTexture(lcTexture* Texture)
{
if (!Texture->mTexture)
glGenTextures(1, &Texture->mTexture);
constexpr int Filters[2][5] =
{
{ GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR_MIPMAP_LINEAR },
{ GL_NEAREST, GL_LINEAR, GL_LINEAR, GL_LINEAR, GL_LINEAR },
};
const int Flags = Texture->GetFlags();
const int FilterFlags = Flags & LC_TEXTURE_FILTER_MASK;
const int FilterIndex = FilterFlags >> LC_TEXTURE_FILTER_SHIFT;
const int MipIndex = Flags & LC_TEXTURE_MIPMAPS ? 0 : 1;
unsigned int Faces, Target;
if ((Flags & LC_TEXTURE_CUBEMAP) == 0)
{
Faces = 1;
Target = GL_TEXTURE_2D;
BindTexture2D(Texture);
}
else
{
Faces = 6;
Target = GL_TEXTURE_CUBE_MAP;
BindTextureCubeMap(Texture);
}
glTexParameteri(Target, GL_TEXTURE_WRAP_S, (Flags & LC_TEXTURE_WRAPU) ? GL_REPEAT : GL_CLAMP_TO_EDGE);
glTexParameteri(Target, GL_TEXTURE_WRAP_T, (Flags & LC_TEXTURE_WRAPV) ? GL_REPEAT : GL_CLAMP_TO_EDGE);
glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, Filters[MipIndex][FilterIndex]);
glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, Filters[1][FilterIndex]);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
if (gSupportsAnisotropic && FilterFlags == LC_TEXTURE_ANISOTROPIC)
glTexParameterf(Target, GL_TEXTURE_MAX_ANISOTROPY_EXT, lcMin(4.0f, gMaxAnisotropy));
int Format;
switch (Texture->GetImage(0).mFormat)
{
default:
case lcPixelFormat::Invalid:
Format = 0;
break;
case lcPixelFormat::A8:
Format = GL_ALPHA;
break;
case lcPixelFormat::L8A8:
Format = GL_LUMINANCE_ALPHA;
break;
case lcPixelFormat::R8G8B8:
Format = GL_RGB;
break;
case lcPixelFormat::R8G8B8A8:
Format = GL_RGBA;
break;
}
int CurrentImage = 0;
if (Flags & LC_TEXTURE_CUBEMAP)
Target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
for (size_t FaceIdx = 0; FaceIdx < Faces; FaceIdx++)
{
void* Data = Texture->GetImage(CurrentImage).mData;
glTexImage2D(Target, 0, Format, Texture->mWidth, Texture->mHeight, 0, Format, GL_UNSIGNED_BYTE, Data);
if (Flags & LC_TEXTURE_MIPMAPS || FilterFlags >= LC_TEXTURE_BILINEAR)
{
int Width = Texture->mWidth;
int Height = Texture->mHeight;
int Components = Texture->GetImage(CurrentImage).GetBPP();
for (int Level = 1; ((Width != 1) || (Height != 1)); Level++)
{
int RowStride = Width * Components;
Width = lcMax(1, Width >> 1);
Height = lcMax(1, Height >> 1);
if (Texture->GetImageCount() == Faces)
{
GLubyte* Out, * In;
In = Out = (GLubyte*)Data;
for (int y = 0; y < Height; y++, In += RowStride)
for (int x = 0; x < Width; x++, Out += Components, In += 2 * Components)
for (int c = 0; c < Components; c++)
Out[c] = (In[c] + In[c + Components] + In[RowStride] + In[c + RowStride + Components]) / 4;
}
else
Data = Texture->GetImage(++CurrentImage).mData;
glTexImage2D(Target, Level, Format, Width, Height, 0, Format, GL_UNSIGNED_BYTE, Data);
}
if (Texture->GetImageCount() == Faces)
CurrentImage++;
}
else
CurrentImage++;
Target++;
}
if ((Flags & LC_TEXTURE_CUBEMAP) == 0)
ClearTexture2D();
else
ClearTextureCubeMap();
}
void lcContext::SetColor(float Red, float Green, float Blue, float Alpha)
{
SetColor(lcVector4(Red, Green, Blue, Alpha));