276 lines
9.2 KiB
C++
276 lines
9.2 KiB
C++
#include "texture.h"
|
||
//#include "globalvar.h"
|
||
|
||
#include <GL/glew.h>
|
||
#include <GL/glu.h>
|
||
|
||
#include <wx/image.h>
|
||
#include <wx/zipstrm.h>
|
||
#include <wx/archive.h>
|
||
#include <wx/fs_zip.h>
|
||
#include <wx/wfstream.h>
|
||
#include <wx/mstream.h>
|
||
#include <wx/glcanvas.h>
|
||
#include <stdio.h>
|
||
|
||
//#include "tools/debug.h"
|
||
|
||
//загрузить текстуру из потока
|
||
unsigned int glLoadBitmap0(int mip,wxInputStream &mis,wxString ext)
|
||
{
|
||
if(mis.IsSeekable()) mis.SeekI(0,wxFromStart);
|
||
unsigned int texName=0;
|
||
glEnable(GL_TEXTURE_2D);
|
||
//glPixelStorei(GL_UNPACK_ALIGNMENT,1);
|
||
glGenTextures(1,&texName);
|
||
glBindTexture(GL_TEXTURE_2D,texName);
|
||
|
||
// glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); //Texture blends with object background
|
||
// glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //Texture does NOT blend with object background
|
||
|
||
//Select a filtering type. BiLinear filtering produces very good results with little performance impact
|
||
// GL_NEAREST - Basic texture (grainy looking texture)
|
||
// GL_LINEAR - BiLinear filtering
|
||
// GL_LINEAR_MIPMAP_NEAREST - Basic mipmapped texture
|
||
// GL_LINEAR_MIPMAP_LINEAR - BiLinear Mipmapped texture
|
||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_LINEAR);//GL_NEAREST GL_LINEAR
|
||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_LINEAR);
|
||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, GL_LINEAR);
|
||
//int mip=2;
|
||
if(mip==0)
|
||
{
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // only first two can be used
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); // all of the above can be used
|
||
}else
|
||
if(mip==1)
|
||
{
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // only first two can be used
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // all of the above can be used
|
||
} else
|
||
if(mip==2)
|
||
{
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); // only first two can be used
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); // all of the above can be used
|
||
} else
|
||
if(mip==3)
|
||
{
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); // only first two can be used
|
||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // all of the above can be used
|
||
}
|
||
|
||
//unsigned short Format=GL_RGB;
|
||
wxImage *m_Image;
|
||
if(ext.Lower()==_T("jpg"))
|
||
m_Image = new wxImage( mis, wxBITMAP_TYPE_JPEG, -1 );
|
||
else
|
||
if(ext.Lower()==_T("bmp"))
|
||
m_Image = new wxImage( mis ,wxBITMAP_TYPE_BMP, -1 );
|
||
else
|
||
if(ext.Lower()==_T("tga"))
|
||
{
|
||
m_Image = new wxImage( mis ,wxBITMAP_TYPE_TGA, -1 );
|
||
}else
|
||
if(ext.Lower()==_T("png"))
|
||
{
|
||
m_Image = new wxImage( mis ,wxBITMAP_TYPE_PNG, -1 );
|
||
}else return 0;
|
||
if(!m_Image->IsOk()) //если плохой рисунок выходим
|
||
{
|
||
delete m_Image;
|
||
return 0;
|
||
}
|
||
|
||
wxImage glImage = m_Image->Mirror(false); //because GL reads textures with 0,0 being the lower-left, we have to flip each image vertically
|
||
if(glImage.HasMask()) glImage.InitAlpha();
|
||
|
||
|
||
//изза того что в wxImage альфа канал храниться отделтно перебираем данные текстуры
|
||
//free(data);
|
||
unsigned char* data = (unsigned char*)malloc(glImage.GetWidth() * glImage.GetHeight() * 4);
|
||
unsigned int d = 0;
|
||
for (int y = 0; y < glImage.GetHeight(); y++)
|
||
{
|
||
for (int x = 0; x < glImage.GetWidth(); x++)
|
||
{
|
||
data[d++] = glImage.GetRed(x, y);
|
||
data[d++] = glImage.GetGreen(x, y);
|
||
data[d++] = glImage.GetBlue(x, y);
|
||
|
||
if(glImage.HasAlpha())
|
||
{
|
||
unsigned char a=glImage.GetAlpha(x, y);
|
||
data[d++] = a;
|
||
}
|
||
else
|
||
data[d++] = 255;
|
||
}
|
||
}
|
||
|
||
if((mip==0)||(mip==1))
|
||
glTexImage2D(GL_TEXTURE_2D, 0, 4, glImage.GetWidth(), glImage.GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||
else
|
||
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, glImage.GetWidth(), glImage.GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||
|
||
free(data);
|
||
|
||
delete m_Image;
|
||
return texName; // Returns the current texture OpenGL ID
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
//загрузить текстуру из файла
|
||
unsigned int glLoadBitmap(int mip,wxString filename)
|
||
{
|
||
if(!wxFile::Exists(filename)) return 0;
|
||
wxFileInputStream mis(filename);
|
||
return glLoadBitmap0(mip,mis,filename.AfterLast(_T('.')));
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
/*TMaterial::TMaterial(TEmptySetPoints *parent):TEmptyPoint(parent)
|
||
{
|
||
textureid=0;
|
||
ColorAmbientRGB.r=0.2f; // 0.2 по умолчанию в OpenGL
|
||
ColorAmbientRGB.g=0.2f;
|
||
ColorAmbientRGB.b=0.2f;
|
||
ColorAmbientRGB.a=1.0f;
|
||
ColorDiffuseRGB.r=0.8f; // 0.8 по умолчанию в OpenGL
|
||
ColorDiffuseRGB.g=0.8f;
|
||
ColorDiffuseRGB.b=0.8f;
|
||
ColorDiffuseRGB.a=1.0f;
|
||
ColorSpecularRGB.r=0.0f; // 0.0 по умолчанию в OpenGL
|
||
ColorSpecularRGB.g=0.0f;
|
||
ColorSpecularRGB.b=0.0f;
|
||
ColorSpecularRGB.a=1.0f;
|
||
data=NULL;
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
TMaterial::~TMaterial()
|
||
{
|
||
if(data!=NULL) free(data);
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
//загрузить рисунок из буфера
|
||
void TMaterial::LoadImage()
|
||
{
|
||
if(imgpath!=_T(""))
|
||
{
|
||
wxMemoryInputStream mis(data,size);
|
||
|
||
textureid=glLoadBitmap0(2,mis,imgpath.AfterLast('.'));
|
||
|
||
free(data);
|
||
data=NULL;
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
void TMaterial::LoadS(wxInputStream *is)
|
||
{
|
||
is->Read(&date,4); //read date
|
||
is->Read(&del,1); //read del
|
||
is->Read(&ObjectID,4); //read ObjectID
|
||
if(!del)
|
||
{
|
||
is->Read(&ColorDiffuseRGB.r,4);
|
||
is->Read(&ColorDiffuseRGB.g,4);
|
||
is->Read(&ColorDiffuseRGB.b,4);
|
||
is->Read(&ColorDiffuseRGB.a,4);
|
||
|
||
is->Read(&Lighting,1);
|
||
is->Read(&blend,1);
|
||
name=loadUTF8String(is); //загрузим название материала
|
||
imgpath=loadUTF8String(is); //загрузим название текстуры
|
||
//загрузим данные текстуры bmp,jpg,tif,png
|
||
is->Read(&size,4);
|
||
if(size>0)
|
||
{
|
||
data = (unsigned char*)malloc(size); //временно в поток потому что текстуру загружать в потоке отличном от контекста нельзя
|
||
is->Read(data,size);
|
||
LoadImage(); //загрузить текстуру и освободить память
|
||
}
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
//устанавливаем материал перед вызовом обьекта
|
||
void TMaterial::Release()
|
||
{
|
||
//прозрачность
|
||
if(blend)
|
||
{
|
||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||
glEnable(GL_BLEND);
|
||
} else glDisable(GL_BLEND);
|
||
if(Lighting) //со светом
|
||
{
|
||
glEnable(GL_LIGHTING);
|
||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (float*)&ColorAmbientRGB);
|
||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (float*)&ColorDiffuseRGB);
|
||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (float*)&ColorSpecularRGB);
|
||
}else
|
||
{//без света
|
||
glDisable(GL_LIGHTING);
|
||
glEnable(GL_COLOR_MATERIAL);
|
||
glColor4f(ColorDiffuseRGB.r,ColorDiffuseRGB.g,ColorDiffuseRGB.b,ColorDiffuseRGB.a);
|
||
glDisable(GL_COLOR_MATERIAL);
|
||
}
|
||
//если текстурированна
|
||
if(textureid!=0)
|
||
{
|
||
glBindTexture(GL_TEXTURE_2D, textureid);
|
||
glEnable(GL_TEXTURE_2D);
|
||
//чтобы цвет не воздействовал на текстуру если она есть
|
||
glEnable(GL_COLOR_MATERIAL);
|
||
glColor4f(1,1,1,ColorDiffuseRGB.a);
|
||
glDisable(GL_COLOR_MATERIAL);
|
||
} else glDisable(GL_TEXTURE_2D);
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
TMaterials::TMaterials(TCity *parent) :TEmptySetPoints(parent)
|
||
{
|
||
ext=_T("mat");
|
||
fid=11347;
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
TMaterials::~TMaterials()
|
||
{
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
void TMaterials::LoadS(wxInputStream *is)
|
||
{
|
||
if(is==NULL) return;
|
||
unsigned int i,count;
|
||
is->Read(&i,4); if(i!=fid) return; //проверка на id файла
|
||
is->Read(&version,4); //версия файла
|
||
is->Read(&fMaxObjectID,4); //максимальный id для этого файла
|
||
is->Read(&fdatesrv,4); //время последнего обновления с сервера сек с 2000
|
||
is->Read(&count,4); //кол во дорог
|
||
List = new TEmptyPoint*[count];
|
||
for(i=0;i<count;i++)
|
||
{
|
||
TMaterial *Material = new TMaterial(this);
|
||
Material->LoadS(is);
|
||
List[i]=Material;
|
||
m_count++;
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
void TMaterials::MouseLUp(RfPointXYZ fGLMLUpXYZ)
|
||
{
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
void TMaterials::MouseRUp(RfPointXYZ fGLMLUpXYZ)
|
||
{
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
void TMaterials::MouseMove(RfPointXYZ fGLMLUpXYZ)
|
||
{
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
void TMaterials::OnMouseWhell(float f)
|
||
{
|
||
}
|
||
//------------------------------------------------------------------------------
|
||
void TMaterials::LoadComplete()
|
||
{
|
||
}*/
|
||
//------------------------------------------------------------------------------
|