Библиотеки GDI оказывают огромную помощь в создании красочного окна приложения. Перья, кисти, регионы, битовые массивы. Можно не заботиться о совместимости кода с аппаратными средствами компьютера. Но в большинстве случаев можно создавать только статические и плоские изображения. Динамичные же сцены или попытка создать объемные изображения омрачает своей медлительностью и сложностью.
Вот здесь и приходит на помощь DirectX. Библиотеке DirectX подвластны реалистичные объемные изображения. Графические сущности 3D визуализации схожи с реальным окружающим миром : 3D среда, мировое пространство, трехмерное пространство. На плоском мониторе DirectX творит чудеса, завораживающие своей реалистичностью. Плата за эту мощь — сложность настройки 3D среды и обеспечения устойчивости работы 3D рендеринга (передача, воспроизведение 3D сцены) при изменениях некоторых настроек приложения и операционной системы.
Устойчивость 3D приложения
На устойчивость работы 3D приложения влияют внутренние и внешние факторы. Внутренние факторы зависят от корректности кода, внешние факторы в основном зависят от пользователя компьютера (и чем «чайней» пользователь, тем серьезней могут быть последствия их действий).
1. Как создать 3D модель и напечатать её на 3D принтере. От задумки до физического воплащения. ABS
- Изменение размеров окна;
- Изменение режима работы приложения (оконный, полноэкранный);
- Изменение цветовой глубины пикселя монитора;
- Переход в спящий/ждущий режим;
- Обработка потери/восстановления фокуса приложением в полноэкранном режиме.
Direct3D — потеря устройства
В Direct3D (визуальная часть библиотеки DirectX) есть такое понятие — потеря устройства. В нормальном состоянии рендеринг (показ 3D сцены) осуществляется без проблем. Но при возникновении событий выше перечисленных факторов, устройство Direct3D может быть потеряно.
Потерянное состояние характеризуется тем, что функции, подготавливающие и осуществляющие рендеринг, возвращают код успеха, но при этом на экране не отображается 3D сцена. Определить это состояние помогает метод IDirect3DDevice9::Present . При потере устройства код его возврата равен D3DERR_DEVICELOST . Расшифровка кода возврата D3DERR_DEVICELOST — устройство было потеряно и рендеринг 3D сцены невозможен. Протестировать устройство Direct3D может быть восстановлено или нет можно с помощью метода IDirect3DDevice9::TestCooperativeLevel . При возврате кода равного D3DERR_DEVICENOTRESET появляется возможность восстановления устройства.
Принудительный сброс устройства Direct3D
В случае изменения размеров окна рендеринга, показ 3D сцены не прекращается, но при изменении форматного отношения (ширины окна к высоте) искажаются геометрические пропорции объектов сцены. В данной ситуации необходим «принудительный» сброс устройства и восстановление объектов 3D сцены для сохранения правильных форм.
Исходник на С++ устойчивого движка 3D приложения
Представленный ниже исходник, с подробными комментариями, описывает выходы из состояния потери устройства Direct3D и сброс/восстановление объектов 3D сцены. На примере полета сквозь звезды шаг за шагом создается устойчивое 3D приложение с использованием MFC.
ВАША ПЕРВАЯ 3Д МОДЕЛЬ В BLENDER
Исходник создан в среде программирования MS Visual Studio .NET 2003. SDK DirectX9.
Источник: www.interestprograms.ru
Python-сообщество
- Начало
- » Python для новичков
- » Как написать 3d программу на Python
#1 Окт. 30, 2014 19:37:03
Как написать 3d программу на Python
Shaman
Ведь все модули написаны на питоне, то есть в них используются стандартные возможности языка. Я не понимаю, как имея на начальном этапе только стандартную часть языка (while, for, if, list, int … ) сделать графический модуль?
В стандартные возможности языка входят стандартные модули. Среди них есть ctypes. он позволяет вызвать функции из “ядра операционной системы”. Там есть и функции для работы с графикой.
Вы не совсем правильно представляете работу с графикой. Даже программа на C не сможет отрисовывать 3D сцены с приемлемой скоростью если будет работать с отдельными пикселями. Общение программы с монитором идет на специальном языке (в котором нет раскраски отдельных пикселей). А сами пиксели красит “Железо”. Грубо говоря программа просит — нарисуй прямую, а видеокарта уже красит пиксели.
Эти языки были обобщены в графических библиотеках например (http://www.opengl.org.ru/, GDI. DirectX и т.п.) Перевод команд библиотеки на команды железа осуществляет видеодрайвер. А из питона можно уже пользоваться разными библиотеками.
http://pyopengl.sourceforge.net/…
Я не специалист в этом деле, может кто подробнее напишет.
#2 Окт. 30, 2014 21:52:16
Как написать 3d программу на Python
doza_and
В стандартные возможности языка входят стандартные модули. Среди них есть ctypes. он позволяет вызвать функции из “ядра операционной системы”. Там есть и функции для работы с графикой.
Не совсем так, если уж быть совсем точным.
“Стандартная” реализция питона — CPython позволяет подключение специально оформленных бинарных модулей как питон-модулей. Эту возможность эксплуатирует и ctypes.
Отредактировано Shaman (Окт. 30, 2014 21:59:46)
#3 Окт. 30, 2014 22:50:03
Как написать 3d программу на Python
Pavel_Blend
Вообще, возможно ли написать 3д программу на питоне с нуля без использования модулей? Под 3д программой я имею ввиду не редактор (типо 3дс Макс, Майа …), а Viewer в котором можно было бы вращать в пространстве какую-нибудь 3д модель (куб, шар …) У меня просто в голове не укладывается, как это реализовывается. Как с помощью всех этих стандартных while, for, if и др. операторов сделать 3д пространство, которое будет видно на мониторе?
Хотя, никто не мешает отрендерить в графический, или видео-формат и смотреть результат другим софтом.
Источник: python.su
Создание игры «Aviator»: изучаем основы 3D-анимации c Three.js. Часть первая. Создание сцены
В этой серии из двух статей мы создадим простую 3D-игру про летающий самолётик при помощи Three.js, библиотеки, упрощающей работу с WebGL. WebGL — для многих тёмный лес из-за сложности и синтаксиса GLSL. Но благодаря Three.js реализация 3D в браузере стала гораздо проще.
В первой части мы разберем основы Three.js и создадим сцену. Во второй — улучшим графику и добавим атмосферности. В данном руководстве не будет разбираться создание всей игры, но вы можете изучить её исходный код и сделать на его основе что-то своё.
HTML и CSS
В этом руководстве упор будет сделан на библиотеку Three.js. Посетите сайт и GitHub-репозиторий, чтобы узнать про неё больше.
Сперва мы импортируем библиотеку в заголовке HTML :
Затем добавим элемент-контейнер для хранения сцены:
Стилизуем её следующим образом:
#world
Собственно, с разметкой и стилями мы закончили!
JavaScript
Three.js очень легко использовать, есть у вас есть базовые знания по JavaScript. Давайте разберем код, который мы будем использовать.
Цветовая палитра
Я считаю правильным всегда определяться с палитрой цветов прежде, чем писать код. В этом проекте я выбрал следующие цвета:
var Colors = < red:0xf25346, white:0xd8d0d1, brown:0x59332e, pink:0xF5986E, brownDark:0x23190f, blue:0x68c3c0, >;
Структура кода
Хотя JavaScript-код и бывает громоздким, его структура весьма проста. Все основные действия нужно поместить в функцию init:
window.addEventListener(‘load’, init, false); function init() < // set up the scene, the camera and the renderer createScene(); // add the lights createLights(); // add the objects createPlane(); createSea(); createSky(); // start a loop that will update the objects’ positions // and render the scene on each frame loop(); >
Настройка сцены
Для создания проекта на Three.js нам нужен следующий минимальный набор:
- Сцена: представьте её, как площадку, на которую нужно добавить каждый объект для отрисовки.
- Камера: в нашем случае мы будем использовать перспективную камеру, но могли бы взять и ортогональную.
- Рендерер: он отрисует всю сцену, используя WebGL.
- Один или несколько объектов: в нашем случае — самолёт, море и небо (несколько облаков).
- Один или несколько источников света: доступно несколько видов источников. Мы будем использовать полусферический источник для атмосферы и направленный — для теней.
Сцена, камера и отрисовщик создаются в функции createScene:
var scene, camera, fieldOfView, aspectRatio, nearPlane, farPlane, HEIGHT, WIDTH, renderer, container; function createScene() < // Get the width and the height of the screen, // use them to set up the aspect ratio of the camera // and the size of the renderer. HEIGHT = window.innerHeight; WIDTH = window.innerWidth; // Create the scene scene = new THREE.Scene(); // Add a fog effect to the scene; same color as the // background color used in the style sheet scene.fog = new THREE.Fog(0xf7d9aa, 100, 950); // Create the camera aspectRatio = WIDTH / HEIGHT; fieldOfView = 60; nearPlane = 1; farPlane = 10000; camera = new THREE.PerspectiveCamera( fieldOfView, aspectRatio, nearPlane, farPlane ); // Set the position of the camera camera.position.x = 0; camera.position.z = 200; camera.position.y = 100; // Create the renderer renderer = new THREE.WebGLRenderer(< // Allow transparency to show the gradient background // we defined in the CSS alpha: true, // Activate the anti-aliasing; this is less performant, // but, as our project is low-poly based, it should be fine 🙂 antialias: true >); // Define the size of the renderer; in this case, // it will fill the entire screen renderer.setSize(WIDTH, HEIGHT); // Enable shadow rendering renderer.shadowMap.enabled = true; // Add the DOM element of the renderer to the // container we created in the HTML container = document.getElementById(‘world’); container.appendChild(renderer.domElement); // Listen to the screen: if the user resizes it // we have to update the camera and the renderer size window.addEventListener(‘resize’, handleWindowResize, false); >
Поскольку размер экрана может изменяться, нам нужно обновлять размер отрисовщика и соотношение сторон камеры:
function handleWindowResize() < // update height and width of the renderer and the camera HEIGHT = window.innerHeight; WIDTH = window.innerWidth; renderer.setSize(WIDTH, HEIGHT); camera.aspect = WIDTH / HEIGHT; camera.updateProjectionMatrix(); >
Источники света
Настройка освещения — это один из самых сложных этапов создания сцены. Источники света задают настроение всей сцены, поэтому работать с ними нужно очень внимательно. На данном этапе мы просто настроим освещение таки образом, чтобы видеть все объекты.
var hemisphereLight, shadowLight; function createLights() < // A hemisphere light is a gradient colored light; // the first parameter is the sky color, the second parameter is the ground color, // the third parameter is the intensity of the light hemisphereLight = new THREE.HemisphereLight(0xaaaaaa,0x000000, .9) // A directional light shines from a specific direction. // It acts like the sun, that means that all the rays produced are parallel. shadowLight = new THREE.DirectionalLight(0xffffff, .9); // Set the direction of the light shadowLight.position.set(150, 350, 350); // Allow shadow casting shadowLight.castShadow = true; // define the visible area of the projected shadow shadowLight.shadow.camera.left = -400; shadowLight.shadow.camera.right = 400; shadowLight.shadow.camera.top = 400; shadowLight.shadow.camera.bottom = -400; shadowLight.shadow.camera.near = 1; shadowLight.shadow.camera.far = 1000; // define the resolution of the shadow; the higher the better, // but also the more expensive and less performant shadowLight.shadow.mapSize.width = 2048; shadowLight.shadow.mapSize.height = 2048; // to activate the lights, just add them to the scene scene.add(hemisphereLight); scene.add(shadowLight); >
Видно, что для настройки освещения используется много параметров. Не бойтесь экспериментировать с цветами, их интенсивностью и источниками света: вы обнаружите огромное количество интересных сочетаний и разберётесь, как их настраивать в соответствии с вашими нуждами.
Создание объекта в Three.js
Если вы разбираетесь в создании 3D-моделей, то можете импортировать в проект свои модели. Мы же создадим объекты из примитивов Three.js, чтобы понять, как они устроены.
В Three.js доступны следующие примитивы: куб, сфера, тор, цилиндр и плоскость. В нашем проекте все объекты будут являться комбинациями этих тел.
Простой цилиндр для моря
Начнём с создания моря, поскольку это самая простая часть. Не будем усложнять и зададим море простым голубым цилиндром, помещённым внизу экрана. В дальнейшем мы сделаем его более красивым.
Разработчик Bitrix АО «Гринатом» , Удалённо , По итогам собеседования
Теперь давайте сделаем море чуть более привлекательным, а волны — более реалистичными:
// First let’s define a Sea object : Sea = function()< // create the geometry (shape) of the cylinder; // the parameters are: // radius top, radius bottom, height, number of segments on the radius, number of segments vertically var geom = new THREE.CylinderGeometry(600,600,800,40,10); // rotate the geometry on the x axis geom.applyMatrix(new THREE.Matrix4().makeRotationX(-Math.PI/2)); // create the material var mat = new THREE.MeshPhongMaterial(< color:Colors.blue, transparent:true, opacity:.6, shading:THREE.FlatShading, >); // To create an object in Three.js, we have to create a mesh // which is a combination of a geometry and some material this.mesh = new THREE.Mesh(geom, mat); // Allow the sea to receive shadows this.mesh.receiveShadow = true; > // Instantiate the sea and add it to the scene: var sea; function createSea()< sea = new Sea(); // push it a little bit at the bottom of the scene sea.mesh.position.y = -600; // add the mesh of the sea to the scene scene.add(sea.mesh); >
Итак, давайте подытожим, что нужно для создания объекта. Нам нужно:
- создать геометрическую модель;
- создать материал;
- передать их в меш;
- добавить меш на сцену.
Следуя этим простым шагам, мы можем создать множество разных примитивных объектов и объединить их в более сложные фигуры.
В следующих этапах мы займёмся именно этим.
Объединяем простые кубы для создания сложной фигуры
Облака уже чуть сложнее моря, поскольку они состоят из нескольких соединённых случайным образом кубов.
Cloud = function()< // Create an empty container that will hold the different parts of the cloud this.mesh = new THREE.Object3D(); // create a cube geometry; // this shape will be duplicated to create the cloud var geom = new THREE.BoxGeometry(20,20,20); // create a material; a simple white material will do the trick var mat = new THREE.MeshPhongMaterial(< color:Colors.white, >); // duplicate the geometry a random number of times var nBlocs = 3+Math.floor(Math.random()*3); for (var i=0; i >
Теперь, когда мы создали облако, мы заполним им всё небо, разместив его копии случайным образом на оси z:
// Define a Sky Object Sky = function() < // Create an empty container this.mesh = new THREE.Object3D(); // choose a number of clouds to be scattered in the sky this.nClouds = 20; // To distribute the clouds consistently, // we need to place them according to a uniform angle var stepAngle = Math.PI*2 / this.nClouds; // create the clouds for(var i=0; i> // Now we instantiate the sky and push its center a bit // towards the bottom of the screen var sky; function createSky()
Ещё сложнее: создаём самолёт
Плохая новость: код самолёта будет длиннее и сложнее. Хорошая: мы знаем уже почти всё необходимое! Весь процесс заключается в комбинировании и инкапсуляции фигур.
var AirPlane = function() < this.mesh = new THREE.Object3D(); // Create the cabin var geomCockpit = new THREE.BoxGeometry(60,50,50,1,1,1); var matCockpit = new THREE.MeshPhongMaterial(); var cockpit = new THREE.Mesh(geomCockpit, matCockpit); cockpit.castShadow = true; cockpit.receiveShadow = true; this.mesh.add(cockpit); // Create the engine var geomEngine = new THREE.BoxGeometry(20,50,50,1,1,1); var matEngine = new THREE.MeshPhongMaterial(); var engine = new THREE.Mesh(geomEngine, matEngine); engine.position.x = 40; engine.castShadow = true; engine.receiveShadow = true; this.mesh.add(engine); // Create the tail var geomTailPlane = new THREE.BoxGeometry(15,20,5,1,1,1); var matTailPlane = new THREE.MeshPhongMaterial(); var tailPlane = new THREE.Mesh(geomTailPlane, matTailPlane); tailPlane.position.set(-35,25,0); tailPlane.castShadow = true; tailPlane.receiveShadow = true; this.mesh.add(tailPlane); // Create the wing var geomSideWing = new THREE.BoxGeometry(40,8,150,1,1,1); var matSideWing = new THREE.MeshPhongMaterial(); var sideWing = new THREE.Mesh(geomSideWing, matSideWing); sideWing.castShadow = true; sideWing.receiveShadow = true; this.mesh.add(sideWing); // propeller var geomPropeller = new THREE.BoxGeometry(20,10,10,1,1,1); var matPropeller = new THREE.MeshPhongMaterial(); this.propeller = new THREE.Mesh(geomPropeller, matPropeller); this.propeller.castShadow = true; this.propeller.receiveShadow = true; // blades var geomBlade = new THREE.BoxGeometry(1,100,20,1,1,1); var matBlade = new THREE.MeshPhongMaterial(); var blade = new THREE.Mesh(geomBlade, matBlade); blade.position.set(8,0,0); blade.castShadow = true; blade.receiveShadow = true; this.propeller.add(blade); this.propeller.position.set(50,0,0); this.mesh.add(this.propeller); >;
Самолёт выглядит слишком просто, не так ли? Не волнуйтесь, в дальнейшем мы сделаем его куда более привлекательным!
Разместим самолёт на сцене:
var airplane; function createPlane()