Saturday, June 25, 2016

frustum.culling.clipping.

Cited

OpenGL Projection Matrix

(http://www.songho.ca/)


...
[OverView]

Therefore, we have to keep in mind that both clipping (frustum culling) and NDC transformations are integrated into GL_PROJECTION matrix. The following sections describe how to build the projection matrix from 6 parameters: left, right, bottom, top, near, and far boundary values...

Node that the frustum culling (clipping) is performed in the clip coordinates, just before dividing by Wc.  The clip coordinates, Xc, Yc, and Zc are tested by comparing with Wc. If any clip coordinate is less than -Wc, OR greater than +Wc, then the VERTEX will be discarded.   [(-Wc) <   Xc, Yc, Zc  <  (+Wc)]
A triangle clipped by frustum


Then, OpenGL will reconstruct the edges of the polygon where clipping occurs..

...
[Perspective Projection]
Perspective Frustum and Normalized Device Coordinates (NDC)
In perspective projection, a 3D point in a truncated pyramid frustum (eye coordinates) is mapped to a cube (NDC); the range of x-coordinate from [Left, Right] to [-1, +1], the y-coordinate from [Bottom, Top] to [-1, +1], and the z-coordinate from [Near, Far] to [-1, +1]..

Node that the eye coordinates are defined in the Right-Handed coordinate system, but NDC uses the Left-Handed coordinate system. That is, the Camera at the origin is looking along (-Z axis in eye space), but it is looking along (+Z axis in NDC).. Since glFrustum() accepts only  positive values of -near- and -far- distances, we need to negate them during the construction of GL_PROJECTION matrix.....

....

























Friday, June 24, 2016

explicit.key.word

Cited 

:http://stackoverflow.com/

:http://en.cppreference.com/

What does the explicit keyword in C++ mean?

[00]

The explicit specifier specifies that a constructor or conversion function (since C++11) doesn't allow implicit conversions or copy-initialization. It may only appear within the decl-specifier-seq of the declaration of such a function within its class definition.

Notes

A constructor with a single non-default parameter (until C++11) that is declared without the function specifier explicit is called a converting constructor.
Both constructors (other than copy/move) and user-defined conversion functions may be function templates; the meaning of explicit doesn't change.

struct A
{
    A(int) { }      // converting constructor
    A(int, int) { } // converting constructor (C++11)
    operator bool() const { return true; }
};
 
struct B
{
    explicit B(int) { }
    explicit B(int, int) { }
    explicit operator bool() const { return true; }
};
 
int main()
{
    A a1 = 1;      // OK: copy-initialization selects A::A(int)
    A a2(2);       // OK: direct-initialization selects A::A(int)
    A a3 {4, 5};   // OK: direct-list-initialization selects A::A(int, int)
    A a4 = {4, 5}; // OK: copy-list-initialization selects A::A(int, int)
    A a5 = (A)1;   // OK: explicit cast performs static_cast
    if (a1) break; // OK: A::operator bool()
    bool na1 = a1; // OK: copy-initialization selects A::operator bool()
    bool na2 = static_cast<bool>(a1); // OK: static_cast performs direct-initialization
 
//  B b1 = 1;      // error: copy-initialization does not consider B::B(int)
    B b2(2);       // OK: direct-initialization selects B::B(int)
    B b3 {4, 5};   // OK: direct-list-initialization selects B::B(int, int)
//  B b4 = {4, 5}; // error: copy-list-initialization does not consider B::B(int,int)
    B b5 = (B)1;   // OK: explicit cast performs static_cast
    if (b1) break; // OK: B::operator bool()
//  bool nb1 = b2; // error: copy-initialization does not consider B::operator bool()
    bool nb2 = static_cast<bool>(b2); // OK: static_cast performs direct-initialization
}

[00]

In C++, the compiler is allowed to make one implicit conversion to resolve the parameters to a function. What this means is that the compiler can use constructors callable with a single parameterto convert from one type to another in order to get the right type for a parameter. Here's an example class with a constructor that can be used for implicit conversions:
class Foo
{
public:
  // single parameter constructor, can be used as an implicit conversion
  Foo (int foo) : m_foo (foo) 
  {
  }

  int GetFoo () { return m_foo; }

private:
  int m_foo;
};
Here's a simple function that takes a Foo object:
void DoBar (Foo foo)
{
  int i = foo.GetFoo ();
}
and here's where the DoBar function is called.
int main ()
{
  DoBar (42);
}
The parameter is not a Foo object, but an int. However, there exists a constructor for Foo that takes an int so this constructor can be used to convert the parameter to the correct type.
The compiler is allowed to do this once for each parameter.
Prefixing the explicit keyword to the constructor prevents the compiler from using that constructor for implicit conversions. Adding it to the above class will create a compiler error at the function call DoBar (42). It is now necessary to call for conversion explicitly with DoBar (Foo (42))
The reason you might want to do this is to avoid accidental construction that can hide bugs. Contrived example:
  • You have a MyString(int size) class with a constructor that constructs a string of the given size. You have a function print(const MyString&), and you call it with print(3). You expect it to print "3", but it prints an empty string of length 3 instead.


[01]

Suppose you have a class String:
class String {
public:
    String(int n); // allocate n bytes to the String object
    String(const char *p); // initializes object with char *p
};
Now if you try
String mystring = 'x';
the char 'x' will be implicitly converted to int and then will call the String(int) constructor. But this is not what the user might have intended. So to prevent such conditions, we shall define the constructor as explicit:
class String {
public:
    explicit String (int n); //allocate n bytes
    String(const char *p); // initialize sobject with string p
};

[02]

In C++, a constructor with only one required parameter is considered an implicit conversion function. It converts the parameter type to the class type. Whether this is a good thing or not depends on the semantics of the constructor.
For example, if you have a string class with constructor String(const char* s), that's probably exactly what you want. You can pass a const char* to a function expecting a String, and the compiler will automatically construct a temporary String object for you.
On the other hand, if you have a buffer class whose constructor Buffer(int size) takes the size of the buffer in bytes, you probably don't want the compiler to quietly turn ints into Buffers. To prevent that, you declare the constructor with the explicit keyword:
class Buffer { explicit Buffer(int size); ... }
That way,
void useBuffer(Buffer& buf);
useBuffer(4);
becomes a compile-time error. If you want to pass a temporary Buffer object, you have to do so explicitly:
useBuffer(Buffer(4));
In summary, if your single-parameter constructor converts the parameter into an object of your class, you probably don't want to use the explicit keyword. But if you have a constructor that simply happens to take a single parameter, you should declare it as explicit to prevent the compiler from surprising you with unexpected conversions.
....




Tuesday, June 21, 2016

Plane.Signed.Distance

Cited

http://www.lighthouse3d.com/tutorials/maths/plane/


A 3D plane can be defined in many ways, however all of them can be derived from the simple case where we have three points.
One of the most common ways to define a plane is with the following equation:
     Ax + By + Cz + D = 0
Assuming three points p0p1, and p2 the coefficients A, B, C and D can be computed as follows:
  • Compute vectors v = p1 – p0, and u = p2 – p0;
  • Compute n = v x u (cross product)
  • Normalize n
  • Assuming n = (xn,yn,zn) is the normalized normal vector then
    • A = xn
    • B = yn
    • C = zn
  • To compute the value of D we just use the equation above, hence -D = Ax + By + Cz. Replacing (x,y,z) for a point in the plane (for instance p0), we get D = – n . p0 (dot product).
The following figure presents all the intervenients in this process.


Distance from a point to a plane
Assuming that the equation Ax + By + Cz + D = 0 has been obtained as shown above then the distance from the plane to a point r(rx,ry,rz) can be obtained just by computing the left side of equation, or
    dist = A*rx + B*ry + C*rz + D = n . r  + D
Actually the distance is the absolute value of dist, but the sign of dist (if it is zero is on the plane) also gives information as to which side of the plane is point r. If the sign is positive then the point is on the side that agrees with the normal n, otherwise it is on the other side.
A curious fact is that when we consider the distance from the plane to the origin, the distance is D.
Projecting a point to a plane
The projection of a point q on a plane defined by Ax + By + Cz + D = 0 is the point on the plane that is closest to q.
Assume that dist is the signed distance from q to the plane. Then the closest point p on the plane is:
    p = q - dist * n

Monday, June 20, 2016

extern.global.variable

-----------------------------------------------------
//FILE##global.h
extern Texture2D* gpTerrainTexture;

//FILE##global.cpp
#include "global.h"
Texture2D * gpTerrainTexture = new gpTerrainTexture;

//FILE##HeightMapSourceImage.h
#include "Texture2D.h"
class HeightMapSourceImage
{
public:
HeightMapSourceImage(Texture2D*& terrainTexture)
:_terrainTexture(terrainTexture)
{
gpTerrainTexture;//why error C2065 occurs?
}
private:
Texture2D * _terrainTexture;
};

// if there is a HeightMapSourceImage.cpp implementation and reference to gpTerrainTexture,
// then the error C2065 disappears.
----------------------------------------------------------

Sunday, June 19, 2016

Reference_&_Pointer

Q?
-----------------
-------------------------------------------------
//FILE##Component.h
#include "Transform"
class Component
{
// implementation with reference
public:
Component(Transform& transform):_transform(transform){}
Transform& GetRefTransform(){return _transform;}
private:
Transform _transform;
// implementation with pointer
public:
Component(Transform* transform):_ptransform(transform){}
Transform* GetPtrTransform(){return _ptransform;}
private:
Transform * _ptransform;
}

//FILE##Camera.h
class Camera : public Component
{
public:
Camera(Transform& transform):Component(transform){}
public:
Camera(Transform* ptransform):Component(ptransform){}
}

//FILE##FreeCamera.h
class FreeCamera: public Component
{
public:
FreeCamera(Transform& transform):Component(transform){}
public:
FreeCamera(Transform* ptransform):Component(ptransform){}
}

//FILE##main.cpp
{// why failed to use the same attribtue _transform inherited from the base_class in this way????
Transform transform;
transform.GetPosition().SetPosition(Vector3(x,y,z));
Camera* mainCamera = new Camera(transform);
// some operation about mainCamera
FreeCamera* freeCamera = new FreeCamera(transform);
}
{// while this is okay..
Transform * ptransform = new ptransform();
ptransform->GetPosition().SetPosition(Vector3(x,y,z));
Camera * pMaincamera = new Camera(ptransform);
// operations on pMaincamera
FreeCamera * pFreeCamera = new FreeCamera(ptransform);
}


--------------------------------

Sunday, June 12, 2016

View Frustum Culling

cited tutorial


In order to perform view frustum culling, two steps are required:
  • Extract the frustum volume information - this has to be done every time the frustum changes, i.e., when the camera moves or when the perspective changes 
  • Test the objects against the frustum's volume to determine whether to cull or not - this has to be performed for every object in every frame. If the culling status of each object is kept from frame to frame then the test itself may be done only when the camera moves, i.e. when the frustum is updated or perspective changes.

BoundingFrustum

Cited

        Tutorial


a BoundingFrustum can be created based on a Projection_Matrix.
such as class BoundingFrustum followed below.

The goal of view frustum culling is therefore to be able to identify what is inside the frustum (totally or partially), and cull everything that is not inside. Only the stuff that is inside the frustum is sent to the graphics hardware.




_____________________________________

__________________
__________________
class BoundingFrustum


 public: Plane _plane[6]; 
 BoundingFrustum(){} 
 BoundingFrustum(const Matrix4x4& matrix){}
 ~BoundingFrustum(){}
 void CalculateFromMatrix(const Matrix4x4& matrix)
 {
   //[0]-left
   //[1]-right
   //[2]-top
   //[3]-bottom
   //[4]-near
   //[5]-far
 }
};

Friday, June 10, 2016

Level Of Detail...LOD...CDLOD Algorithm

Cited
http://www.insaneunity.com/blog/tag/cdlod/


In a 3D game, each image is calculated from a scene consisting of triangles. 
A graphics card can process and display a fixed number of triangles/ps. 
The purpose of the management of LEVEL of DETAIL (or LOD) is to reduce the number of triangles to be processed in order to optimize the display time of each image.




Tuesday, June 7, 2016

Vertex Format

Cited Officialhttps://www.opengl.org/wiki/Vertex_Specification


Vertex Format


The glVertexAttribPointer​ functions state where an attribute index gets its array data from. But it also defines how OpenGL should interpret that data. Thus, these functions conceptually do two things: set the buffer object information on where the data comes from and define the format of that data.

The format parameters describe how to interpret a single vertex of information from the array. Vertex Attributes in the Vertex Shader can be declared as a floating-point GLSL type (such as float​ or vec4​), an integral type (such as uint​ or ivec3​), or a double-precision type (such as double​ or dvec4​). Double-precision attributes are only available in OpenGL 4.1 or ARB_vertex_attrib_64bit.

The general type of attribute used in the vertex shader must match the general type provided by the attribute array. This is governed by which glVertexAttribPointer​ function you use. For floating-point attributes, you must use glVertexAttribPointer​. For integer (both signed and unsigned), you must use glVertexAttribIPointer​. And for double-precision attributes, where available, you must useglVertexAttribLPointer​.

Each attribute index represents a vector of some type, from 1 to 4 components in length. The size​ parameter of the glVertexAttribPointer​ functions defines the number of components in the vector provided by the attribute array. It can be any number 1-4. Note that size​ does not have to exactly match the size used by the vertex shader. If the vertex shader has fewer components than the attribute provides, then the extras are ignored. If the vertex shader has more components than the array provides, the extras are given values from the vector (0, 0, 0, 1) for the missing XYZW components.

The latter is not true for double-precision inputs (OpenGL 4.1 or ARB_vertex_attrib_64bit). If the shader attribute has more components than the provided value, the extra components will have undefined values.



.
.