#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()) { VertBufferArr[i.first] = std::shared_ptr(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 >::iterator i = Data.Vec3CoordArr.begin(); i != Data.Vec3CoordArr.end(); ++i ) { if (VertBufferArr[i.first] == std::shared_ptr()) { VertBufferArr[i.first] = std::shared_ptr(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& 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& 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& 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& 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 MakeVertexCoordVec(vec2 posFrom, vec2 posTo) { std::vector r; r.resize(6); FillVertexCoordVec(r, 0, posFrom, posTo); return r; } std::vector MakeTexCoordVec(vec2 texCoordFrom, vec2 texCoordTo) { std::vector 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& vertexArr, const std::vector& 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