engine/src/Render/RenderMisc.cpp
2013-12-01 22:42:47 +00:00

402 lines
9.7 KiB
C++

#include "include/Engine.h"
namespace SE
{
#ifdef TARGET_WIN32
VBOObject::VBOObject()
{
AssertIfInMainThread();
glGenBuffers(1, &Buffer);
}
VBOObject::VBOObject(const VBOObject& c)
{
throw ErrorToLog("Copy constructor for VBOObject called\n");
}
VBOObject& VBOObject::operator=(const VBOObject& c)
{
throw ErrorToLog("operator= for VBOObject called\n");
return *this;
}
VBOObject::~VBOObject()
{
AssertIfInMainThread();
glDeleteBuffers(1, &Buffer);
}
#endif
TDataTriangleList& TDataTriangleList::operator+=(const TDataTriangleList& dataTriangleList)
{
BOOST_FOREACH(auto& i, dataTriangleList.Vec3CoordArr)
{
if (Vec3CoordArr.count(i.first) == 0)
{
Vec3CoordArr[i.first] = i.second;
}
else
{
Vec3CoordArr[i.first].insert(Vec3CoordArr[i.first].end(), i.second.begin(), i.second.end());
}
}
BOOST_FOREACH(auto& i, dataTriangleList.Vec2CoordArr)
{
if (Vec2CoordArr.count(i.first) == 0)
{
Vec2CoordArr[i.first] = i.second;
}
else
{
Vec2CoordArr[i.first].insert(Vec2CoordArr[i.first].end(), i.second.begin(), i.second.end());
}
}
return *this;
}
TTriangleListAncestor::TTriangleListAncestor()
{
}
TTriangleListAncestor::TTriangleListAncestor(const TTriangleListAncestor& c)
{
Data = c.Data;
}
TTriangleListAncestor& TTriangleListAncestor::operator=(const TTriangleListAncestor& c)
{
Data = c.Data;
RefreshBuffer();
return *this;
}
TTriangleListAncestor::TTriangleListAncestor(const TDataTriangleList& dataTriangleList)
{
Data = dataTriangleList;
}
TTriangleListAncestor& TTriangleListAncestor::operator=(const TDataTriangleList& dataTriangleList)
{
Data = dataTriangleList;
RefreshBuffer();
return *this;
}
TTriangleListAncestor::~TTriangleListAncestor()
{
}
#ifdef TARGET_WIN32
TTriangleList::TTriangleList()
: TTriangleListAncestor()
, NeedPrepareBufferObjects(true)
, NeedRefreshBuffer(false)
{
}
TTriangleList::~TTriangleList()
{
}
void TTriangleList::InnerRefreshBuffer()
{
AssertIfInMainThread();
if (NeedPrepareBufferObjects && Data.Vec2CoordArr.size() > 0 && Data.Vec3CoordArr.size() > 0)
{
NeedPrepareBufferObjects = false;
BOOST_FOREACH(auto& i, Data.Vec2CoordArr)
{
if (VertBufferArr[i.first] == std::shared_ptr<VBOObject>())
{
VertBufferArr[i.first] = std::shared_ptr<VBOObject>(new VBOObject);
glBindBuffer(GL_ARRAY_BUFFER, VertBufferArr[i.first]->Buffer);
//What to do if buffer becomes empty?
if (i.second.size() > 0)
{
glBufferData(GL_ARRAY_BUFFER, i.second.size() * 8, &i.second[0], GL_STATIC_DRAW);
}
else
{
glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_STATIC_DRAW);
}
}
}
BOOST_FOREACH(auto& i, Data.Vec3CoordArr)
//for (std::map<std::string, std::vector<vec3> >::iterator i = Data.Vec3CoordArr.begin(); i != Data.Vec3CoordArr.end(); ++i )
{
if (VertBufferArr[i.first] == std::shared_ptr<VBOObject>())
{
VertBufferArr[i.first] = std::shared_ptr<VBOObject>(new VBOObject);
glBindBuffer(GL_ARRAY_BUFFER, VertBufferArr[i.first]->Buffer);
//What to do if buffer becomes empty?
if (i.second.size() > 0)
{
glBufferData(GL_ARRAY_BUFFER, i.second.size() * 12, &i.second[0], GL_STATIC_DRAW);
}
else
{
glBufferData(GL_ARRAY_BUFFER, 0, NULL, GL_STATIC_DRAW);
}
}
}
}
BOOST_FOREACH(auto& i, Data.Vec2CoordArr)
{
glBindBuffer(GL_ARRAY_BUFFER, VertBufferArr[i.first]->Buffer);
RefreshAttribBuffer2fv(i.first, Data.Vec2CoordArr);
}
BOOST_FOREACH(auto& i, Data.Vec3CoordArr)
{
glBindBuffer(GL_ARRAY_BUFFER, VertBufferArr[i.first]->Buffer);
RefreshAttribBuffer3fv(i.first, Data.Vec3CoordArr);
}
NeedRefreshBuffer = false;
}
void TTriangleList::RefreshBuffer()
{
if (!NeedRefreshBuffer)
{
NeedRefreshBuffer = true;
PerformInMainThreadAsync(boost::bind(&TTriangleList::InnerRefreshBuffer, this));
}
}
#endif
void FillVertexCoordVec(std::vector<vec3>& coordVec, int pos, vec2 posFrom, vec2 posTo)
{
vec2 pos1 = posFrom;
vec2 pos2 = vec2(posFrom.v[0], posTo.v[1]);
vec2 pos3 = posTo;
vec2 pos4 = vec2(posTo.v[0], posFrom.v[1]);
coordVec[pos] = vec3(pos1, 0);
coordVec[pos+1] = vec3(pos2, 0);
coordVec[pos+2] = vec3(pos3, 0);
coordVec[pos+3] = vec3(pos3, 0);
coordVec[pos+4] = vec3(pos4, 0);
coordVec[pos+5] = vec3(pos1, 0);
}
void FillTexCoordVec(std::vector<vec2>& coordVec, int pos, vec2 texCoordFrom, vec2 texCoordTo)
{
vec2 tex1 = texCoordFrom;
vec2 tex2 = vec2(texCoordFrom.v[0], texCoordTo.v[1]);
vec2 tex3 = texCoordTo;
vec2 tex4 = vec2(texCoordTo.v[0], texCoordFrom.v[1]);
coordVec[pos] = tex1;
coordVec[pos+1] = tex2;
coordVec[pos+2] = tex3;
coordVec[pos+3] = tex3;
coordVec[pos+4] = tex4;
coordVec[pos+5] = tex1;
}
void FillVertexCoordVec_4Points(std::vector<vec3>& coordVec, int pos, vec2 pos1, vec2 pos2, vec2 pos3, vec2 pos4)
{
coordVec[pos] = vec3(pos1, 0);
coordVec[pos+1] = vec3(pos2, 0);
coordVec[pos+2] = vec3(pos3, 0);
coordVec[pos+3] = vec3(pos3, 0);
coordVec[pos+4] = vec3(pos4, 0);
coordVec[pos+5] = vec3(pos1, 0);
}
void FillTexCoordVec_4Points(std::vector<vec2>& coordVec, int pos, vec2 texCoord1, vec2 texCoord2, vec2 texCoord3, vec2 texCoord4)
{
coordVec[pos] = texCoord1;
coordVec[pos+1] = texCoord2;
coordVec[pos+2] = texCoord3;
coordVec[pos+3] = texCoord3;
coordVec[pos+4] = texCoord4;
coordVec[pos+5] = texCoord1;
}
std::vector<vec3> MakeVertexCoordVec(vec2 posFrom, vec2 posTo)
{
std::vector<vec3> r;
r.resize(6);
FillVertexCoordVec(r, 0, posFrom, posTo);
return r;
}
std::vector<vec2> MakeTexCoordVec(vec2 texCoordFrom, vec2 texCoordTo)
{
std::vector<vec2> r;
r.resize(6);
FillTexCoordVec(r, 0, texCoordFrom, texCoordTo);
return r;
}
TDataTriangleList MakeDataTriangleList(vec2 posFrom, vec2 posTo, vec2 texCoordFrom, vec2 texCoordTo)
{
TDataTriangleList triangleList;
triangleList.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB] = MakeVertexCoordVec(posFrom, posTo);
triangleList.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB] = MakeTexCoordVec(texCoordFrom, texCoordTo);
return triangleList;
}
void MoveDataTriangleList(TDataTriangleList& triangleList, vec3 shift)
{
if (triangleList.Vec3CoordArr.count(CONST_STRING_POSITION_ATTRIB) == 0)
{
return;
}
BOOST_FOREACH(auto& i, triangleList.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB])
{
i += shift;
}
}
void RotateDataTriangleList(TDataTriangleList& triangleList, const mat3& m)
{
if (triangleList.Vec3CoordArr.count(CONST_STRING_POSITION_ATTRIB) == 0)
{
return;
}
BOOST_FOREACH(vec3& i, triangleList.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB])
{
i = i * m;
}
}
void ScaleDataTriangleList(TDataTriangleList& triangleList, float scale)
{
if (triangleList.Vec3CoordArr.count(CONST_STRING_POSITION_ATTRIB) == 0)
{
return;
}
BOOST_FOREACH(vec3& i, triangleList.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB])
{
i.v[0] *= scale;
i.v[1] *= scale;
i.v[2] *= scale;
}
}
void ScaleDataTriangleList(TDataTriangleList& triangleList, vec3 scaleVec)
{
if (triangleList.Vec3CoordArr.count(CONST_STRING_POSITION_ATTRIB) == 0)
{
return;
}
BOOST_FOREACH(vec3& i, triangleList.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB])
{
i.v[0] *= scaleVec.v[0];
i.v[1] *= scaleVec.v[1];
i.v[2] *= scaleVec.v[2];
}
}
TDataTriangleList& ClearDataTriangleList(TDataTriangleList& triangleList)
{
BOOST_FOREACH(auto& i, triangleList.Vec2CoordArr)
{
i.second.clear();
}
BOOST_FOREACH(auto& i, triangleList.Vec3CoordArr)
{
i.second.clear();
}
return triangleList;
}
TDataTriangleList& InsertIntoDataTriangleList(TDataTriangleList& triangleList, const std::vector<vec3>& vertexArr, const std::vector<vec2>& texCoordArr)
{
triangleList.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].insert(triangleList.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].end(), vertexArr.begin(), vertexArr.end());
triangleList.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].insert(triangleList.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].end(), texCoordArr.begin(), texCoordArr.end());
return triangleList;
}
TTriangleList MakeTriangleList(vec2 posFrom, vec2 posTo, vec2 texCoordFrom, vec2 texCoordTo)
{
TTriangleList triangleList;
triangleList.Data = MakeDataTriangleList(posFrom, posTo, texCoordFrom, texCoordTo);
triangleList.RefreshBuffer();
return triangleList;
}
void Replace6PointsInTriangleList(TDataTriangleList& triangleList, int pos, vec2 posFrom, vec2 posTo, vec2 texCoordFrom, vec2 texCoordTo)
{
FillVertexCoordVec(triangleList.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB], pos, posFrom, posTo);
FillTexCoordVec(triangleList.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB], pos, texCoordFrom, texCoordTo);
}
void Replace6PointsInTriangleList_4Points(TDataTriangleList& triangleList, int pos, vec2 pos1, vec2 pos2, vec2 pos3, vec2 pos4, vec2 texCoord1, vec2 texCoord2, vec2 texCoord3, vec2 texCoord4)
{
FillVertexCoordVec_4Points(triangleList.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB], pos, pos1, pos2, pos3, pos4);
FillTexCoordVec_4Points(triangleList.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB], pos, texCoord1, texCoord2, texCoord3, texCoord4);
}
void CheckGlError(const std::string& msg)
{
AssertIfInMainThread();
cardinal error = glGetError();
if (error != GL_NO_ERROR)
{
if (msg == "")
{
throw ErrorToLog("Gl error = "+tostr(error));
}
else
{
throw ErrorToLog("Gl error = "+tostr(error) + "; with message = " + msg);
}
}
}
} //namespace SE