Moved texture upload to context.
This commit is contained in:
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user