aboutsummaryrefslogtreecommitdiff
path: root/modules/render/render_osg_model.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/render/render_osg_model.cpp')
-rw-r--r--modules/render/render_osg_model.cpp342
1 files changed, 342 insertions, 0 deletions
diff --git a/modules/render/render_osg_model.cpp b/modules/render/render_osg_model.cpp
new file mode 100644
index 0000000..4062fed
--- /dev/null
+++ b/modules/render/render_osg_model.cpp
@@ -0,0 +1,342 @@
+/*
+ * render_osg_model.cpp - represents renderable things by model
+ *
+ * Copyright (c) 2018 Intel Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Author: Zong Wei <wei.zong@intel.com>
+ */
+
+#include "render_osg_model.h"
+
+#include <iostream>
+#include <string>
+
+#include <osg/MatrixTransform>
+#include <osg/Texture2D>
+#include <osgDB/ReadFile>
+
+namespace XCam {
+
+RenderOsgModel::RenderOsgModel (const char *name, uint32_t width, uint32_t height)
+ : _name (NULL)
+ , _model (NULL)
+ , _geode (NULL)
+ , _program (NULL)
+ , _texture (NULL)
+{
+ XCAM_LOG_DEBUG ("RenderOsgModel width(%d), height(%d) ", width, height);
+ XCAM_ASSERT (name);
+ if (name)
+ _name = strndup (name, XCAM_MAX_STR_SIZE);
+
+ _model = new osg::Group ();
+ _geode = new osg::Geode ();
+
+ _texture = create_texture (width, height);
+ if (_texture.get ()) {
+ add_texture (_texture);
+ }
+}
+
+RenderOsgModel::RenderOsgModel (const char *name, bool from_file)
+ : _name (NULL)
+ , _model (NULL)
+ , _geode (NULL)
+ , _program (NULL)
+ , _texture (NULL)
+{
+ XCAM_LOG_DEBUG ("RenderOsgModel model name (%s) ", name);
+ XCAM_ASSERT (name);
+ if (name)
+ _name = strndup (name, XCAM_MAX_STR_SIZE);
+
+ _model = new osg::Group ();
+ _geode = new osg::Geode ();
+
+ if (from_file && NULL != _geode.get ()) {
+ osg::ref_ptr<osg::Node> node = create_model_from_file (name);
+ _geode->addChild (node);
+ }
+}
+
+RenderOsgModel::~RenderOsgModel ()
+{
+ if (_name)
+ xcam_free (_name);
+}
+
+osg::Node*
+RenderOsgModel::create_model_from_file (const char *name)
+{
+ XCAM_LOG_DEBUG ("Invailide node name %s", name);
+ if (name == NULL) {
+ return NULL;
+ }
+
+ osg::ref_ptr<osg::Node> node = osgDB::readNodeFile (name);
+ if (NULL == node.get ()) {
+ XCAM_LOG_ERROR ("Read node file FAILD!!! node name %s", name);
+ }
+
+ return node.release();
+}
+
+void
+RenderOsgModel::append_model (SmartPtr<RenderOsgModel> &child_model)
+{
+ osg::ref_ptr<osg::Group> model = get_model ();
+
+ if (NULL == model.get () || NULL == child_model.ptr ()) {
+ XCAM_LOG_ERROR ("Append child model ERROR!! NULL model !!");
+ return;
+ }
+
+ model->addChild (child_model->get_model ());
+}
+
+void
+RenderOsgModel::append_geode (SmartPtr<RenderOsgModel> &child_model)
+{
+ osg::ref_ptr<osg::Group> model = get_model ();
+
+ if (NULL == model.get () || NULL == child_model.ptr ()) {
+ XCAM_LOG_ERROR ("Append child geode ERROR!! NULL model !!");
+ return;
+ }
+
+ model->addChild (child_model->get_geode ());
+}
+
+XCamReturn
+RenderOsgModel::setup_shader_program (
+ const char *name,
+ osg::Shader::Type type,
+ const char *source_text)
+{
+ XCAM_LOG_DEBUG ("setup shader program name(%s), type(%d)", name, type);
+ XCamReturn result = XCAM_RETURN_NO_ERROR;
+
+ if (NULL == _program.get ()) {
+ _program = new osg::Program ();
+ _program->setName (name);
+ }
+
+ _program->addShader (new osg::Shader (type, source_text));
+
+ _model->getOrCreateStateSet ()->setAttributeAndModes (_program, osg::StateAttribute::ON);
+ _model->getOrCreateStateSet ()->setMode (GL_DEPTH_TEST, osg::StateAttribute::ON);
+
+ return result;
+}
+
+XCamReturn
+RenderOsgModel::setup_vertex_model (
+ BowlModel::VertexMap &vertices,
+ BowlModel::PointMap &points,
+ BowlModel::IndexVector &indices,
+ float a,
+ float b,
+ float c)
+{
+ XCamReturn result = XCAM_RETURN_NO_ERROR;
+
+ osg::ref_ptr<osg::Group> model = get_model ();
+ osg::ref_ptr<osg::Geode> geode = get_geode ();
+ osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry ();
+
+ geode->addDrawable (geometry);
+ geometry->setUseVertexBufferObjects (true);
+
+ osg::ref_ptr<osg::Vec3Array> vertex_array = new osg::Vec3Array ();
+ osg::ref_ptr<osg::Vec2Array> tex_coord_array = new osg::Vec2Array ();
+ osg::ref_ptr<osg::DrawElementsUInt> index_array = new osg::DrawElementsUInt (GL_TRIANGLE_STRIP, 0);
+
+ osg::ref_ptr<osg::Vec3Array> normal_array = new osg::Vec3Array ();
+ osg::ref_ptr<osg::Vec4Array> color_array = new osg::Vec4Array ();
+
+ normal_array->push_back (osg::Vec3 (0, -1, 0));
+ geometry->setNormalArray (normal_array);
+ geometry->setNormalBinding (osg::Geometry::BIND_OVERALL);
+
+ color_array->push_back (osg::Vec4 (1.0, 0.0, 0.0, 1.0));
+ geometry->setColorArray (color_array);
+ geometry->setColorBinding (osg::Geometry::BIND_OVERALL);
+
+ for (uint32_t idx = 0; idx < vertices.size (); idx++) {
+ vertex_array->push_back (
+ osg::Vec3f (vertices[idx].x * a,
+ vertices[idx].y * b,
+ vertices[idx].z * c));
+ }
+
+ for (uint32_t idx = 0; idx < points.size (); idx++) {
+ tex_coord_array->push_back (osg::Vec2f (points[idx].x, points[idx].y));
+ }
+
+ for (uint32_t idx = 0; idx < indices.size (); idx++) {
+ index_array->push_back (indices[idx]);
+ }
+
+ geometry->setVertexArray (vertex_array.get ());
+
+ if (points.size () > 0) {
+ geometry->setTexCoordArray (0, tex_coord_array.get ());
+ }
+
+ if (indices.size () > 0) {
+ geometry->addPrimitiveSet (index_array.get ());
+ } else {
+ geometry->addPrimitiveSet (new osg::DrawArrays (GL_TRIANGLE_FAN, 0, 4));
+ }
+
+ model->addChild (geode);
+
+ return result;
+}
+
+XCamReturn
+RenderOsgModel::setup_model_matrix (
+ float translation_x,
+ float translation_y,
+ float translation_z,
+ float rotation_x,
+ float rotation_y,
+ float rotation_z,
+ float rotation_degrees)
+{
+ XCamReturn result = XCAM_RETURN_NO_ERROR;
+
+ osg::ref_ptr<osg::Group> model = get_model ();
+ osg::ref_ptr<osg::Geode> geode = get_geode ();
+
+ const osg::Vec3f axis(rotation_x, rotation_y, rotation_z);
+ osg::ref_ptr<osg::MatrixTransform> mat = new osg::MatrixTransform ();
+ mat->setMatrix (osg::Matrix::scale (osg::Vec3 (1.0, 1.0, 1.0)) *
+ osg::Matrix::rotate ((rotation_degrees / 180.f) * osg::PI_2, axis) *
+ osg::Matrix::translate (osg::Vec3 (translation_x, translation_y, translation_z)));
+
+ mat->addChild (geode);
+ model->addChild (mat);
+
+ return result;
+}
+
+XCamReturn
+RenderOsgModel::update_texture (SmartPtr<VideoBuffer> &buffer)
+{
+ XCamReturn result = XCAM_RETURN_NO_ERROR;
+
+ XCAM_LOG_DEBUG ("RenderOsgModel::update_texture ");
+
+ if (NULL == _texture.get ()) {
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ {
+ SmartLock locker (_mutex);
+
+ VideoBufferInfo info = buffer->get_video_info ();
+ uint32_t image_width = info.width;
+ uint32_t image_height = info.height;
+
+ osg::ref_ptr<osg::Image> image_y = new osg::Image ();
+ osg::ref_ptr<osg::Image> image_uv = new osg::Image ();
+
+ uint8_t* image_buffer = buffer->map ();
+ if (NULL == image_buffer) {
+ XCAM_LOG_ERROR ("buffer map return NULL!!");
+ result = XCAM_RETURN_ERROR_MEM;
+ } else {
+ uint8_t* src_y = image_buffer;
+ uint8_t* src_uv = image_buffer + image_width * image_height;
+
+ image_y->setImage (image_width, image_height, 1,
+ GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE,
+ src_y, osg::Image::NO_DELETE);
+
+ image_uv->setImage (image_width / 2, image_height / 2, 1,
+ GL_LUMINANCE, GL_RG, GL_UNSIGNED_BYTE,
+ src_uv, osg::Image::NO_DELETE);
+
+ _texture->_texture_y->setImage (image_y);
+ _texture->_texture_uv->setImage (image_uv);
+ }
+ //buffer->unmap ();
+ }
+
+ return result;
+}
+
+NV12Texture*
+RenderOsgModel::create_texture (uint32_t width, uint32_t height)
+{
+ osg::ref_ptr<NV12Texture> nv12 = new NV12Texture (width, height);
+
+ nv12->_texture_y = new osg::Texture2D ();
+ nv12->_texture_y->setImage (new osg::Image ());
+
+ nv12->_texture_y->setInternalFormat (GL_LUMINANCE);
+ nv12->_texture_y->setResizeNonPowerOfTwoHint (false);
+ nv12->_texture_y->setNumMipmapLevels (0);
+ nv12->_texture_y->setFilter (osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
+ nv12->_texture_y->setFilter (osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
+ nv12->_texture_y->setWrap (osg::Texture::WRAP_S, osg::Texture::CLAMP);
+ nv12->_texture_y->setWrap (osg::Texture::WRAP_T, osg::Texture::CLAMP);
+
+ nv12->_texture_y->setTextureWidth (width);
+ nv12->_texture_y->setTextureHeight (height);
+
+ nv12->_texture_uv = new osg::Texture2D ();
+ nv12->_texture_uv->setImage (new osg::Image ());
+
+ nv12->_texture_uv->setInternalFormat (GL_RG);
+ nv12->_texture_uv->setResizeNonPowerOfTwoHint (false);
+ nv12->_texture_uv->setNumMipmapLevels (0);
+ nv12->_texture_uv->setFilter (osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
+ nv12->_texture_uv->setFilter (osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
+ nv12->_texture_uv->setWrap (osg::Texture::WRAP_S, osg::Texture::CLAMP);
+ nv12->_texture_uv->setWrap (osg::Texture::WRAP_T, osg::Texture::CLAMP);
+
+ nv12->_texture_uv->setTextureWidth (width / 2);
+ nv12->_texture_uv->setTextureHeight (height / 2);
+
+ return nv12.release ();
+}
+
+XCamReturn
+RenderOsgModel::add_texture (osg::ref_ptr<NV12Texture> &texture)
+{
+ XCamReturn result = XCAM_RETURN_NO_ERROR;
+
+ osg::ref_ptr<osg::Group> model = get_model ();
+
+ if (NULL == model.get () || NULL == _texture.get ()) {
+ return XCAM_RETURN_ERROR_PARAM;
+ }
+
+ model->getOrCreateStateSet()->setTextureAttribute(0, texture->_texture_y.get ());
+ texture->_uniform_y = new osg::Uniform (osg::Uniform::SAMPLER_2D, "textureY");
+ texture->_uniform_y->set (0);
+ model->getOrCreateStateSet ()->addUniform (texture->_uniform_y.get ());
+
+ model->getOrCreateStateSet ()->setTextureAttribute (1, texture->_texture_uv.get ());
+ texture->_uniform_uv = new osg::Uniform (osg::Uniform::SAMPLER_2D, "textureUV");
+ texture->_uniform_uv->set (1);
+ model->getOrCreateStateSet ()->addUniform (texture->_uniform_uv.get ());
+
+ return result;
+}
+
+} // namespace XCam