CObject* build() { sys::info << "ogl::CBoxObjectBuilder::build()" << sys::endl; float dmax = hasOption(CObjectBuilder::NORMALIZED) ? math::max(mWidth, math::max(mHeight, mDepth)) : 1.0f; float hwidth = (mWidth / 2.0f) / dmax; float hheight = (mHeight / 2.0f) / dmax; float hdepth = (mDepth / 2.0f) / dmax; const size_t nNumVertices = 24; const size_t nNumIndices = 36; // bool bFlatface = hasOption(CObjectBuilder::FLATFACE); math::vec3* positions = new math::vec3[nNumVertices]; positions[ 0] = math::vec3(-hwidth,-hheight, hdepth); positions[ 1] = math::vec3(-hwidth,-hheight, hdepth); positions[ 2] = math::vec3(-hwidth,-hheight, hdepth); positions[ 3] = math::vec3( hwidth,-hheight, hdepth); positions[ 4] = math::vec3( hwidth,-hheight, hdepth); positions[ 5] = math::vec3( hwidth,-hheight, hdepth); positions[ 6] = math::vec3( hwidth, hheight, hdepth); positions[ 7] = math::vec3( hwidth, hheight, hdepth); positions[ 8] = math::vec3( hwidth, hheight, hdepth); positions[ 9] = math::vec3(-hwidth, hheight, hdepth); positions[10] = math::vec3(-hwidth, hheight, hdepth); positions[11] = math::vec3(-hwidth, hheight, hdepth); positions[12] = math::vec3(-hwidth,-hheight,-hdepth); positions[13] = math::vec3(-hwidth,-hheight,-hdepth); positions[14] = math::vec3(-hwidth,-hheight,-hdepth); positions[15] = math::vec3( hwidth,-hheight,-hdepth); positions[16] = math::vec3( hwidth,-hheight,-hdepth); positions[17] = math::vec3( hwidth,-hheight,-hdepth); positions[18] = math::vec3( hwidth, hheight,-hdepth); positions[19] = math::vec3( hwidth, hheight,-hdepth); positions[20] = math::vec3( hwidth, hheight,-hdepth); positions[21] = math::vec3(-hwidth, hheight,-hdepth); positions[22] = math::vec3(-hwidth, hheight,-hdepth); positions[23] = math::vec3(-hwidth, hheight,-hdepth); math::vec2* texcoords = new math::vec2[nNumVertices]; texcoords[ 0] = math::vec2(1.0f, 1.0f); texcoords[ 1] = math::vec2(0.0f, 1.0f); texcoords[ 2] = math::vec2(0.0f, 1.0f); texcoords[ 3] = math::vec2(0.0f, 1.0f); texcoords[ 4] = math::vec2(1.0f, 1.0f); texcoords[ 5] = math::vec2(1.0f, 1.0f); texcoords[ 6] = math::vec2(0.0f, 0.0f); texcoords[ 7] = math::vec2(1.0f, 0.0f); texcoords[ 8] = math::vec2(1.0f, 0.0f); texcoords[ 9] = math::vec2(1.0f, 0.0f); texcoords[10] = math::vec2(0.0f, 0.0f); texcoords[11] = math::vec2(0.0f, 0.0f); texcoords[12] = math::vec2(0.0f, 1.0f); texcoords[13] = math::vec2(1.0f, 1.0f); texcoords[14] = math::vec2(0.0f, 0.0f); texcoords[15] = math::vec2(1.0f, 1.0f); texcoords[16] = math::vec2(0.0f, 1.0f); texcoords[17] = math::vec2(1.0f, 0.0f); texcoords[18] = math::vec2(1.0f, 0.0f); texcoords[19] = math::vec2(0.0f, 0.0f); texcoords[20] = math::vec2(1.0f, 1.0f); texcoords[21] = math::vec2(0.0f, 0.0f); texcoords[22] = math::vec2(1.0f, 0.0f); texcoords[23] = math::vec2(0.0f, 1.0f); math::vec3* normals = new math::vec3[nNumVertices]; normals[ 0] = math::vec3( 0.0f, 0.0f, 1.0f); normals[ 1] = math::vec3(-1.0f, 0.0f, 0.0f); normals[ 2] = math::vec3( 0.0f,-1.0f, 0.0f); normals[ 3] = math::vec3( 0.0f, 0.0f, 1.0f); normals[ 4] = math::vec3( 1.0f, 0.0f, 0.0f); normals[ 5] = math::vec3( 0.0f,-1.0f, 0.0f); normals[ 6] = math::vec3( 0.0f, 0.0f, 1.0f); normals[ 7] = math::vec3( 1.0f, 0.0f, 0.0f); normals[ 8] = math::vec3( 0.0f, 1.0f, 0.0f); normals[ 9] = math::vec3( 0.0f, 0.0f, 1.0f); normals[10] = math::vec3(-1.0f, 0.0f, 0.0f); normals[11] = math::vec3( 0.0f, 1.0f, 0.0f); normals[12] = math::vec3( 0.0f, 0.0f,-1.0f); normals[13] = math::vec3(-1.0f, 0.0f, 0.0f); normals[14] = math::vec3( 0.0f,-1.0f, 0.0f); normals[15] = math::vec3( 0.0f, 0.0f,-1.0f); normals[16] = math::vec3( 1.0f, 0.0f, 0.0f); normals[17] = math::vec3( 0.0f,-1.0f, 0.0f); normals[18] = math::vec3( 0.0f, 0.0f,-1.0f); normals[19] = math::vec3( 1.0f, 0.0f, 0.0f); normals[20] = math::vec3( 0.0f, 1.0f, 0.0f); normals[21] = math::vec3( 0.0f, 0.0f,-1.0f); normals[22] = math::vec3(-1.0f, 0.0f, 0.0f); normals[23] = math::vec3( 0.0f, 1.0f, 0.0f); static GLushort indices[] = { 3, 0, 9, // triangle 0 // face 0 // +z 3, 9, 6, // triangle 1 // face 0 12, 15, 18, // triangle 2 // face 1 // -z 12, 18, 21, // triangle 3 // face 1 1, 13, 22, // triangle 4 // face 2 // -x 1, 22, 10, // triangle 5 // face 2 16, 4, 7, // triangle 6 // face 3 // +x 16, 7, 19, // triangle 7 // face 4 2, 5, 17, // triangle 8 // face 5 // -y 2, 17, 14, // triangle 9 // face 5 23, 20, 8, // triangle 10 // face 6 // +y 23, 8, 11 // triangle 11 // face 7 }; math::vec3* tangents = new math::vec3[nNumVertices]; math::vec3* binormals = new math::vec3[nNumVertices]; for(size_t i = 0; i < nNumIndices; i+=3) // for every triangle { ushort i0 = indices[i+0]; ushort i1 = indices[i+1]; ushort i2 = indices[i+2]; math::vec3& p0 = positions[i0]; math::vec3& p1 = positions[i1]; math::vec3& p2 = positions[i2]; math::vec2& t0 = texcoords[i0]; math::vec2& t1 = texcoords[i1]; math::vec2& t2 = texcoords[i2]; math::vec3 dp1(p1 - p0); // e1 math::vec3 dp2(p2 - p0); // e2 math::vec3 normal = math::normalize(math::cross(dp2, dp1)); normals[i0] += normal; // avarage the normals normals[i0] = math::normalize(normals[i0]); normals[i1] += normal; normals[i1] = math::normalize(normals[i1]); normals[i2] += normal; normals[i2] = math::normalize(normals[i2]); math::vec2 dt1 = t1 - t0; math::vec2 dt2 = t2 - t0; float r = 1.0f / (dt1.x * dt2.y - dt1.y * dt2.x); math::vec3 ta = (dp1 * dt2.y - dp2 * dt1.y) * r; // tangent math::vec3 bi = (dp2 * dt1.x - dp1 * dt2.x) * r; // binormal tangents[i0] = ta; tangents[i1] = ta; tangents[i2] = ta; binormals[i0] = bi; binormals[i1] = bi; binormals[i2] = bi; } if(hasOption(CObjectBuilder::INVERTED)) { for(size_t i = 0; i < nNumVertices; ++i) { normals[i] *= -1.0f; tangents[i] *= -1.0f; binormals[i] *= -1.0f; } for(ushort i = 0; i < nNumIndices; i+=3) { GLushort tmp = indices[i+1]; indices[i+1] = indices[i+2]; indices[i+2] = tmp; } } if(mTextureScale != 1.0f) { for(size_t i = 0; i < nNumVertices; ++i) texcoords[i] = texcoords[i] / mTextureScale; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// CObject* pObject = new CObject; pObject->mNumVertices = nNumVertices; pObject->mNumIndices = nNumIndices; pObject->setDrawStrategy(mDrawStrategy == nullptr ? new CDrawStrategy : mDrawStrategy); //////////////////////////////////////////////////////////////////////////////////////////////////////////////// { // shapes CShape* pShape = new CShape; pShape->setVertexBufferRange(0, pObject->mNumVertices, GL_FLOAT); pShape->setIndexBufferRange(0, pObject->mNumIndices, GL_UNSIGNED_SHORT); CMaterial* pMaterial = new CMaterial; CDdsTextureBuilder* pTextureBuilder = new CDdsTextureBuilder; pTextureBuilder->setFile("notfound.dds"); CTexture* pTexture = pTextureBuilder->build(); pTexture->setFiltering(CTexture::EFiltering::TRILINEAR); delete pTextureBuilder; pMaterial->setTexture(CTexture::EScope::DIFFUSE, pTexture); pShape->setMaterial(pMaterial); pObject->addShape(pShape); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////// pObject->mBuffers.resize(5); glGenVertexArrays(1, &(pObject->mVAO)); glBindVertexArray(pObject->mVAO); // indices glGenBuffers(1, &(pObject->mBuffers[INDEX_BUFFER_INDEX])); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, pObject->mBuffers[INDEX_BUFFER_INDEX]); glBufferData(GL_ELEMENT_ARRAY_BUFFER, nNumIndices * sizeof(GLushort), indices, GL_STATIC_DRAW); // positions glGenBuffers(1, &(pObject->mBuffers[POSITION_BUFFER_INDEX])); glBindBuffer(GL_ARRAY_BUFFER, pObject->mBuffers[POSITION_BUFFER_INDEX]); glBufferData(GL_ARRAY_BUFFER, nNumVertices * sizeof(math::vec3), positions, GL_STATIC_DRAW); glVertexAttribPointer(POSITION_ATTRIBUTE, 3, GL_FLOAT, GL_FALSE, sizeof(math::vec3), (const GLvoid*)(0)); glEnableVertexAttribArray(POSITION_ATTRIBUTE); // positions // texcoords glGenBuffers(1, &(pObject->mBuffers[TEXCOORD_BUFFER_INDEX])); glBindBuffer(GL_ARRAY_BUFFER, pObject->mBuffers[TEXCOORD_BUFFER_INDEX]); glBufferData(GL_ARRAY_BUFFER, nNumVertices * sizeof(math::vec2), texcoords, GL_STATIC_DRAW); glVertexAttribPointer(TEXCOORD_ATTRIBUTE, 2, GL_FLOAT, GL_FALSE, sizeof(math::vec2), (const GLvoid*)(0)); //(GLvoid*)((0 + 3) * sizeof(GLfloat))); glEnableVertexAttribArray(TEXCOORD_ATTRIBUTE); // texcoords // normals glGenBuffers(1, &(pObject->mBuffers[NORMAL_BUFFER_INDEX])); glBindBuffer(GL_ARRAY_BUFFER, pObject->mBuffers[NORMAL_BUFFER_INDEX]); glBufferData(GL_ARRAY_BUFFER, nNumVertices * sizeof(math::vec3), normals, GL_STATIC_DRAW); glVertexAttribPointer(NORMAL_ATTRIBUTE, 3, GL_FLOAT, GL_FALSE, sizeof(math::vec3), (const GLvoid*)(0)); //(GLvoid*)((0 + 3 + 2) * sizeof(GLfloat))); glEnableVertexAttribArray(NORMAL_ATTRIBUTE); // normals // tangents glGenBuffers(1, &(pObject->mBuffers[TANGENT_BUFFER_INDEX])); glBindBuffer(GL_ARRAY_BUFFER, pObject->mBuffers[TANGENT_BUFFER_INDEX]); glBufferData(GL_ARRAY_BUFFER, nNumVertices * sizeof(math::vec3), tangents, GL_STATIC_DRAW); glVertexAttribPointer(TANGENT_ATTRIBUTE, 3, GL_FLOAT, GL_FALSE, sizeof(math::vec3), (const GLvoid*)(0)); //(GLvoid*)((0 + 3 + 2) * sizeof(GLfloat))); glEnableVertexAttribArray(TANGENT_ATTRIBUTE); // tangents // clean glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindVertexArray(0); delete [] positions; delete [] texcoords; delete [] normals; delete [] tangents; delete [] binormals; //////////////////////////////////////////////////////////////////////////////////////////////////////////////// return pObject; }
void CDeform2d::doDeform(const TPoint2DVect &surf, IDriver *drv, IPerturbUV *uvp) { nlassert(uvp); typedef CQuadEffect::TPoint2DVect TPoint2DVect; TPoint2DVect dest; CQuadEffect::processPoly(surf, (float) _XGranularity, (float) _YGranularity, dest); uint realWidth = NLMISC::raiseToNextPowerOf2(_Width); uint realHeight= NLMISC::raiseToNextPowerOf2(_Height); // draw the poly contour /*for (uint k = 0; k < dest.size(); ++k) { CDRU::drawLine(dest[k].x, dest[k].y, dest[(k + 1) % dest.size()].x, dest[(k + 1) % dest.size()].y, *drv, CRGBA::Red); }*/ static CMaterial mat; mat.setDoubleSided(true); mat.setLighting(false); mat.setZFunc(CMaterial::always); /* mat.setColor(CRGBA::Red); mat.texEnvOpRGB(0, CMaterial::Add); */ static CVertexBuffer vb; vb.setName("CDeform2d"); vb.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag); drv->setFrustum(0, (float) _Width, 0, (float) _Height, -1, 1, false); drv->setupViewMatrix(CMatrix::Identity); drv->setupModelMatrix(CMatrix::Identity); const float iDu = 1.f / _Width; const float iDv = 1.f / _Height; const float widthRatio = _Width / (float) realWidth; const float heightRatio = _Height / (float) realHeight; float u, u2, v; float du, dv; TPoint2DVect::const_iterator it; // get back datas from frame buffer for (it = dest.begin(); it != dest.end(); ++it) { // todo hulud use the new render to texture interface // drv->copyFrameBufferToTexture(_Tex, 0, (uint32) it->x,(uint32) it->y, (uint32) it->x, (uint32) it->y, _XGranularity, _YGranularity); } /** setup the whole vertex buffer * we don't share vertices here, as we work with unaligned quads */ vb.setNumVertices((uint32)dest.size() << 2); mat.setTexture(0, _Tex); { CVertexBufferReadWrite vba; vb.lock (vba); uint k = 0; // current index in the vertex buffer for (it = dest.begin(); it != dest.end(); ++it, k += 4) { // \todo optimize this by a direct access to the vertex buffer (if needed) // blit data to frame buffer and apply deformations vba.setVertexCoord(k, NLMISC::CVector(it->x, 0, it->y)); vba.setVertexCoord(k + 1, NLMISC::CVector(it->x + _XGranularity, 0, it->y)); vba.setVertexCoord(k + 2, NLMISC::CVector(it->x + _XGranularity, 0, it->y + _YGranularity)); vba.setVertexCoord(k + 3, NLMISC::CVector(it->x , 0, it->y + _YGranularity)); // perturbation of the uv coordinates u = it->x * iDu; v = it->y * iDv; uvp->perturbUV(u, v, du, dv); vba.setTexCoord(k, 0, (u + du) * widthRatio, (v + dv) * heightRatio ); u2 = (it->x + _XGranularity) * iDu; uvp->perturbUV(u2, v, du, dv); vba.setTexCoord(k + 1, 0, (u2 + du) * widthRatio, (v + dv) * heightRatio ); v = (it->y + _YGranularity) * iDv; uvp->perturbUV(u2, v, du, dv); vba.setTexCoord(k + 2, 0, (u2 + du) * widthRatio, (v + dv) * heightRatio ); uvp->perturbUV(u, v, du, dv); vba.setTexCoord(k + 3, 0, (u + du) * widthRatio, (v + dv) * heightRatio ); } } drv->activeVertexBuffer(vb); drv->renderRawQuads(mat, 0, (uint32)dest.size()); }
bool readMaterialTexture(CMaterial& material, IOReadBase* pRead, const std::string& strFilename) { std::string strCommand; std::vector<std::string> setWords; strCommand = getLineCommand(pRead,setWords); if ("{"!=strCommand) { return false; } std::string strTexture; bool bAdd = false; while (!pRead->IsEof()) { strCommand = getLineCommand(pRead,setWords); if ("texture"==strCommand) { if (setWords.size()>0) { strTexture=GetParentPath(strFilename)+setWords[0]; strTexture = ChangeExtension(strTexture,".dds"); } } else if ("colour_op"==strCommand) { if (setWords.size()>0) { if ("add"==setWords[0]) { bAdd = true; } } } else if ("scroll_anim"==strCommand) { if (setWords.size()==2) { material.vTexAnim.x=atof(setWords[0].c_str()); material.vTexAnim.y=atof(setWords[1].c_str()); } } else if ("}"==strCommand) { break; } else { MessageBoxA(NULL,strCommand.c_str(),"Unknon in texture_unit!",0); } } if (strTexture.length()>0) { if (bAdd) { //material.setEmissive(strTexture); material.setTexture(0,strTexture.c_str()); } else { material.setTexture(0,strTexture.c_str()); } } return true; }
// TMP TMP void tempDumpColPolys() { CPackedWorld *pw = R2::getEditor().getIslandCollision().getPackedIsland(); if (pw) { static CMaterial material; static CMaterial wiredMaterial; static CMaterial texturedMaterial; static CVertexBuffer vb; static bool initDone = false; if (!initDone) { vb.setVertexFormat(CVertexBuffer::PositionFlag); vb.setPreferredMemory(CVertexBuffer::AGPVolatile, false); material.initUnlit(); material.setDoubleSided(true); material.setZFunc(CMaterial::lessequal); wiredMaterial.initUnlit(); wiredMaterial.setDoubleSided(true); wiredMaterial.setZFunc(CMaterial::lessequal); wiredMaterial.setColor(CRGBA(255, 255, 255, 250)); wiredMaterial.texEnvOpAlpha(0, CMaterial::Replace); wiredMaterial.texEnvArg0Alpha(0, CMaterial::Diffuse, CMaterial::SrcAlpha); wiredMaterial.setBlend(true); wiredMaterial.setBlendFunc(CMaterial::srcalpha, CMaterial::invsrcalpha); texturedMaterial.initUnlit(); texturedMaterial.setDoubleSided(true); texturedMaterial.setZFunc(CMaterial::lessequal); initDone = true; } // just add a projected texture R2::getEditor().getIslandCollision().loadEntryPoints(); R2::CScenarioEntryPoints &sep = R2::CScenarioEntryPoints::getInstance(); CVectorD playerPos = UserEntity->pos(); R2::CScenarioEntryPoints::CCompleteIsland *island = sep.getCompleteIslandFromCoords(CVector2f((float) playerPos.x, (float) playerPos.y)); static CSString currIsland; if (island && island->Island != currIsland) { currIsland = island->Island; CTextureFile *newTex = new CTextureFile(currIsland + "_sp.tga"); newTex->setWrapS(ITexture::Clamp); newTex->setWrapT(ITexture::Clamp); texturedMaterial.setTexture(0, newTex); texturedMaterial.texEnvOpRGB(0, CMaterial::Replace); texturedMaterial.texEnvArg0RGB(0, CMaterial::Texture, CMaterial::SrcColor); texturedMaterial.setTexCoordGen(0, true); texturedMaterial.setTexCoordGenMode(0, CMaterial::TexCoordGenObjectSpace); CMatrix mat; CVector scale((float) (island->XMax - island->XMin), (float) (island->YMax - island->YMin), 0.f); scale.x = 1.f / favoid0(scale.x); scale.y = 1.f / favoid0(scale.y); scale.z = 0.f; mat.setScale(scale); mat.setPos(CVector(- island->XMin * scale.x, - island->YMin * scale.y, 0.f)); // CMatrix uvScaleMat; // uint texWidth = (uint) (island->XMax - island->XMin); uint texHeight = (uint) (island->YMax - island->YMin); float UScale = (float) texWidth / raiseToNextPowerOf2(texWidth); float VScale = (float) texHeight / raiseToNextPowerOf2(texHeight); // uvScaleMat.setScale(CVector(UScale, - VScale, 0.f)); uvScaleMat.setPos(CVector(0.f, VScale, 0.f)); // texturedMaterial.enableUserTexMat(0, true); texturedMaterial.setUserTexMat(0, uvScaleMat * mat); } const CFrustum &frust = MainCam.getFrustum(); // IDriver *driver = ((CDriverUser *) Driver)->getDriver(); driver->enableFog(true); const CRGBA clearColor = CRGBA(0, 0, 127, 0); driver->setupFog(frust.Far * 0.8f, frust.Far, clearColor); CViewport vp; vp.init(0.f, 0.f, 1.f, 1.f); driver->setupViewport(vp); CScissor scissor; viewportToScissor(vp, scissor); driver->setupScissor(scissor); // driver->setFrustum(frust.Left, frust.Right, frust.Bottom, frust.Top, frust.Near, frust.Far, frust.Perspective); driver->setupViewMatrix(MainCam.getMatrix().inverted()); driver->setupModelMatrix(CMatrix::Identity); // // const CVector localFrustCorners[8] = { CVector(frust.Left, frust.Near, frust.Top), CVector(frust.Right, frust.Near, frust.Top), CVector(frust.Right, frust.Near, frust.Bottom), CVector(frust.Left, frust.Near, frust.Bottom), CVector(frust.Left * frust.Far / frust.Near, frust.Far, frust.Top * frust.Far / frust.Near), CVector(frust.Right * frust.Far / frust.Near, frust.Far, frust.Top * frust.Far / frust.Near), CVector(frust.Right * frust.Far / frust.Near, frust.Far, frust.Bottom * frust.Far / frust.Near), CVector(frust.Left * frust.Far / frust.Near, frust.Far, frust.Bottom * frust.Far / frust.Near) }; // roughly compute covered zones // /* sint frustZoneMinX = INT_MAX; sint frustZoneMaxX = INT_MIN; sint frustZoneMinY = INT_MAX; sint frustZoneMaxY = INT_MIN; for(uint k = 0; k < sizeofarray(localFrustCorners); ++k) { CVector corner = camMat * localFrustCorners[k]; sint zoneX = (sint) (corner.x / 160.f) - zoneMinX; sint zoneY = (sint) floorf(corner.y / 160.f) - zoneMinY; frustZoneMinX = std::min(frustZoneMinX, zoneX); frustZoneMinY = std::min(frustZoneMinY, zoneY); frustZoneMaxX = std::max(frustZoneMaxX, zoneX); frustZoneMaxY = std::max(frustZoneMaxY, zoneY); } */ const uint TRI_BATCH_SIZE = 10000; // batch size for rendering static std::vector<TPackedZoneBaseSPtr> zones; zones.clear(); pw->getZones(zones); for(uint k = 0; k < zones.size(); ++k) { zones[k]->render(vb, *driver, texturedMaterial, wiredMaterial, MainCam.getMatrix(), TRI_BATCH_SIZE, localFrustCorners); } } }