Вы читаете coin3d_ru

Как вы могли заметить, листинги с кодом перестали выглядеть красиво. Вот что мне ответили в саппорте:

Запрет на использование атрибутов “class” и “id” внутри записей пользователей был введен Живым Журналом как мера по борьбе с фишинговыми атаками.

В дальнейшем, возможность использования данных атрибутов будет возвращена для пользователей платных аккаунтов. Вы можете следить за информацией об обновлениях по адресу http://lj-ru-support.livejournal.com/tag/release.

На данный момент вы можете использовать атрибут style для элементов записи для присвоения им тех или иных свойств стилей.

Примите извинения за неудобства.


Утилиту для подсветки кода я, конечно же, перепишу, но старые листинги обновлять не буду. Так что вот.(

Метки:

Хочу рассказать о давно известном факте, на который никогда не обращал внимания. Но знать его нужно, поэтому зафиксирую прямо тут и здесь.
Что такое статические методы всем прекрасно известно. Чем статические методы отличаются от методов тоже понятно. Но! От меня долгое время ускользал тот факт, что некоторые методы всегда являются статическими, независимо от использования ключевого слова static. Это операторы new и delete. По своей природе они не могут работать с объектом, т.к. именно они выделяют память для будущего объекта и освобождают её после его удаления. Т.е. в момент их вызова объект ещё либо не создан, либо уже разрушен.
Разработчики приняли очень правильное решение избавить программистов от потенциальных ошибок и сделали эти операторы статическими по умолчанию.
В приведённом ниже коде операторы new и delete являются статическими методами, поэтому внутри них невозможно использовать указатель на объект this.

new & delete.cpp
1 2 3 4 5 6    class Object { public: void * operator new( size_t ); void operator delete( void * ); };

Метки:

О записях...

Записи в сообществе не статичны, по возможности я их корректирую, дополняю, исправляю ошибки. К сожалению, в сообществе нельзя выставлять внеочередную дату, поэтому я не могу как-то выделить обновлённые записи. Удалять и создавать новую запись не хочется.
На данном этапе к описаниям классов добавляются примеры использования. Это небольшие законченные примеры того, как пользоваться тем или иным классом. Они предельно просты и не реализуют всех возможностей описываемых классов, зато их просто понять.
Утилита для подсветки кода также обновляется периодически.

Метки:

"Чиним" coin

#UPD: Бяки.( Отправил разработчикам эту ошибку. В ответ получил: "Тех. поддержка оказывается только пользователям платных аккаунтов". Вот с каких пор, чтобы сообщить об ошибке, нужно осуществлять подписку? Ну и ладно, я всё равно умею эту ошибку исправлять.)


При каждой компиляции шейдера, выводится информационное сообщение об успешной или провальной компиляции.
По моему, видеть этот диалог при успешной компиляции вовсе не обязательно, поэтому мы от него избавимся.


Для исправления, откройте файл "SoGLSLShaderObject.cpp" и отредактируйте метод SoGLSLShaderObject::load как показано ниже. Пересоберите библиотеку.
SoGLSLShaderObject.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56    SbBool SoGLSLShaderObject::isLoaded(void) const { return (this->shaderHandle != 0); } void SoGLSLShaderObject::load(const char* srcStr) { this->unload(); this->setParametersDirty(TRUE); GLint flag; GLenum sType; switch (this->getShaderType()) { default: assert(0 &&" unknown shader type"); case VERTEX: sType = GL_VERTEX_SHADER_ARB; break; case FRAGMENT: sType = GL_FRAGMENT_SHADER_ARB; break; case GEOMETRY: sType = GL_GEOMETRY_SHADER_EXT; break; } this->shaderHandle = this->glctx->glCreateShaderObjectARB(sType); this->programid = 0; if (this->shaderHandle == 0) return; this->programid = soglshaderobject_idcounter++; this->glctx->glShaderSourceARB(this->shaderHandle, 1, (const COIN_GLchar **)&srcStr, NULL); this->glctx->glCompileShaderARB(this->shaderHandle); if (SoGLSLShaderObject::didOpenGLErrorOccur("SoGLSLShaderObject::load()")) { this->shaderHandle = 0; return; } this->glctx->glGetObjectParameterivARB(this->shaderHandle, GL_OBJECT_COMPILE_STATUS_ARB, &flag); //---------------------------- Исправление if (!flag) { SoGLSLShaderObject::printInfoLog(this->GLContext(), this->shaderHandle, this->getShaderType()); this->shaderHandle = 0; } //----------------------------- }

Метки:

#UPD: Упс, таблицу стилей перепутал. Вот эти стили подключать надо.

Мне не удалось найти готового решения для подсветки синтаксиса, интегрируемого в ЖЖ, поэтому была создана программа "BeCode, выполняющая обработку исходных кодов и подготовку их для помещения в блог.
Выбранное мной решение привело к небольшой проблеме, подсветка осуществляется только при наличии необходимых стилей, т.е. вне блога coin3d-ru код остаётся чёрно-белым.
Эта проблема лего устраняется, путём добавления необходимых стилей к текущему стилю вашего журнала. Это даже даёт некоторое преимущество, т.к. вы можете настроить отображение кода по своему усмотрению.

coin3d-ru.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34    /* classes for code highlight */ .sc_CodeHeader { color: #FFF; background-color: #666; font-weight: 700; font-size:12px; } .sc_LineNumber { color: #EEE; background-color: #AAA; padding-left: 5px; padding-right: 5px; } .sc_codeBlock { color: #000; background-color: #FFF; } .sc_kwrd { color: #00F; font-weight:bolder; } .sc_str { color: #C00; } .sc_macro { color: #900; } .sc_comment { color: #080; } .sc_direct { color: #00F; }
#UPD: Хм. Собрал версию 3.1.3 и опять не увидел теней. Вероятно, сам что-то поменял в настройках, а не в койне дело. Будем искать...

В репозитории появилась тестовая версия coin4. Обрадовался. Вроде всё работало даже, к счастью не успел уроки на четвёртую версию переделать.
Оказалось, что какая-то проблема с шейдерами там, разбираться не стал. К не релизным версиям не придираются.

Следующий файл содержит сцену с перемещающимися объектами, отбрасывающими динамические тени.
При открытии появятся диалоги, сообщающие об удачной компиляции каждого шейдера.

Это дурацкая ошибка библиотеки, исправление которой я опишу позже (разработчикам я про неё тоже написал, жду их реакции).

Чтобы открыть этот файл, нужно собрать загрузчик сцен из предыдущего урока.
Как это не печально, но открыв сцену в coin4 теней я не увидел.
P.S.: Убедитесь, что перед "#Inventor V2.1 ascii" нет пробелов. Это должна быть первая строка файла.

shadow.iv
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49     #Inventor V2.1 ascii # to get some lighting when headlight is turned off in the viewer DirectionalLight { direction 0 0 -1 intensity 0.2 } ShadowGroup { quality 1 # to get per pixel lighting ShadowStyle { style NO_SHADOWING } SpotLight { location -8 -8 8.0 direction 1 1 -1 cutOffAngle 0.35 dropOffRate 0.7 } ShadowStyle { style CASTS_SHADOW_AND_SHADOWED } Separator { Complexity { value 1.0 } Material { diffuseColor 1 1 0 specularColor 1 1 1 shininess 0.9 } Shuttle { translation0 -3 1 0 translation1 3 -5 0 speed 0.25 on TRUE } Translation { translation -5 0 2 } Sphere { radius 2.0 } } Separator { Material { diffuseColor 1 0 0 specularColor 1 1 1 shininess 0.9 } Shuttle { translation0 0 -5 0 translation1 0 5 0 speed 0.15 on TRUE } Translation { translation 0 0 -3 } Cube { depth 1.8 } } Separator { Material { diffuseColor 0 1 0 specularColor 1 1 1 shininess 0.9 } Shuttle { translation0 -5 0 0 translation1 5 0 0 speed 0.3 on TRUE } Translation { translation 0 0 -3 } Cube { } } ShadowStyle { style SHADOWED } Coordinate3 { point [ -10 -10 -3, 10 -10 -3, 10 10 -3, -10 10 -3 ] } Material { specularColor 1 1 1 shininess 0.9 } Complexity { textureQuality 0.1 } Texture2 { image 2 2 3 0xffffff 0x225588 0x225588 0xffffff } Texture2Transform { scaleFactor 4 4 } FaceSet { numVertices 4 } }

auto ptr

При использовании библиотеки coin3d интенсивно используется динамическое создание объектов, при этом запрещено непосредственное объектов посредством вызова деструктора, т.е. создание объектов графа-сцены в стеке невозможно.
Удаление объектов происходит аналогично COM-объектам. В каждом объекта реализован интрузивный счётчик ссылок, при каждом добавлении объекта в граф-сцену счётчик ссылок увеличивается, при изымании объекта или удалении граф-сцены счётчик уменьшается. При обнулении счётчика объект удаляется.
Это создаёт небольшую проблему: велика возможность утечек памяти, если в процессе построения граф-сцены случится что-то неожиданное. Чтобы хоть как-то уменьшить эту проблему я написал аналог класса std::auto_ptr, но для объектов граф-сцены.
Для упрощения создания объектов, не требуется явная передача указателя на динамически созданный объект. По умолчанию, автоматически конструируется объект заданного типа. При явной передаче указателя на управление, указатель может быть указанного типа или любого дочернего типа.

SoAutoPtr.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64    #pragma once /** auto ptr Пример использования: SoAutoPtr<SoSeparator> sep; SoAutoPtr<SoCube> cube; sep->addChild( cube ); */ template< class T> class SoAutoPtr { public: /*explicit*/ SoAutoPtr( T * ptr = 0 ) : _ptr(ptr) { if( !_ptr ) _ptr = new T; _ptr->ref(); } SoAutoPtr( const SoAutoPtr & rhs ) { _ptr = rhs._ptr; _ptr->ref(); } SoAutoPtr & operator = ( const SoAutoPtr & rhs ) { if( _ptr ) _ptr->unref(); _ptr = rhs._ptr; _ptr->ref(); return *this; } ~SoAutoPtr() { if( _ptr ) _ptr->unref(); } T * operator -> () const { return _ptr; } operator T* () { return _ptr; } T* Release() { _ptr->unrefNoDelete(); T* result = _ptr; _ptr = 0; return result; } private: T * _ptr; };
Небольшая функция, позволяющая выгружать в файл части графа или весь граф полностью, для последующей его загрузки и использования.

saver.cpp
1 2 3 4 5 6 7 8 9 10 11    #include <Inventor/SoOutput.h> #include <Inventor/actions/SoWriteAction.h> void Save( const char * fileName, SoNode * root ) { SoOutput output; output.openFile( fileName ); SoWriteAction wa( &output ); wa.apply( root ); }

SoInput - Загрузчик сцен

В библиотеке Coin3D есть возможность сохранения и последующей загрузки граф-сцены, полностью или частично.
Для загрузки используется объект класса SoInput и статические функции класса SoDB.
Для сохранения используется объект класса SoOutput.

В этом примере создаётся утилита для просмотра сохранённых граф-сцен. На её примере можно разобраться, как происходит загрузка граф-сцены из файла и последующая работа с загруженной граф-сценой.
Как видно из кода, это не консольное, а оконное MFC приложение.

Loader.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47    #define VC_EXTRALEAN #include <afxext.h> #include <Inventor/Win/SoWin.h> #include <Inventor/Win/viewers/SoWinExaminerViewer.h> #include <Inventor/nodes/SoSeparator.h> #include <Inventor/SoInput.h> class CLoaderApp : public CWinApp { public: virtual BOOL InitInstance() { CWinApp::InitInstance(); while(true) { if( IDYES != AfxMessageBox( _T("Load next Inventor file?"), MB_YESNO) ) break; CFileDialog dlg( TRUE, _T(".iv"), NULL, 0, _T("OI Files (*.iv)|*.iv||") ); if( IDOK != dlg.DoModal() ) break; const CStringA fullPath( dlg.GetPathName() ); HWND wnd = SoWin::init( "Viewer" ); SoInput input; input.openFile( fullPath.GetString() ); SoSeparator * root = SoDB::readAll( &input ); SoWinExaminerViewer * viewer = new SoWinExaminerViewer(wnd ); viewer->setSceneGraph( root ); viewer->setSize( SbVec2s(800, 600) ); viewer->show(); SoWin::mainLoop(); }; return FALSE; } }; CLoaderApp theApp

Меценатам

Поддержать проект
ЯндексЯндекс. ДеньгиХочу такую же кнопку

Метки

Разработано LiveJournal.com
Designed by Tiffany Chow