void UpdateVBOs() { PROFILE_SCOPED() //create buffer and upload data Graphics::VertexBufferDesc vbd; vbd.attrib[0].semantic = Graphics::ATTRIB_POSITION; vbd.attrib[0].format = Graphics::ATTRIB_FORMAT_FLOAT3; vbd.attrib[1].semantic = Graphics::ATTRIB_NORMAL; vbd.attrib[1].format = Graphics::ATTRIB_FORMAT_FLOAT3; vbd.numVertices = ctx->NUMVERTICES(); vbd.usage = Graphics::BUFFER_USAGE_STATIC; m_vertexBuffer.reset(Pi::renderer->CreateVertexBuffer(vbd)); GasPatchContext::VBOVertex* vtxPtr = m_vertexBuffer->Map<GasPatchContext::VBOVertex>(Graphics::BUFFER_MAP_WRITE); assert(m_vertexBuffer->GetDesc().stride == sizeof(GasPatchContext::VBOVertex)); const Sint32 edgeLen = ctx->edgeLen; const double frac = ctx->frac; for (Sint32 y=0; y<edgeLen; y++) { for (Sint32 x=0; x<edgeLen; x++) { const vector3d p = GetSpherePoint(x*frac, y*frac); const vector3d pSubCentroid = p - clipCentroid; clipRadius = std::max(clipRadius, p.Length()); vtxPtr->pos = vector3f(pSubCentroid); vtxPtr->norm = vector3f(p); ++vtxPtr; // next vertex } } m_vertexBuffer->Unmap(); }
// Generates full-detail vertices, and also non-edge normals and colors void QuadPatchJob::GenerateBorderedData(const SQuadSplitRequest *data) const { const vector3d &v0 = data->v0; const vector3d &v1 = data->v1; const vector3d &v2 = data->v2; const vector3d &v3 = data->v3; const int edgeLen = data->edgeLen; const double fracStep = data->fracStep; const Terrain *pTerrain = data->pTerrain.Get(); const int borderedEdgeLen = (edgeLen * 2) + (BORDER_SIZE * 2) - 1; const int numBorderedVerts = borderedEdgeLen*borderedEdgeLen; // generate heights plus a N=BORDER_SIZE unit border double *bhts = data->borderHeights.get(); vector3d *vrts = data->borderVertexs.get(); for ( int y = -BORDER_SIZE; y < (borderedEdgeLen - BORDER_SIZE); y++ ) { const double yfrac = double(y) * (fracStep*0.5); for ( int x = -BORDER_SIZE; x < (borderedEdgeLen - BORDER_SIZE); x++ ) { const double xfrac = double(x) * (fracStep*0.5); const vector3d p = GetSpherePoint(v0, v1, v2, v3, xfrac, yfrac); const double height = pTerrain->GetHeight(p); assert(height >= 0.0f && height <= 1.0f); *(bhts++) = height; *(vrts++) = p * (height + 1.0); } } assert(bhts == &data->borderHeights[numBorderedVerts]); }
void QuadPatchJob::GenerateSubPatchData( double *heights, vector3f *normals, Color3ub *colors, double *borderHeights, vector3d *borderVertexs, const vector3d &v0, const vector3d &v1, const vector3d &v2, const vector3d &v3, const int edgeLen, const int xoff, const int yoff, const int borderedEdgeLen, const double fracStep, const Terrain *pTerrain) const { // Generate normals & colors for vertices vector3d *vrts = borderVertexs; Color3ub *col = colors; vector3f *nrm = normals; double *hts = heights; // step over the small square for ( int y = 0; y < edgeLen; y++ ) { const int by = (y + BORDER_SIZE) + yoff; for ( int x = 0; x < edgeLen; x++ ) { const int bx = (x + BORDER_SIZE) + xoff; // height const double height = borderHeights[bx + (by * borderedEdgeLen)]; assert(hts != &heights[edgeLen * edgeLen]); *(hts++) = height; // normal const vector3d &x1 = vrts[(bx - 1) + (by * borderedEdgeLen)]; const vector3d &x2 = vrts[(bx + 1) + (by * borderedEdgeLen)]; const vector3d &y1 = vrts[bx + ((by - 1) * borderedEdgeLen)]; const vector3d &y2 = vrts[bx + ((by + 1) * borderedEdgeLen)]; const vector3d n = ((x2 - x1).Cross(y2 - y1)).Normalized(); assert(nrm != &normals[edgeLen * edgeLen]); *(nrm++) = vector3f(n); // color const vector3d p = GetSpherePoint(v0, v1, v2, v3, x * fracStep, y * fracStep); setColour(*col, pTerrain->GetColor(p, height, n)); assert(col != &colors[edgeLen * edgeLen]); ++col; } } assert(hts == &heights[edgeLen*edgeLen]); assert(nrm == &normals[edgeLen*edgeLen]); assert(col == &colors[edgeLen*edgeLen]); }
void GeoPatch::_UpdateVBOs() { if (m_needUpdateVBOs) { m_needUpdateVBOs = false; if (!m_vbo) glGenBuffersARB(1, &m_vbo); glBindBufferARB(GL_ARRAY_BUFFER, m_vbo); glBufferDataARB(GL_ARRAY_BUFFER, sizeof(GeoPatchContext::VBOVertex)*ctx->NUMVERTICES(), 0, GL_DYNAMIC_DRAW); double xfrac=0.0, yfrac=0.0; double *pHts = heights.Get(); const vector3f *pNorm = &normals[0]; const Color3ub *pColr = &colors[0]; GeoPatchContext::VBOVertex *pData = ctx->vbotemp; for (int y=0; y<ctx->edgeLen; y++) { xfrac = 0.0; for (int x=0; x<ctx->edgeLen; x++) { const double height = *pHts; const vector3d p = (GetSpherePoint(xfrac, yfrac) * (height + 1.0)) - clipCentroid; clipRadius = std::max(clipRadius, p.Length()); pData->x = float(p.x); pData->y = float(p.y); pData->z = float(p.z); ++pHts; // next height pData->nx = pNorm->x; pData->ny = pNorm->y; pData->nz = pNorm->z; ++pNorm; // next normal pData->col[0] = pColr->r; pData->col[1] = pColr->g; pData->col[2] = pColr->b; pData->col[3] = 255; ++pColr; // next colour ++pData; // next vertex xfrac += ctx->frac; } yfrac += ctx->frac; } glBufferDataARB(GL_ARRAY_BUFFER, sizeof(GeoPatchContext::VBOVertex)*ctx->NUMVERTICES(), ctx->vbotemp, GL_DYNAMIC_DRAW); glBindBufferARB(GL_ARRAY_BUFFER, 0); } }
// Generates full-detail vertices, and also non-edge normals and colors void SinglePatchJob::GenerateMesh(const SSingleSplitRequest *data) const { double *heights = data->heights; vector3f *normals = data->normals; Color3ub *colors = data->colors; double *borderHeights = data->borderHeights.get(); vector3d *borderVertexs = data->borderVertexs.get(); const vector3d &v0 = data->v0; const vector3d &v1 = data->v1; const vector3d &v2 = data->v2; const vector3d &v3 = data->v3; const int edgeLen = data->edgeLen; const double fracStep = data->fracStep; const Terrain *pTerrain = data->pTerrain.Get(); const int borderedEdgeLen = edgeLen+(BORDER_SIZE*2); const int numBorderedVerts = borderedEdgeLen*borderedEdgeLen; // generate heights plus a 1 unit border double *bhts = data->borderHeights.get(); vector3d *vrts = borderVertexs; for (int y=-BORDER_SIZE; y<borderedEdgeLen-BORDER_SIZE; y++) { const double yfrac = double(y) * fracStep; for (int x=-BORDER_SIZE; x<borderedEdgeLen-BORDER_SIZE; x++) { const double xfrac = double(x) * fracStep; const vector3d p = GetSpherePoint(v0, v1, v2, v3, xfrac, yfrac); const double height = pTerrain->GetHeight(p); assert(height >= 0.0f && height <= 1.0f); *(bhts++) = height; *(vrts++) = p * (height + 1.0); } } assert(bhts == &data->borderHeights.get()[numBorderedVerts]); // Generate normals & colors for non-edge vertices since they never change Color3ub *col = colors; vector3f *nrm = normals; double *hts = heights; vrts = borderVertexs; for (int y=BORDER_SIZE; y<borderedEdgeLen-BORDER_SIZE; y++) { for (int x=BORDER_SIZE; x<borderedEdgeLen-BORDER_SIZE; x++) { // height const double height = borderHeights[x + y*borderedEdgeLen]; assert(hts!=&heights[edgeLen*edgeLen]); *(hts++) = height; // normal const vector3d &x1 = vrts[(x-1) + y*borderedEdgeLen]; const vector3d &x2 = vrts[(x+1) + y*borderedEdgeLen]; const vector3d &y1 = vrts[x + (y-1)*borderedEdgeLen]; const vector3d &y2 = vrts[x + (y+1)*borderedEdgeLen]; const vector3d n = ((x2-x1).Cross(y2-y1)).Normalized(); assert(nrm!=&normals[edgeLen*edgeLen]); *(nrm++) = vector3f(n); // color const vector3d p = GetSpherePoint(v0, v1, v2, v3, (x-BORDER_SIZE)*fracStep, (y-BORDER_SIZE)*fracStep); setColour(*col, pTerrain->GetColor(p, height, n)); assert(col!=&colors[edgeLen*edgeLen]); ++col; } } assert(hts == &heights[edgeLen*edgeLen]); assert(nrm == &normals[edgeLen*edgeLen]); assert(col == &colors[edgeLen*edgeLen]); }
// Generates full-detail vertices, and also non-edge normals and colors void BasePatchJob::GenerateMesh(double *heights, vector3f *normals, Color3ub *colors, double *borderHeights, vector3d *borderVertexs, const vector3d &v0, const vector3d &v1, const vector3d &v2, const vector3d &v3, const int edgeLen, const double fracStep, const Terrain *pTerrain) const { const int borderedEdgeLen = edgeLen+2; const int numBorderedVerts = borderedEdgeLen*borderedEdgeLen; // generate heights plus a 1 unit border double *bhts = borderHeights; vector3d *vrts = borderVertexs; for (int y=-1; y<borderedEdgeLen-1; y++) { const double yfrac = double(y) * fracStep; for (int x=-1; x<borderedEdgeLen-1; x++) { // quit out if( s_abort) return; const double xfrac = double(x) * fracStep; const vector3d p = GetSpherePoint(v0, v1, v2, v3, xfrac, yfrac); const double height = pTerrain->GetHeight(p); assert(height >= 0.0f && height <= 1.0f); *(bhts++) = height; *(vrts++) = p * (height + 1.0); } } assert(bhts==&borderHeights[numBorderedVerts]); // Generate normals & colors for non-edge vertices since they never change Color3ub *col = colors; vector3f *nrm = normals; double *hts = heights; vrts = borderVertexs; for (int y=1; y<borderedEdgeLen-1; y++) { for (int x=1; x<borderedEdgeLen-1; x++) { // quit out if( s_abort) return; // height const double height = borderHeights[x + y*borderedEdgeLen]; assert(hts!=&heights[edgeLen*edgeLen]); *(hts++) = height; // normal const vector3d &x1 = vrts[x-1 + y*borderedEdgeLen]; const vector3d &x2 = vrts[x+1 + y*borderedEdgeLen]; const vector3d &y1 = vrts[x + (y-1)*borderedEdgeLen]; const vector3d &y2 = vrts[x + (y+1)*borderedEdgeLen]; const vector3d n = ((x2-x1).Cross(y2-y1)).Normalized(); assert(nrm!=&normals[edgeLen*edgeLen]); *(nrm++) = vector3f(n); // color const vector3d p = GetSpherePoint(v0, v1, v2, v3, (x-1)*fracStep, (y-1)*fracStep); setColour(*col, pTerrain->GetColor(p, height, n)); assert(col!=&colors[edgeLen*edgeLen]); ++col; } } assert(hts==&heights[edgeLen*edgeLen]); assert(nrm==&normals[edgeLen*edgeLen]); assert(col==&colors[edgeLen*edgeLen]); }