//! deletes all textures void CNullDriver::deleteAllTextures() { // we need to remove previously set textures which might otherwise be kept in the // last set material member. Could be optimized to reduce state changes. setMaterial(SMaterial()); for (u32 i=0; i<Textures.size(); ++i) Textures[i].Surface->releaseRef(); Textures.clear(); }
ResourceId CResourceManager::createMaterial(ResourceId base, ResourceId normal, ResourceId specular, ResourceId glow, ResourceId alpha) { // Create material ResourceId id = m_nextMaterialId; ++m_nextMaterialId; // Add material m_materials[id] = SMaterial(base, normal, specular, glow, alpha); // Notify listener with create event notifyResourceListeners(EResourceType::Material, id, EListenerEvent::Create); return id; }
//------------------------------------------------------------------------------ void CSky::updateVirtual() { model.materials.clear(); model.materials.push_back(SMaterial(context->getShaders()->getShaderProgram(NShader::PROGRAM_BASIC), sky.diffuseTexture, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, QVector<int32>(), false)); model.meshes.clear(); model.meshes.push_back(SMesh()); SMesh *mesh = &model.meshes.back(); mesh->transformation = SMatrix::composeTransformation(mesh->position, mesh->rotation, mesh->scale); mesh->vertices.resize(NSky::VERTICES_SPHERE2 * NSky::VERTICES_ROUND2); mesh->faces.push_back(SFaces(&model.materials.back())); SFaces *face = &mesh->faces.back(); face->faces.resize(NSky::VERTICES_SPHERE * NSky::VERTICES_ROUND2 * NSky::FACE_BLOCK_SIZE); for(uint32 h = 0; h < NSky::VERTICES_SPHERE2; h++) { //qDebug("___"); const float y = static_cast<float>(h) / static_cast<float>(NSky::VERTICES_SPHERE); const float yRad = y * NMath::PI; //qDebug(QString("%1 %2 %3").arg(y).arg(yRad).arg(cosf(yRad)).toStdString().c_str()); for(uint32 r = 0; r < NSky::VERTICES_ROUND2; r++) { const uint32 v = h * NSky::VERTICES_ROUND2 + r; const float x = static_cast<float>(r) / static_cast<float>(NSky::VERTICES_ROUND); const float xRad = x * NMath::PI_2; //qDebug(QString("%1").arg(v).toStdString().c_str()); mesh->vertices[v].position = QVector3D(sinf(xRad) * sinf(yRad), cosf(yRad), cosf(xRad) * sinf(yRad)); mesh->vertices[v].texCoord = QVector2D(x, (y - 0.5f) * ((y < 0.5f) ? 1.0f : -1.0f) * 2.0f); if((h) && (r)) { const uint32 vv = (v - NSky::VERTICES_ROUND2 - 1) * NSky::FACE_BLOCK_SIZE; //qDebug(QString("%1 %2 %3").arg(vv).arg(v).arg(v - NSky::VERTICES_ROUND).toStdString().c_str()); face->faces[vv + 0].vertex0 = v - 1; face->faces[vv + 0].vertex1 = v - NSky::VERTICES_ROUND2 - 1; face->faces[vv + 0].vertex2 = v; face->faces[vv + 1].vertex0 = v; face->faces[vv + 1].vertex1 = v - NSky::VERTICES_ROUND2 - 1; face->faces[vv + 1].vertex2 = v - NSky::VERTICES_ROUND2; } /*else qDebug("ne");*/ } } }
//------------------------------------------------------------------------------ void CWater::updateVirtual() { model.materials.clear(); model.meshes.clear(); // ground model.materials.push_back(SMaterial(context->getShaders()->getShaderProgram(NShader::PROGRAM_TERRAIN), NULL, NULL, NULL, water.detailGroundTexture, NULL, NULL, NULL, NULL, NULL, NULL, NULL)); model.meshes.push_back(SMesh()); SMesh *mesh = &model.meshes.back(); mesh->transformation = SMatrix::composeTransformation(mesh->position, mesh->rotation, mesh->scale); mesh->faces.push_back(SFaces(&model.materials.back())); SFaces *faces = &mesh->faces.back(); faces->material = &model.materials.back(); mesh->vertices.resize(NWater::VERTICES_COUNT); mesh->vertices[0].position = QVector3D(-0.5, water.depth, 0.5); mesh->vertices[1].position = QVector3D( 0.5, water.depth, 0.5); mesh->vertices[2].position = QVector3D(-0.5, water.depth, -0.5); mesh->vertices[3].position = QVector3D( 0.5, water.depth, -0.5); mesh->vertices[0].texCoord = QVector2D(-0.0, 100.0); mesh->vertices[1].texCoord = QVector2D(-100.0, 100.0); mesh->vertices[2].texCoord = QVector2D(-0.0, 0.0); mesh->vertices[3].texCoord = QVector2D(-100.0, 0.0); for(uint32 i = 0; i < NWater::VERTICES_COUNT; i++) { mesh->vertices[i].color = water.color.toVector3D() * water.color.w(); mesh->vertices[i].color2 = QVector3D(1.0, 0.0, 0.0); } faces->faces.resize(NWater::FACE_BLOCK_SIZE); faces->faces[0] = SFace(0, 1, 2); faces->faces[1] = SFace(2, 1, 3); // level model.materials.push_back(SMaterial(context->getShaders()->getShaderProgram(NShader::PROGRAM_WATER), NULL, water.windTexture, NULL, water.detailTexture, water.environmentTexture, NULL, NULL, NULL, NULL, NULL, NULL, QVector<int32>(), true, true)); model.meshes.push_back(SMesh()); mesh = &model.meshes.back(); mesh->transformation = SMatrix::composeTransformation(mesh->position, mesh->rotation, mesh->scale); mesh->faces.push_back(SFaces(&model.materials.back())); faces = &mesh->faces.back(); faces->material = &model.materials.back(); mesh->vertices.resize(NWater::VERTICES_COUNT); mesh->vertices[0].position = QVector3D(-0.5, 0.0, 0.5); mesh->vertices[1].position = QVector3D( 0.5, 0.0, 0.5); mesh->vertices[2].position = QVector3D(-0.5, 0.0, -0.5); mesh->vertices[3].position = QVector3D( 0.5, 0.0, -0.5); mesh->vertices[0].texCoord = QVector2D(-0.0, 100.0); mesh->vertices[1].texCoord = QVector2D(-100.0, 100.0); mesh->vertices[2].texCoord = QVector2D(-0.0, 0.0); mesh->vertices[3].texCoord = QVector2D(-100.0, 0.0); faces->faces.resize(NWater::FACE_BLOCK_SIZE * 2); faces->faces[0] = SFace(0, 1, 2); faces->faces[1] = SFace(2, 1, 3); // under level model.materials.push_back(SMaterial(context->getShaders()->getShaderProgram(NShader::PROGRAM_UNDER_WATER), NULL, water.windTexture, NULL, water.detailTexture, water.environmentTexture, NULL, NULL, NULL, NULL, NULL, NULL, QVector<int32>(), true, true)); model.meshes.push_back(model.meshes.back()); mesh = &model.meshes.back(); faces = &mesh->faces.back(); faces->material = &model.materials.back(); faces->faces[0] = SFace(1, 0, 2); faces->faces[1] = SFace(1, 2, 3); }
//------------------------------------------------------------------------------ void CTerrain::updateVirtual() { const uint32 stepX = 1 << terrain.stepX; // edges count (vertices: step + 1) const uint32 stepZ = 1 << terrain.stepZ; const uint32 divStepX = 1 << terrain.divStepX; // count of chunks const uint32 divStepZ = 1 << terrain.divStepZ; const uint32 stepMeshX = stepX / divStepX; // number of edges in chunk const uint32 stepMeshZ = stepZ / divStepZ; QVector<SVertex> vx((stepX + 1) * (stepZ + 1)); QVector<float> heightMap((stepX + 1) * (stepZ + 1), 0.0f); QVector<bool> usedHeightMap((stepX + 1) * (stepZ + 1), false); QVector<int32> heightMapLayer((stepX + 1) * (stepZ + 1), -1); float depth = 1.0f; srand(terrain.seed); // compute heightmap if(!terrain.landBorder) { heightMap[0] = rndHeight(); heightMap[stepX] = rndHeight(); heightMap[(stepX + 1) * stepZ] = rndHeight(); heightMap[(stepX + 1) * stepZ + stepX] = rndHeight(); } usedHeightMap[0] = true; usedHeightMap[stepX] = true; usedHeightMap[(stepX + 1) * stepZ] = true; usedHeightMap[(stepX + 1) * stepZ + stepX] = true; fractalGrid(&heightMap[0], &usedHeightMap[0], stepX, stepZ, stepX, stepZ, 0, depth); // compute positions float x = 0.0f; float z = 0.0f; const float xInc = 1.0f / stepX; const float zInc = 1.0f / stepZ; for(uint32 i = 0; i <= stepX; i++, x += xInc) { for(uint32 j = 0; j <= stepZ; j++, z += zInc) { const uint32 k = ((stepX + 1) * i + j); vx[k].position = QVector3D(x - 0.5f, heightMap[k] * terrain.heightMultiplier, z - 0.5f); vx[k].normal = QVector3D(0.0, 1.0, 0.0); vx[k].texCoord = QVector2D(-x * 10, z * 10); vx[k].color = QVector3D(1.0, 0.0, 0.0); vx[k].color2 = QVector3D(0.0, 0.0, 0.0); } z = 0.0f; } // compute normals, tangents, bitangents for(int32 v = 0; v < vx.size(); v++) { uint32 x = v % (stepX + 1); uint32 z = v / (stepX + 1); if((x > 0) && (x < stepX) && (z > 0) && (z < stepZ)) { QVector3D &vC = vx[v].position; QVector3D &vL = vx[v - 1].position; QVector3D &vR = vx[v + 1].position; QVector3D &vT = vx[v - stepX - 1].position; QVector3D &vB = vx[v + stepX + 1].position; vx[v].normal = QVector3D::normal(vC, vL, vT); vx[v].normal += QVector3D::normal(vC, vT, vR); vx[v].normal += QVector3D::normal(vC, vR, vB); vx[v].normal += QVector3D::normal(vC, vB, vL); vx[v].normal.normalize(); vx[v].normalTangent = QVector3D(vx[v].normal.y(), -vx[v].normal.x(), -vx[v].normal.z()); vx[v].normalBitangent = QVector3D(-vx[v].normal.x(), -vx[v].normal.z(), vx[v].normal.y()); } } // compute colors by layers for(int32 v = 0; v < vx.size(); v++) { for(int32 l = 0; l != terrain.layers.size(); l++) { const SMaterialLayer *layer = &terrain.layers[l]; if(!(((layer->useHeightLimit) && ((vx[v].position.y() < layer->minHeight) || (vx[v].position.y() > layer->maxHeight))) || ((layer->useSlopeLimit) && (((1.0f - vx[v].normal.y()) < layer->minSlope) || ((1.0f - vx[v].normal.y()) > layer->maxSlope))))) { vx[v].color = layer->color.toVector3D() * layer->color.w(); heightMapLayer[v] = l; } } } /*for(int32 v = 0; v < vx.size(); v++) qDebug(QString("y %1, x %2: %3").arg(v / (stepX + 1)).arg(v % (stepX + 1)).arg(heightMapLayer[v]).toStdString().c_str());*/ // divide to meshes, fill model meshes /*model.materials.clear(); model.materials.push_back(SMaterial(context->getShaders()->getShaderProgram(NShader::PROGRAM_TERRAIN), context->getMaps()->addMap(SMap(":/maps/data/maps/rocks00n.png")), context->getMaps()->addMap(SMap(":/maps/data/maps/rocks00n.png")), context->getMaps()->addMap(SMap(":/maps/data/maps/rocks00n.png"))));*/ /*model.meshes.clear(); for(uint32 m = 0; m < (divStepX * divStepZ); m++) { model.meshes.push_back(SMesh()); SMesh *mesh = &model.meshes.back(); mesh->transformation = SMatrix::composeTransformation(mesh->position, mesh->rotation, mesh->scale); mesh->faces.push_back(SFaces()); SFaces *faces = &mesh->faces.back(); mesh->vertices.resize((stepMeshX + 1) * (stepMeshZ + 1)); faces->faces.resize(stepMeshX * stepMeshZ * NTerrain::FACE_BLOCK_SIZE); uint32 offset = (m / divStepZ) * stepMeshZ * (stepX + 1) + (m % divStepX) * stepMeshX; uint32 mCol2 = 0; for(uint32 mRow = 0; mRow <= stepMeshZ; mRow++, offset += (stepX + 1)) { for(uint32 mCol = 0; mCol <= stepMeshX; mCol++, mCol2++) { mesh->vertices[mCol2] = vx[offset + mCol]; if((mRow == stepMeshZ) || (mCol == stepMeshX)) mesh->vertices[mCol2].color = QVector3D(0.8, 0.2, 0.2); } } for(uint32 i = 0; i < stepMeshX; i++) { for(uint32 j = 0; j < stepMeshZ; j++) { const uint32 k = (stepMeshX * i + j) * NTerrain::FACE_BLOCK_SIZE; const uint32 l0 = (stepMeshX + 1) * i + j + 0; const uint32 l1 = (stepMeshX + 1) * i + j + 1; const uint32 l2 = (stepMeshX + 1) * (i + 1) + j + 0; const uint32 l3 = (stepMeshX + 1) * (i + 1) + j + 1; faces->faces[k + 0] = SFace(l0, l1, l2); faces->faces[k + 1] = SFace(l2, l1, l3); } } }*/ model.materials.clear(); const CMap *noMap = context->getMaps()->getMap(NMap::DEFAULT_NORMAL); // default map model.meshes.clear(); for(uint32 gz = 0; gz < divStepZ; gz++) { for(uint32 gx = 0; gx < divStepX; gx++) { // sub mesh //const uint32 groupBase = gz * divStepZ + gx; const uint32 vxGroupBase = gz * stepMeshZ * (stepX + 1) + gx * stepMeshX; //qDebug("new mesh"); model.meshes.push_back(SMesh()); SMesh *mesh = &model.meshes.back(); mesh->transformation = SMatrix::composeTransformation(mesh->position, mesh->rotation, mesh->scale); for(uint32 ez = 0; ez < stepMeshZ; ez++) { for(uint32 ex = 0; ex < stepMeshX; ex++) { // two faces block const uint32 vx0 = vxGroupBase + ez * (stepX + 1) + ex; const uint32 vx1 = vx0 + 1; const uint32 vx2 = vx0 + (stepX + 1); const uint32 vx3 = vx2 + 1; for(uint8 v = 0; v < NTerrain::FACE_BLOCK_SIZE; v++) { // one face const uint32 face[NModel::FACE_SIZE] = { (!v) ? vx0 : vx2, (!v) ? vx1 : vx1, (!v) ? vx2 : vx3 }; // material signature QSet<int32> faceSet; faceSet.insert(heightMapLayer[face[0]]); faceSet.insert(heightMapLayer[face[1]]); faceSet.insert(heightMapLayer[face[2]]); QVector<int32> faceMats = faceSet.toList().toVector(); qSort(faceMats.begin(), faceMats.end()); //qDebug(QString("%1 %2 %3 : %4 %5 %6 : %7").arg(face[0]).arg(face[1]).arg(face[2]).arg(heightMapLayer[face[0]]).arg(heightMapLayer[face[1]]).arg(heightMapLayer[face[2]]).arg(faceMats.size()).toStdString().c_str()); /*for(int32 i : faceMats) qDebug(QString("%1").arg(i).toStdString().c_str());*/ SFaces *faces = NULL; for(auto f = mesh->faces.begin(); f != mesh->faces.end(); f++) { // find faces group by material signature if(!f->material) { //qDebug("chyba mat chybi"); break; } else if(f->material->layerVx == faceMats) { //qDebug("nasel"); faces = &(*f); break; } } if(!faces) { SMaterial *material = NULL; for(auto m = model.materials.begin(); m != model.materials.end(); m++) { // find previous used material if(m->layerVx == faceMats) { //qDebug("nenasel, ale predchozí mat ano"); material = &(*m); break; } } if(!material) { //qDebug("nenasel"); const CMap *maps[NModel::FACE_SIZE]; for(int32 i = 0; static_cast<uint32>(i) < NModel::FACE_SIZE; i++) { maps[i] = (faceMats.size() > i) ? ((faceMats[i] != -1) ? terrain.layers[faceMats[i]].detailTexture : noMap) : NULL; /*if(maps[i]) qDebug(maps[i]->getMap()->file.toStdString().c_str()); else qDebug("no map");*/ } model.materials.push_back(SMaterial(context->getShaders()->getShaderProgram(NShader::PROGRAM_TERRAIN), NULL, NULL, NULL, maps[0], NULL, NULL, NULL, NULL, NULL, maps[1], maps[2], faceMats)); material = &model.materials.back(); } mesh->faces.push_back(SFaces(material)); faces = &mesh->faces.back(); } uint16 newFace[NModel::FACE_SIZE]; SVertex newVx[NModel::FACE_SIZE] = { vx[face[0]], vx[face[1]], vx[face[2]] }; for(uint32 i = 0; i < NModel::FACE_SIZE; i++) { // set texture using multiplier if(heightMapLayer[face[i]] == faceMats[0]) newVx[i].color2.setX(1.0f); else if(heightMapLayer[face[i]] == faceMats[1]) newVx[i].color2.setY(1.0f); else if(heightMapLayer[face[i]] == faceMats[2]) newVx[i].color2.setZ(1.0f); //qDebug(QString("face %1: %2 %3 %4").arg(i).arg(newVx[i].color2.x()).arg(newVx[i].color2.y()).arg(newVx[i].color2.z()).toStdString().c_str()); bool found = false; for(int32 v = 0; v < mesh->vertices.size(); v++) { // find same vertex if((mesh->vertices[v].position == newVx[i].position) && (mesh->vertices[v].color2 == newVx[i].color2)) { //qDebug("same vx found"); found = true; newFace[i] = v; break; } } if(!found) { //qDebug("same vx not found"); newFace[i] = mesh->vertices.size(); mesh->vertices.push_back(newVx[i]); } } faces->faces.push_back(SFace(newFace[0], newFace[1], newFace[2])); } } } //qDebug(QString("-------- face groups: %1").arg(mesh->faces.size()).toStdString().c_str()); } } //qDebug(QString("-------- meshes: %1").arg(model.meshes.size()).toStdString().c_str()); }
float c_nearPlaneDistance = 0.1f; const float c_cameraVerticalFOV = 40.0f * c_pi / 180.0f; // the scene const std::vector<SSphere> c_spheres = { // Position | Radius| Emissive | Diffuse { { 4.0f, 4.0f, 6.0f }, 0.5f, { { 10.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f } } }, // light { { 0.0f, 0.0f, 4.0f }, 2.0f, { { 0.0f, 0.0f, 0.0f }, { 0.5f, 0.5f, 0.5f } } }, // ball }; const std::vector<STriangle> c_triangles = {}; const std::vector<SQuad> c_quads = { // floor SQuad({ -4.0f, -3.0f, -4.0f },{ -4.0f, 2.0f, -4.0f },{ -4.0f, 2.0f, 12.0f },{ -4.0f, -3.0f, 12.0f }, SMaterial({ 0.0f, 0.0f, 0.0f },{ 0.1f, 0.9f, 0.1f })), // green wall SQuad({ -15.0f, -2.0f, 15.0f },{ 15.0f, -2.0f, 15.0f },{ 15.0f, -2.0f, -15.0f },{ -15.0f, -2.0f, -15.0f }, SMaterial({ 0.0f, 0.0f, 0.0f },{ 0.9f, 0.1f, 0.1f })), }; const std::vector<SAABB> c_aabbs = {}; const std::vector<SOBB> c_obbs = {}; const TVector3 c_rayMissColor = { 0.0f, 0.0f, 0.0f }; #elif RENDER_SCENE() == 1 // camera parameters - assumes no roll (z axis rotation) and assumes that the camera isn't looking straight up const TVector3 c_cameraPos = {0.0f, 0.0f, -10.0f}; const TVector3 c_cameraLookAt = { 0.0f, 0.0f, 0.0f };
//! Removes all texture from the texture cache and deletes them, freeing lot of //! memory. void CNullDriver::removeAllTextures() { setMaterial ( SMaterial() ); deleteAllTextures(); }