/
wmigor
/
z-plane
Обзор
Документация
Войти
/
wmigor
/
z-plane
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
app/src/Ground.cpp
170 строк
6 KB
wmigor
Плавное управление мышкой
04 июн 2026, 23:00
Верифицирован
04 июн 2026, 23:00
43aa585
Код
Авторство
О чём код?
#include "Ground.h" #include <osg/ShapeDrawable> Ground::Ground(osg::MatrixTransform *aircraftView): osg::Geode() { auto vertexShader = "uniform mat4 uLightMatrix;\n" "uniform mat4 uModelMatrix;\n" "varying vec3 vColor;\n" "varying vec2 vUv;\n" "varying vec4 vPosFromLight;\n" "vec3 lightDirection = vec3(0.0, 1.0, 0.0);\n" "float uvScale = 10.0;\n" "void main()\n" "{\n" " vec3 normal = gl_Normal;\n" " float t = max(0.5, dot(normal, lightDirection));\n" " vColor = gl_Color.rgb * t;\n" " vUv = gl_MultiTexCoord0.xy * uvScale;\n" " vec3 fragPos = vec3(uModelMatrix * vec4(gl_Vertex.xyz, 1.0));\n" " vPosFromLight = uLightMatrix * vec4(fragPos, 1.0);\n" " gl_Position = ftransform();\n" "}"; auto fragmentShader = "uniform sampler2D uShadowMap;\n" "uniform sampler2D uDiffuseMap;\n" "varying vec3 vColor;\n" "varying vec2 vUv;\n" "varying vec4 vPosFromLight;\n" "float shadow()\n" "{\n" " vec3 projCoords = vPosFromLight.xyz / vPosFromLight.w;\n" " projCoords = projCoords * 0.5 + 0.5;\n" " if (projCoords.z > 1.0)\n" " return 0.0;\n" " float closestDepth = texture2D(uShadowMap, projCoords.xy).r;\n" " float currentDepth = projCoords.z;\n" " float bias = 0.000;\n" " float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;\n" " return shadow;\n" "}\n" "void main()\n" "{\n" " vec3 color = vColor * texture2D(uDiffuseMap, vUv).xyz * (1.0 - shadow() * 0.75);\n" " gl_FragColor = vec4(color, 1.0);\n" "}"; auto program = new osg::Program(); program->addShader(new osg::Shader(osg::Shader::VERTEX, vertexShader)); program->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragmentShader)); getOrCreateStateSet()->setAttributeAndModes(program, osg::StateAttribute::ON); getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); getOrCreateStateSet()->setTextureAttributeAndModes(0, createGroundTexture()); getOrCreateStateSet()->addUniform(new osg::Uniform("uDiffuseMap", 0)); auto shadowMap = createShadowMap(1024, 1024); auto shadowCamera = createShadowCamera(shadowMap); shadowCamera->addChild(aircraftView); addChild(shadowCamera); shadowCamera->setUpdateCallback(new ShadowCameraCallback(aircraftView)); getOrCreateStateSet()->setTextureAttributeAndModes(1, shadowMap); getOrCreateStateSet()->addUniform(new osg::Uniform("uShadowMap", 1)); auto modelMatrixUniform = new osg::Uniform("uModelMatrix", osg::Matrixf()); auto lightMatrixUniform = new osg::Uniform("uLightMatrix", osg::Matrixf()); getOrCreateStateSet()->addUniform(modelMatrixUniform); getOrCreateStateSet()->addUniform(lightMatrixUniform); auto geode = new osg::Geode(); geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3d(0.0, -1.0, 0.0), 10000.0, 2.0, 10000.0))); addChild(geode); geode->setUpdateCallback(new GroundCallback(shadowCamera, modelMatrixUniform, lightMatrixUniform)); } osg::Texture2D *Ground::createGroundTexture() { auto image = new osg::Image(); image->allocateImage(2, 2, 1, GL_RGB, GL_FLOAT); auto color1 = 0.7f; auto color2 = 0.5f; auto colors = (float *) image->data(); colors[0] = colors[1] = colors[2] = color1; colors[3] = colors[4] = colors[5] = color2; colors[6] = colors[7] = colors[8] = color2; colors[9] = colors[10] = colors[11] = color1; auto texture = new osg::Texture2D(); texture->setImage(image); texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST); texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::REPEAT); texture->setWrap(osg::Texture::WRAP_T, osg::Texture::REPEAT); return texture; } osg::Texture2D *Ground::createShadowMap(int width, int height) { auto texture = new osg::Texture2D(); texture->setTextureSize(width, height); texture->setInternalFormat(GL_DEPTH_COMPONENT); texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR); texture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_BORDER); texture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_BORDER); texture->setBorderColor(osg::Vec4(1.0, 1.0, 1.0, 1.0)); return texture; } osg::Camera *Ground::createShadowCamera(osg::Texture2D *shadowMap) { auto camera = new osg::Camera(); camera->setViewport(0, 0, shadowMap->getTextureWidth(), shadowMap->getTextureHeight()); camera->setClearDepth(1.0); camera->setClearMask(GL_DEPTH_BUFFER_BIT); camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); camera->attach(osg::Camera::DEPTH_BUFFER, shadowMap); camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); camera->setAllowEventFocus(false); camera->setProjectionMatrixAsOrtho(-6.0, 6.0, -6.0, 6.0, 0.1, 10000.0); camera->setViewMatrixAsLookAt(osg::Vec3(0.0, 10.0, 0.0), osg::Vec3(0.0, 0.0, 0.0), osg::Vec3(0.0, 0.0, 1.0)); return camera; } GroundCallback::GroundCallback(osg::Camera *camera, osg::Uniform *modelMatrixUniform, osg::Uniform *lightMatrixUniform): _camera(camera), _modelMatrixUniform(modelMatrixUniform), _lightMatrixUniform(lightMatrixUniform) { } void GroundCallback::operator()(osg::Node* node, osg::NodeVisitor* nv) { _lightMatrixUniform->set(_camera->getViewMatrix() * _camera->getProjectionMatrix()); osg::Matrixf modelMatrix; modelMatrix.makeTranslate(0.0, -1.0, 0.0); _modelMatrixUniform->set(modelMatrix); traverse(node, nv); } ShadowCameraCallback::ShadowCameraCallback(osg::MatrixTransform *aircraft): _aircraft(aircraft) { } void ShadowCameraCallback::operator()(osg::Node* node, osg::NodeVisitor* nv) { auto camera = dynamic_cast<osg::Camera *>(node); if (camera != NULL) { auto position = _aircraft->getMatrix().getTrans(); camera->setViewMatrixAsLookAt(position + osg::Vec3d(0.0, 10.0, 0.0), position, osg::Vec3d(0.0, 0.0, 1.0)); } traverse(node, nv); }