Plane::Plane(float quadWidth, float quadHeight, unsigned int width, unsigned int height){ //There's one more row of vertices than quads, same for columns unsigned int quadCount = width*height; unsigned int vertexCount = (width+1)*(height+1); // This is explained further down, but the formula for the amount of indices in the plane is // (quads per row * 2 + 1) * rows + 1 // The last +1 is for the stitch leading into the plane altogether, // while the +1 for each row is for the stitch finalizing each strip (as well as starting the next one.) unsigned int indexCount = (2 * width + 1) * height + 1; Vertex* vertices = new Vertex[vertexCount]; GLuint* indices = new GLuint[indexCount]; GenerateVertices(vertices, quadWidth, quadHeight, width + 1, height + 1); GenerateUvCoordinates(vertices, 1.0f / quadWidth, 1.0f / quadHeight, width + 1, height + 1); GenerateIndices(indices, width, height); GenerateNormals(vertices, width + 1, height + 1); GenerateVao(vertices, indices, vertexCount, indexCount); delete[] vertices; delete[] indices; }
void GeoPatchContext::Init() { frac = 1.0 / double(edgeLen-3); numTris = 2*(edgeLen-1)*(edgeLen-1); GenerateIndices(); }
void Terrain::RestoreDeviceObjects(void) { InvalidateDeviceObjects(); LoadTexture(); LoadTerrainFromFile(m_sTerrainFile.c_str()); /*if (FAILED(m_pd3dDevice->CreateVertexBuffer(m_uNumVertices * sizeof(TerrainVertex), D3DUSAGE_WRITEONLY, TerrainVertex::FVF_Flags, D3DPOOL_MANAGED, &m_pVertexBuffer, 0))) { return; } TerrainVertex *pVertices = NULL; if (SUCCEEDED(m_pVertexBuffer->Lock(0, 0, (void **)&pVertices, 0))) { float fStartX = -m_fTerrainWidth / 2.0f, fEndX = m_fTerrainWidth / 2.0f; float fStartZ = m_fTerrainDepth / 2.0f, fEndZ = -m_fTerrainDepth / 2.0f; float fTextureU = 10.0f / (float)m_uCellsPerRow; float fTextureV = 10.0f / (float)m_uCellsPerCol; int nIndex = 0, i = 0; for (float z = fStartZ; z >= fEndZ; z -= m_fCellsSpace, ++i) { int j = 0; for (float x = fStartX; x <= fEndX; x += m_fCellsSpace, ++j) { nIndex = i * m_uCellsPerRow + j; pVertices[nIndex] = TerrainVertex(x, m_vHeightData[nIndex], z, j * fTextureU, i * fTextureV); ++nIndex; } } m_pVertexBuffer->Unlock(); }*/ UINT uWidth = (int)sqrt((float)m_uNumVertices); if (FAILED(m_pd3dDevice->CreateVertexBuffer(m_uNumVertices * sizeof(Vertex), D3DUSAGE_WRITEONLY, Vertex::FVF_Flags, D3DPOOL_MANAGED, &m_pVertexBuffer, 0))) { return; } Vertex *pVertices = NULL; if (SUCCEEDED(m_pVertexBuffer->Lock(0, 0, (void **)&pVertices, 0))) { GenerateTerrainVertex(pVertices, &m_vHeightData[0], uWidth, uWidth); m_pVertexBuffer->Unlock(); } m_uNumIndices = GetIndicesNum(uWidth, uWidth); if (FAILED(m_pd3dDevice->CreateIndexBuffer(m_uNumIndices * sizeof(int), D3DUSAGE_WRITEONLY, D3DFMT_INDEX32, D3DPOOL_MANAGED, &m_pIndexBuffer, 0))) { return; } int *pIndices = NULL; if (SUCCEEDED(m_pIndexBuffer->Lock(0, 0, (void **)&pIndices, 0))) { GenerateIndices(pIndices, uWidth, uWidth); m_pIndexBuffer->Unlock(); } ZeroMemory(&m_d3dMaterial, sizeof(D3DMATERIAL9)); m_d3dMaterial.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); m_d3dMaterial.Diffuse = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f); m_d3dMaterial.Specular = D3DXCOLOR(0.3f, 0.3f, 0.3f, 1.0f); m_d3dMaterial.Emissive = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f); m_d3dMaterial.Power = 0.0f; }
HeightMappedPlane::HeightMappedPlane(float quadWidth, float quadHeight, float maxHeight, unsigned int width, unsigned int height, Texture* heightMap){ unsigned int quadCount = width * height; unsigned int vertexCount = (width + 1) * (height + 1); // We're not doing trianglestrips this time, so six indicies per quad (2 triangles * 3 points). unsigned int indexCount = quadCount * 6; Vertex* vertices = new Vertex[vertexCount]; GLuint* indices = new GLuint[indexCount]; //heightMap->PrintData(); GenerateVertices(vertices, quadWidth, quadHeight, maxHeight, width + 1, height + 1, heightMap); GenerateIndices(indices, width, height); GenerateUvCoordinates(vertices, 1.0f / quadWidth, 1.0f / quadHeight, width + 1, height + 1); Model::GenerateNormals(vertices, indices, vertexCount, indexCount); Model::GenerateTangents(vertices, indices, vertexCount, indexCount); Model::GenerateBitangents(vertices, vertexCount); Model::GenerateVao(vertices, indices, vertexCount, indexCount); }
Terrain::Terrain(const char* filename) { // Load height map from file int components; unsigned char* data; data = stbi_load(filename, &width, &height, &components, 0); if (data == NULL) Log() << "Couldn't load image: " << filename << "\n"; // Convert height map to float. heightMap = new float*[width]; normals = new glm::vec3*[width]; tangents = new glm::vec3*[width]; for (int i = 0; i < width; i++) { heightMap[i] = new float[height]; normals[i] = new glm::vec3[height]; tangents[i] = new glm::vec3[height]; } for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { heightMap[x][y] = data[(x + y*width)*components] / 256.f; } } stbi_image_free(data); Filter3x3(); CalculateNormals(); GenerateVertices(); GenerateIndices(); for (int i = 0; i < width; i++) { delete[] normals[i]; delete[] tangents[i]; } delete[] normals; delete[] tangents; GenerateBuffers(); GenerateVertexArray(); }
bool Terrain::LoadFromFile(const string& filename) { //Unload previous terrain, if exists Unload(); WriteToLog("Loading heightmap from TGA file...\n"); Image img; if (!img.Load(filename)) { WriteToLog("ERROR: Failed to load heightmap.\n"); return false; } //Load neccessary data to GPU WriteToLog("Generating indices...\n"); GenerateIndices(); WriteToLog("Loading all vertex data to VAO...\n"); LoadVertices(heightmap.Heap(), img); WriteToLog("OK: Terrain was loaded\n"); return true; }
void SetupAxis(int nm, GLuint &vao, GLuint &vbo, GLuint &ibo) { std::vector<gmtl::Point3f>start; std::vector<gmtl::Point3f> verts; std::vector<unsigned int> indices; std::vector<gmtl::Point3f> color; std::vector<gmtl::Point2f> uvs; std::vector<gmtl::Point3f> normals; int np = 5; gmtl::Point3f p0(.0f, .0f, .0f); gmtl::Point3f p1(.025f, .0f, .0f); gmtl::Point3f p2(.025f, .85f, .0f); gmtl::Point3f p3(.055f, .85f, .0f); gmtl::Point3f p4(.0f, 1.0f, .0f); start.push_back(p0); start.push_back(p1); start.push_back(p2); start.push_back(p3); start.push_back(p4); verts = rPoints(start, nm, np, 'y'); color = cPoints(verts, 'o'); normals = nPoints(verts, 'a'); uvs = uvPoints(nm, np); GenerateIndices(nm, np, indices); axisIndexSize = indices.size(); int vertOffset = verts.size() * sizeof(gmtl::Point3f); int uvOffset = uvs.size() * sizeof(gmtl::Point2f); int colorOffset = color.size() * sizeof(gmtl::Point3f); int indexOffset = indices.size() * sizeof(GLuint); int normalOffset = normals.size() * sizeof(gmtl::Point3f); glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &ibo); //Setup 1 buffer name and store the generated buffer object name their glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); //bind the buffer name to the target glBufferData(GL_ELEMENT_ARRAY_BUFFER, //target buffer object indexOffset, //size of buffer object &indices[0], //pointer to the data GL_STATIC_DRAW); glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); //Set the size and data of the Vertex Buffer Object and set it to STATIC_DRAW glBufferData(GL_ARRAY_BUFFER, //this is the target we are buffering to vertOffset + colorOffset + normalOffset + uvOffset, //this is the total size of the buffer NULL, //address of the content to be updated nothing because we are setting it in the subData buffers GL_STATIC_DRAW);//+ uvOffset + normalOffset glBufferSubData(GL_ARRAY_BUFFER, 0, //offset where data replacement will begin vertOffset, //size &verts[0]);//address of the content to be updated glBufferSubData(GL_ARRAY_BUFFER, vertOffset, //offset where data replacement will begin colorOffset, //size &color[0]);//data glBufferSubData(GL_ARRAY_BUFFER, vertOffset + colorOffset, normalOffset, &normals[0]); glBufferSubData(GL_ARRAY_BUFFER, vertOffset + colorOffset + normalOffset, uvOffset, &uvs[0]); //verts|uv|color|normals //layout(location = 0) in vec4 VertexPosition; //layout(location = 1) in vec4 VertexColor; //layout(location = 2) in vec3 VertexNormal; //layout(location = 3) in vec2 VertexUV; //This is the layout in the shader for the attribute variables //that will be binded to the different geometry buffers glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)(0)); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)(vertOffset)); // vertex buffer object glEnableVertexAttribArray(2); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*)(vertOffset + colorOffset)); // vertex buffer object glEnableVertexAttribArray(3); glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 0, (void*)(vertOffset + colorOffset + normalOffset)); glBindVertexArray(0); //Bind the index buffer for the object glBindBuffer(GL_ARRAY_BUFFER, 0); // Bind the index buffer for the object glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); }
void VegetationFixedGeometry::Build(Vector<VegetationRenderData*>& renderDataArray, const FastNameSet& materialFlags) { ReleaseRenderData(renderDataArray); renderDataArray.push_back(new VegetationRenderData()); VegetationRenderData& renderData = *renderDataArray[0]; NMaterial* vegetationMaterial = NMaterial::CreateMaterial(FastName("Vegetation_Material"), NMaterialName::GRASS, NMaterial::DEFAULT_QUALITY_NAME); vegetationMaterial->AddNodeFlags(DataNode::NodeRuntimeFlag); FastNameSet::iterator end = materialFlags.end(); for(FastNameSet::iterator it = materialFlags.begin(); it != end; ++it) { vegetationMaterial->SetFlag(it->first, NMaterial::FlagOn); } if(RenderManager::Instance()->GetCaps().isFramebufferFetchSupported) { vegetationMaterial->SetFlag(VegetationPropertyNames::FLAG_FRAMEBUFFER_FETCH, NMaterial::FlagOn); } vegetationMaterial->SetPropertyValue(VegetationPropertyNames::UNIFORM_WORLD_SIZE, Shader::UT_FLOAT_VEC3, 1, &worldSize); renderData.SetMaterial(vegetationMaterial); SafeRelease(vegetationMaterial); size_t resolutionCount = resolutionScale.size(); uint32 sortDirectionCount = GetSortDirectionCount(); Vector<VegetationIndex>& indexData = renderData.GetIndices(); Vector<VegetationVertex>& vertexData = renderData.GetVertices(); uint32 tilesPerRow = (uint32)resolutionScale[resolutionCount - 1]; uint32 maxClusterRowSize = (tilesPerRow * maxClusters); size_t maxTotalClusters = maxClusterRowSize * maxClusterRowSize; uint32 layerDataCount = 0; uint32 indexDataCount = 0; for(uint32 layerIndex = 0; layerIndex < maxLayerTypes; ++layerIndex) { TextureSheetCell& cellData = textureSheet.cells[layerIndex]; layerDataCount += VEGETATION_CLUSTER_SIZE[cellData.geometryId]; indexDataCount += VEGETATION_CLUSTER_INDEX_SIZE[cellData.geometryId]; } uint32 totalIndexCount = 0; for(uint32 i = 0; i < resolutionCount; ++i) { totalIndexCount += indexDataCount * (maxTotalClusters / (uint32)resolutionScale[i]); } totalIndexCount *= sortDirectionCount; indexData.resize(totalIndexCount); vertexData.resize(maxTotalClusters * layerDataCount); Vector<uint32> layerOffsets(maxLayerTypes); GenerateVertices(maxClusters, maxTotalClusters, maxClusterRowSize, tilesPerRow, unitSize, layerOffsets, renderData); GenerateIndices(maxClusters, maxClusterRowSize, layerOffsets, renderData); //VI: need to build vertex & index objects AFTER initialization GenerateRenderDataObjects(renderData); }