V-world open source project

Source: Internet
Author: User
Document directory
  • 1.1 V-World lib
  • 1.2 vwviewer
  • 1.3 open source license
  • 1.4 Third-Party Libraries
  • 1.5 join the project
  • 2.1 compile
  • 2.2 run
  • 3.1 create an application project
  • 3.2 configure an application project
  • 3.5 create scene nodes using scene map-related classes
  • 3.6 ry
  • 3.7 complete instance

By yurunsun@gmail.com
Sina Weibo @ sun yurun Sina Blog
Csdn blog

Date:

1. Project Overview 1.1 V-World lib

V-World Lib is a high-performance 3D graphics library implemented by opengl1.1. It is used to quickly develop interactive 3D graphics applications in Windows operating systems.

The main features are as follows:

  • Mathematical libraries such as vectors, tuples, and Matrices
  • Basic elements and model file elements
  • Scenario diagram composed of geometric nodes, lighting nodes, camera nodes, and group nodes
  • Encapsulation drawing and form
  • Separation of interfaces and implementations for ease of use
  • Reference count management memory
1.2 vwviewer

As a sample application, vwviewer uses v-world lib to implement a 3D model viewer that supports multiple formats.

1.3 open source license

All of the above items comply with the GNU Public License (lgpl): Allow Dynamic Links in commercial applications.

1.4 Third-Party Libraries
  • Use lib3ds to process 3DS files

  • Use GLM to process OBJ files

  • Wtl helps process Win32 APIs

1.5 join the project
  • Project home: https://code.google.com/p/v-world/

  • SVN: https://v-world.googlecode.com/svn/trunk/

  • Submit bugs or want to join please contact: yurunsun@gmail.com

2. Compile and run 2.1.
  • Install vs2010 (except for Express, because it does not contain templates such as ATL)

  • Go to the wtl project homepage or go to the checkout wtl Template Library: SVN: // svn.code.sf.net/p/wtl/code/

  • Open the wtl project directory of checkout and\wtl\trunk\wtl\include\Copy all the header files under the directory to the Microsoft SDK header file directory created when installing vs2010, for example:

    D:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\atlmfc\include\
  • Open with vs2010VirtualWorld.sln, Compile

2.2 run

The target files compiled in debug and release modes are placed in\BinDebug\And\BinRelease\Directory. Virtualworld. dll is V-World Lib, and vwviewer.exe is the sample program developed using the V-World Library: 3D model viewer.

3. Use v-world lib to develop graphics software

The following uses vwviewer as an example to describe how to use v-world lib to develop interactive graphics software.

3.1 create an application project

V-World lib providesCWindowWindow classes of the base class can be independently displayed as frame-style Windows, and can also be easily embedded into windows generated by any framework such as MFC, wtl, ATL, Win32, and Qt as subwindows, therefore, the type of the application is very free. In vwviewer, we use the vs plug-in of wtl to automatically generate a frame-style main window with a menu bar.

3.2 configure an application project
  • Add header file

    One of the features of v-world Lib is the separation from interfaces. Only one header file (plus the. INL file provides inline function implementation) and one library file are required. The header file defines the required interface classes. Except for some getter/setter functions that provide efficient inline implementation, all others use pure virtual functions as interfaces.

    Go to the application project configuration page and choose configuration Properties> VC ++ directories> include directories.

    Add

    ..\VirtualWorld\Include;
  • Add library files

    We recommend that you use v-world as a dynamic link. During compilation, there are two methods to find the function address of the dynamic link library. One is to display and use the function address in the code.LoadLibraryThe other is the. Lib file generated by the link with the dynamic link library. (Note that the. lib here only exists to find the DLL address. Do not confuse it with the static link method .) We select the latter method:

    Go to the application project configuration page and choose configuration Properties> VC ++ directories> library directories.

    Add

    ..\VirtualWorld\BinDebug

    For the release configuration, change

    ..\VirtualWorld\BinRelease;

    Then

    Choose application project configuration> Configuration Properties> linkder> Input

    AddVirtualWorld.lib

Next open..\VirtualWorld\Include\VirtualWorld.hFile to view the available class libraries.

3.3 Use Factory CFactoryCreate an instance
namespace VirtualWorld {    class VIRTUALWORLD_API CFactory         : public CSingleton<CFactory>    {    public:        IWindow32*                  CreateWindow32();        //...    };}

Most classes defined in the header file need to use the factory class to create instances, which is a common mode for separating interfaces.

On the other hand, the existence of the factory class as a singleton is also a conventional model.

For example, to create an iwindow32 object:

IWindow32* pView = VirtualWorld::CFactory::GetInstance()->CreateWindow32();
3.4 use window class IWindow32Create window

Readers who are familiar with Win32 APIs will find thatIWindow32Some Windows-style function interfaces are defined, because v-world Lib is not prepared for cross-platform.

Method:

  • CreateWin(...): In comparison with the standard Win32 APICreateWindowThe function has the same parameters.

  • GetHwnd(): Get window handle

  • RedrawWin(...): In comparison with the standard Win32 APIRedrawWindowThe function has the same parameters.

  • PreTranslateMessage(...): MFC-style message preprocessing functions

Attribute:

  • RootSGNode: Root Node of the scenario diagram (for more information)

  • ActiveCameraNode: Activated cameras (coming soon)

  • GUIEventHandler: Gui Event Callback interface (coming soon)

Specific applications:

  1. Add iwindow32 as a member in the main window class generated by wtl:

    VirtualWorld::IWindow32*    m_pView;
  2. In the main window class generated by wtlWM_CREATEResponse FunctionsOnCreateCreate a subwindow:

    m_pView = pFac->CreateWindow32();m_hWndClient = m_pView->CreateWin(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);m_pView->SetGUIEventHandler(this);

Now we have successfully called the iwindow32 API in v-world to create a subwindow.

3.5 use the scenario diagram-related class to create the scenario node 3.5.1 concept of the scenario Diagram

InIWindow32The interface mentions two functions for accessing the graph root node of the scenario. The following describes the related concepts of the scenario graph.

In terms of data structure, a scenario is a dag, called scene graph, or SG for short. The scenario is drawn to traverse each node of SG. Nodes are divided into group nodes and leaf nodes. The following pseudocode shows a possible and reasonable call order:

// Here is my own leafnode * myself = new leafnode; // There is a car on the left, a dog, leafnode * car = new leafnode; leafnode * dog = new leafnode; groupnode * leftside = new groupnode; leftside-> addchild (CAR); leftside-> addchild (DOG); // There is a playground and football leafnode * football = new leafnode in the distance; leafnode * grassland = new leafnode; groupnode * Faraway = new groupnode; faraway-> addchild (Football); faraway-> addchild (grassland ); // figure groupnode * root = new groupnode; root-> addchild (leftside); root-> addchild (faraway ); root-> addchild (myself );
3.5.2 node base class ISceneBaseNode

This class is the base class for all scenario nodes.

Attribute:

  • Name: node name
  • Parent: parent node pointer
  • Nodetype: Node Type
  • Nodetypestring: node type of the string version
  • Visibility: visible
  • Localmatrix: transformation matrix in the Local Coordinate System
  • Worldmatrix: transformation matrix in the world coordinate system

The local coordinate system is initially a 4*4 unit matrix. The transformation matrix under the world coordinate system is equivalent to the transformation matrix under the world coordinate system of the parent node, multiplied by the transformation matrix under the Local Coordinate System:

this->WorldMatrix = parent->WorldMatrix * this->LocalMatrix

Note that the node is stored in the map container provided by its parent node as the key. Therefore, all nodes must have names. Otherwise, they cannot be attached to the parent node.

Method:

Translate(const CVector3f& t);Rotate(float angle, const CVector3f& axis);Scale(const CVector3f& axis);

It indicates the translation, rotation, and scaling of the node in the local coordinate system. The actual effect is directly applied to the local coordinate transformation matrix of the current node. Example:

Initially, the node's local coordinate transformation matrix L = I is the unit matrix. when moving to the (1.0f, 2.0f, 3.0f) position, create the displacement matrix T:

    1 0 0 0T = 0 1 0 0    0 0 1 0    1 2 3 1

In this case

L = L * T = I * T;

Perform the following scaling along the XYZ axis (2.0f, 5.0f, 0.5f), that is, 2 times the X axis, 5 times the Y axis, and 0.5 times the original Z axis, then create the scaling matrix R

    2 0 0 0R = 0 5 0 0    0 0 0.5 0    0 0 0 1

In this case

L = L * R = I * T * R
3.5.3 group nodes ISceneGroupNode

BesidesISceneBaseNodeIn addition to the provided attributes and methods, the system is mainly responsible for managing subnodes:

typedef std::map<CString, ISceneBaseNode*> NodeTable;void AddChild(ISceneBaseNode* a_Child);ISceneBaseNode* GetChild(const CString& a_Name) const;const NodeTable& GetChildren() const;void RemoveChild(ISceneBaseNode* a_Child);void RemoveChild(const CString& a_Name);

Using map to manage subnodes is one of the classic modes.

3.5.4 metanode ISceneGeometryNode

BesidesISceneBaseNodeIn addition to the provided attributes and methodsGeometryObjectAttribute to attach an element to an element node.GeometryObjectWill be introduced later.

3.5.5 illumination nodes ISceneLightNode

DivisionISceneBaseNodeIn addition to the property method provided, the following lighting attributes are added:

ID;Ambient;Diffuse;Specular;Position;SpotDirection;SpotExponent;SpotCutoff;Attenuation;

These are classic lighting parameters. For more information, see the graphic tutorial.

3.5.6 camera nodes ISceneCameraNode

The new attributes are as follows:

Fovy;ZNear;ZFar;Rect;

These are classic parameters for adjusting the angle of view, cropping the plane, and the size of the view.

Add method:

The new method in cameranode has some special features:

void LookAt(const CVector3f& a_Position, const CVector3f& a_FocusPoint, const CVector3f& a_UpVector);

This is the DivisionISceneBaseNodeIn addition to the three affine transformations provided in, another function that can act on the transformation matrix, readers familiar with OpenGL will immediately find that this function is similar to the classic

gluLookAt(...);

HereLookAtModifiedLocalMatrixTo complete the coordinate system transformation.

3.5.7 Add the camera node to the root node

Readers who have played the game know that there are multiple perspectives in the game. For example, when the first person perspective is in a csgame, the camera obviously needs to move with the character node. In this case, it is reasonable to use the camera node and the metanode as the subnode. However, when the game goes down, CS allows you to use a free angle of view. In this case, you do not have to add the camera node to the scene graph, so that you can easily change the camera in the world coordinate system.

At any time, there can only be one activated camera. That's whyIWindow32ProvidedActiveCameraAttribute.

3.6 ry

In 3.5.4, we mentioned the usage of metadata nodes.GeometryObjectAttribute as a ry, in turn eachGeometryObjectMust be attachedISceneGeometryNodeNodes appear in the scenario diagram.

3.6.1 IGeometryBaseObject

The base class of all ry graphics classes.

Attribute:

  • DrawMode: Draw a graph by filling or contour
  • NormalMode: Vertex normal or surface normal
  • GetBoundingBox: Box
  • Material: Materials
3.6.2 common images

Similar to databases such as Glu, glut, and qgl, the basic graph is provided here:

  • IGeometryCubeObject: Cube
  • IGeometrySphereObject: Sphere
  • IGeometryCylinderObject: Cylinder
3.6.3 obtain images from model files

IGeometryModelObjectThe new method is

bool LoadModel(const CString& a_FileName);

When you use the factory function to create this instance, different instances are created based on the file type (. OBJ,. 3DS,. Dae,. 3 dxml,..., etc. Call example:

CString modelType = CUtility::GetFileSuffix(a_FilePath);IGeometryModelObject* objModel = CFactory::GetInstance()->CreateGeometryModelObject(modelType);if (objModel != NULL) {    bool hr = objModel->LoadModel(a_FilePath);    if (hr == true)  {        //...    }}

Currently, OBJ and 3DS files are supported.

3.7 complete instance

The following is the sample code for calling V-model in vwviewer. For the complete code, seeMainFrm.cpp.

LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/){    CFactory* pFac = CFactory::GetInstance();    m_pView = pFac->CreateWindow32();    m_hWndClient = m_pView->CreateWin(m_hWnd, rcDefault, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_CLIENTEDGE);    m_pView->SetGUIEventHandler(this);    m_pCameraDlg = new CCameraDlg();    m_pCameraDlg->Create(m_hWnd);    m_pNodetreeDlg = new CNodetreeDlg();    m_pNodetreeDlg->Create(m_hWnd);    ISceneGroupNode* rootNode = pFac->CreateSceneGroupNode();    ISceneCameraNode* cameraNode = pFac->CreateSceneCameraNode();    ISceneGeometryNode* cubeNode = pFac->CreateSceneGeometryNode();    ISceneGeometryNode* sphereNode = pFac->CreateSceneGeometryNode();    ISceneGeometryNode* cylinderNode = pFac->CreateSceneGeometryNode();    ISceneLightNode* lightNode = pFac->CreateSceneLightNode();    IGeometryCubeObject* cubeObj = pFac->CreateGeometryBoxObject();    IGeometrySphereObject* sphereObj = pFac->CreateGeometrySphereObject();    IGeometryCylinderObject* cylinderObj = pFac->CreateGeometryCylinderObject();    IMaterial* material = pFac->CreateMaterial();    material->SetAmbient(CVector4f(0.000f, 0.50f, 0.000f, 1.0f));    material->SetDiffuse(CVector4f(0.000f, 0.300f, 0.000f, 1.0f));    material->SetSpecular(CVector4f(1.000f, 1.000f, 1.000f, 1.0f));    material->SetEmmision(CVector4f(0.000f, 0.000f, 0.000f, 1.0f));    material->SetShine(128.000f);    cubeObj->SetMaterial(material);    cubeObj->SetRadius(0.3f);    cubeObj->SetDrawMode(IGeometryBaseObject::GEOMETRY_DRAW_SOLID);    cubeNode->SetName(_T("Box1"));    cubeNode->SetGeometryObject(cubeObj);    cubeNode->Translate(CVector3f(1.0f, 0.0f, 0.0f));    rootNode->AddChild(cubeNode);    sphereObj->SetMaterial(material);    sphereObj->SetRadius(0.4f);    sphereObj->SetDrawMode(IGeometryBaseObject::GEOMETRY_DRAW_SOLID);    sphereObj->SetNormalMode(IGeometryBaseObject::GEOMETRY_NORMAL_VERTEX);    sphereNode->SetName(_T("Sphere1"));    sphereNode->SetGeometryObject(sphereObj);    sphereNode->Translate(CVector3f(-1.0f, 0.0f, 0.0f));    rootNode->AddChild(sphereNode);    cylinderObj->SetMaterial(material);    cylinderObj->SetDrawMode(IGeometryBaseObject::GEOMETRY_DRAW_SOLID);    cylinderObj->SetNormalMode(IGeometryBaseObject::GEOMETRY_NORMAL_VERTEX);    cylinderObj->SetBaseRadius(0.3f);    cylinderNode->SetName(_T("Cylinder1"));    cylinderNode->SetGeometryObject(cylinderObj);    cylinderNode->Translate(CVector3f(0.0f, 0.0f, -1.0f));    cylinderNode->Rotate(0.1f, CVector3f(1.0f, 0.0f, 0.0f));    rootNode->AddChild(cylinderNode);    lightNode->SetName(_T("light0"));    lightNode->SetAmbient(CVector4f(0.4f, 0.4f, 0.4f, 1.0f));    lightNode->SetPosition(CVector4f(-1.0f, -1.0f, 1.0f, 0.0f));    rootNode->AddChild(lightNode);    cameraNode->SetName(_T("Camera"));    cameraNode->SetFovy(30.0f);    cameraNode->SetZNear(1.0f);    cameraNode->SetZFar(1000.0f);    cameraNode->Translate(CVector3f(0.0f, 0.0f, 5.0f));    rootNode->SetName(_T("Root"));    m_pView->SetActiveCameraNode(cameraNode);    m_pView->SetRootSGNode(rootNode);    // register object for message filtering and idle updates    CMessageLoop* pLoop = _Module.GetMessageLoop();    ATLASSERT(pLoop != NULL);    pLoop->AddMessageFilter(this);    pLoop->AddIdleHandler(this);    return 0;}
4. Architecture Design of V-Model

The V-model is logically divided into four layers:

  • Mathematics
  • Graphics
  • Node
  • Window Type

Among them, the mathematics class includes cvector3, cvector4, and cmatrix, which contains a large number of mathematical operations;

Some of the graphics classes provide basic graphics and some are used to load model files. During rendering, the display list Technology in opengl1.1 is used to improve rendering efficiency;

The node logic clearly organizes the scenario and simplifies the world coordinate system, local coordinate system, and affine transformation that are prone to errors into a parent-child relationship;

The window class encapsulates windows Windows, organizes root nodes and cameras, and provides GUI Event Callback interfaces.

Generally, users can use V-model to quickly process 3D model files and organize scenarios for rendering. Interested readers can apply to join this project, expand the Supported file formats, and modify bugs; for vwviewer, you are also welcome to join us with creative ideas about this product.

  • If this article is helpful to you, please go to the csdn blog to leave a message;
  • Reprinted Please note: From yurun technology blog http://blog.csdn.net/sunyurun

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.