2009年7月10日星期五

why to learn OpenGL?

有点无聊,于是打开了之前收藏的关于opengl tutorials的链接。既然是tutorial嘛,当然很多都是初步介绍怎么使用api等一些基础,于是有点烦。

就想,为什么要学OpenGL呢?
1. 通过学OpenGL来了解Graphics/Rendering Pipeline.
例如在看Essential Mathematics for Grames and Interactive Application时候,那些Transformation, lighting, framebufffer等概念以及计算方式,
要是结合OpenGL的Api,那些原理对应什么api,能达到什么效果,这感觉多好啊。
例如在3D Game Engine Design, second edition时候,那个software render engine,要是结合原理一起看,那估计就深刻了。

2. OpenGL是基础招式,例如C/C++的语法掌握,在此基础上可以去学习很多更复杂的算法、框架和系统等。
例如http://www.paulsprojects.net/opengl/projects1.html这上面就很多特效算法,当然不是为了某几个特别的例子啦,
我估计从它们中可以了解到一类的特效,甚至做一个特效系统,然后特效算法估计也涉及其它更广阔的知识面。

glext; glew, glee这些library的原理

下面就是glext为我们做的事:
(1), 根据显卡厂商对某个extension的具体说明来定义一些宏.
#define GL_ARRAY_BUFFER_ARB 0x8892 //具体的地址是在各个specification中定义的.
#define GL_STATIC_DRAW_ARB 0x88E4

(2), 声明一些函数指针的类型.
typedef void (APIENTRY * PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer);
typedef void (APIENTRY * PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers);
typedef void (APIENTRY * PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers);
typedef void (APIENTRY * PFNGLBUFFERDATAARBPROC) (GLenum target, int size, const GLvoid *data, GLenum usage);

然后在我自己的实现中就需要做以下的事:
(3). 声明定义一些函数指针:
PFNGLGENBUFFERSARBPROC glGenBuffersARB = NULL;
PFNGLBINDBUFFERARBPROC glBindBufferARB = NULL;
PFNGLBUFFERDATAARBPROC glBufferDataARB = NULL;
PFNGLDELETEBUFFERSARBPROC glDeleteBuffersARB = NULL;

(4). 利用wglGetProcAddress函数取得各个函数的地址指针.
glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB");
而其实在glATI.h, wglATI.h, ATIExtensions.h, and ATIExtensions.c中也是这么做的.

那些glew, glee就将上面4步都给我们做了.

所以当使用extensions时候,
要么是下载glext回来,自己提供源代码实现(3, 4)两步.
要么是直接用glew or glee.

2009年7月9日星期四

opengl32.dll--Windows系统下OpenGL的实现和扩展

Windows, OpenGL Versions, and Extensions
这是在http://www.gamedev.net/ 上看到的文章, 这里转帖一下:
Something I've noticed any number of times is that many people are quite vague on how OpenGL works on Windows. This causes a lot of confusion about exactly what the limitations on Windows are with respect to versions, and people tend to say things that don't make sense. The most common misunderstanding is that Windows is limited to OpenGL 1.1. It's time to clear things up.
First, let's start by dissecting the basic OpenGL architecture on Windows. When you build your OpenGL based program, you link to opengl32.lib. This file from the Platform SDK is a companion to the opengl32.dll that ships with Windows. The GL/gl.h header you use matches these two files. When your code runs, some behind the scenes work happens that loads up the functions out of opengl32.dll. However, opengl32.dll is a purely software implementation of OpenGL 1.1, and it's probably not what you want to be using. What you want to be using is the real OpenGL DLL, for example nvoglnt.dll. This file is installed with your video driver.
This is where magic starts to happen. Your calls to opengl32.dll will be redirected to the actual driver specific DLL, which exports at least all the functions in opengl32.dll. The trick is, it also exports a lot more than that. The entire OpenGL API for the version that it supports will be exported, along with all the extensions. Calls to wglGetProcAddress become GetProcAddress calls on the OpenGL DLL that came from the driver. This isn't limited to extensions; you can use it on regular non-extension functions as long as the video driver supports a version of OpenGL that includes them.
The problem here is that, depending on the manufacturer of your video driver and the version, the real DLL that implements OpenGL could be anywhere. Windows provides opengl32.dll as a common place to go to, instead of having to figure out what DLL you need at runtime. That DLL also servves the dual purpose of providing the basic software implementation. That's why it's nearly never been updated; adding new OpenGL functions would mean writing code to implement all of that in software. In Vista they decided to provide a new version built on D3D instead of software, so applications using the Vista headers and libraries can get a baseline of OpenGL 1.4 statically.
All that an extension loader does, then, is to automate the tedious process of making the dozens or hundreds of GetProcAddress calls to retrieve the functions that aren't statically linked and forwarded. Again, these functions don't have to be extensions. You can wglGetProcAddress for glMapBuffer, not just glMapBufferARB. There's no question of what Windows supports. It doesn't matter. The only function you actually need from Windows is wglGetProcAddress, which is your key to accessing the real OpenGL DLL. The rest of the interface is just a convenience in that you don't have to go out and get the addresses for the OpenGL 1.1 functions, since they're already being redirected for you. And since modern extension loaders are machine generated systems that automatically look up everything, it's less relevant than ever before.

2009年7月8日星期三

Reading note - memory management

book1: Memory as a Programming concept in c and c++ 已经打印了.
book2: c++ pointers and dynamic menory management. Michael C. Daconta.

Memory location: a container that can store a binary number.
Address: a unique binary number assigned to every memory location. 特别的二进制数。
Pointer: a memory location that stores an address
Variable:a named memory location that can store a value of certain data type..[book2 chapter2]

There is absolutely no difference in functionality between pointers and references. The difference is that with references, the compiler handles the details of passing pointers and dereferencing them instead of you doing it yourself.
1. A reference is an alias for a variable, is not an object, while a pointer is an object. An object has two main attributes: its storage class and its type. The storage class determines the lifetime of this chunk of storage, while the type determines the meaning of values found in the object.
2. References exist only in the compiler and not after compilation. They have symbol table entries only.
3. 初始化时候要给出初值,除了在class中是在初始化列表中的,不能做数学操作.

Array name, is a label, the label of the first address, is not the same as a pointer.

Three memory spaces: [book1,2]
1. global: for global variables(函数之外没有被static关键字的, 函数之内有static关键字的,类声明中static的variables), allocated at compile.
2. stack: activation frame when a function is called, the local automatic variables.
3. free store: binary heap(system heap or free store) at os level keeped by os memory management, dynamic list of free segments at process level keeped by process memory manager.[book1 chapter4].

malloc/new.
malloc 自己用sizeof觉得分配的字节数,返回的是void*,分配得到的空间之内是垃圾数据;
而new在这三方面都有所不同。

Pass by value: cope the variable's content to the activation frame(function stack).
Pass by reference: cope the variable's address to the activation frame.

在datastructure中找linklist的笔记, 也涉及pointer的使用, 学会画图来表示, 32bit里面是variable的地址呢,还是pointer的地址呢?这就是一级pointer和二级pointer的区别
特别是那个push(struct node *head, int data)的为什么错了, 而需要改成push(struct node **head, int data)?
一定要学着画图, 并且结合以下的概念,
函数传递struct node,那么是将整个structure copy一份到被调用函数的activation frame;
如果函数传递的是struct node*,那么是将structure的地址,也就是指针本身的context copy一份到被调用函数的activation frame;
如果函数传递的是struct node**,那么是将指针本身的address copy一份到被调用函数的activation frame, 这样就修改到指针本身了.

intel relative

英特尔® 软件网络 那个blog的页面上看出来intel的确是在做multi-core的,相对于nvidia的GPGPU.

2009年6月16日星期二

memory management in c/c++, resources

1. book, Memory as a Programming Concept in C and C++.
2. book, 程序员的自我修养—链接、装载与库, 第10 章 内存.
3. C++ Memory Management: From Fear to Triumph, 3parts.

http://www.gowrikumar.com/c/
http://wangcong.org/blog/?p=291 西邮 Redhat Beijing
http://www.matrix67.com/blog/archives/429 重庆的 顾森88年, 这天才好像读北大中文系(2007.9开始),PKU的ACM貌似对他没难度,估计也是高中就天才那种,信息学奥赛,http://www.matrix67.com/blog/archives/319
http://cuitianyi.com 89年高中就acm获奖数学天才,保送ZJU的CS,貌似他们跟楼天成是类似的人物,高手都是在初高中就很出名了,。基础数学-> CS. http://cuitianyi.com/blog/category/life/page/5/,http://cuitianyi.com/blog/%e5%9c%a8%e9%83%91%e5%b7%9e/, : 离散数学,组合数学,数学分析...文理都优秀,在他们的圈子里面很活跃,但估计也有疑惑的时候。:大量,很大量的阅读经典的文史著作和数学著作,算法,编程。:距离一般人有点远,甚至例如家庭条件等就不允许,但是只是程度和轨迹不一样的啦,阅读文史,算法编程还是可以和应该做的。

2009年4月25日星期六

Nvidia widgets (gui)

目录结构:

extern/glew
/glut

src/nvglutils/nvShaderUtils.h // dependent on glew
/nvwidgets/nvGlutWidgets.cpp, nvGlutWidgets.h // dependent on glut
/nvwidgets/nvGLWidgets.cpp, nvGLWidgets.h // dependent on opengl
/nvwidgets/nvWidgets.cpp, nvWidgets.h
/examples/example.cpp

类结构:
nvWidgets.h, class UIPainter and class UIContext.

GLWidgets.h, class GLUIPainter: public UIPainter {
//implement all the virtual functions of the base class,
//to draw ui elements with OpenGL.
GLUIPainter();
begin(const Rect &window);
end();
drawXXXX(...);
...
init();//compile and like shaders. invoked by begin(...) function.
};

class UIContext {
//This class is ready for use, but use the GlutUIContext as adaptor.
UIContext( UIPainter& painter ); // use painter(GLUIPainter) to draw UI.
reshape(int w, int h);
isOnFocus();
mouse(int button, int state, ...);
keyboard(unsigned char k, int x, int y);

begin(); //m_painter->begin(m_window);
end(); //m_painter->end();
doLabel(...);// use the painter to drawLabel;
doButton(...);// use the painter to drawButton;
...

UIPainter *m_painter;
Rect m_window;
Point m_currentCursor;
ButtonState m_mouseButton[3];
unsigned char m_keyBuffer[32];
....
};

GlutWidgets.h, class GlutUIContext: public UIContext {
// As an adaptor for GLUT,
GlutUIContext():UIContext(*(new GLUIPainter())), m_ownPainter(true) {}
GlutUIContext(UIPainter &painter):UIContext(painter), m_ownPainter(false) {}
init(); // invoke glewInit();
mouse(int button, int state, int x, int y); //translate the Glut mouse to nvWidgets mouse.
specialKeyboard(int k, int x, int y);
};

小结:
(1)一个负责底层draw UI的类UIPainter,用OpenGL做底层API的话就实现一个GLUIPainter,如果用DirectX做渲染的话就实现一个DXUIPainter.
这个类被UIContext调用。
(2)一个负责管理窗口的UIContext类,工作包括记录自己的windows(大小位置等),响应keyboard/mouse的输入,对用UIPainter来画UI.
提供了GlutUIContex作为adapter,是否也可以实现Win32UIContext, QtUIContext.
(3)这个nvwidgets目的只是在glut提供的窗口上用OpenGL来画出UI和相应这些UI,
like the author of this project said, it is suitable for small dome.
假如是在Win32上实现,不知是否类似。
假如是在Qt上实现,Qt好像是提供class QPainter to render 2D widgets.
(4)另外,貌似提供的example占用99%CPU.
原来可能是:
static void idle()
{
glutPostRedisplay();
}
glutIdleFunc(idle);
When the application is idle(not responding to event), it refresh constantly(also often used to implement animation).

Email from the author:

That's expected. nvwidgets processes the input and draws the screen
simultaneously. It was designed for real-time applications that are
constantly redrawing the screen, so in those cases that was not an
issue.

This however is one of the main complains people have; there's an
issue already open about it:

http://code.google.com/p/nvidia-widgets/issues/detail?id=1

the IMGUI forums also discuss this issue and propose solutions:

https://mollyrocket.com/forums/viewforum.php?f=10

A simple workaround is not to refresh the screen constantly, but limit
it to 60 or 30 Hz. That can be achieved with WaitableTimers. See the
comment section of the following article:

http://cbloomrants.blogspot.com/2009/03/03-02-09-sleep-sucks-and-vsync-woes.html
另外涉及的link including:
http://meshula.net/wordpress/?p=189
http://www.gamedev.net/community/forums/topic.asp?topic_id=445787&whichpage=2?

问题包括:
(4.1) 游戏shot CPU usage to 100%是否合适? 意见包括对于real-time application来说,this 's not an issue. 反面意见是, the computer's fans roar like a vacuum cleaner. Power consumption. Expecially for a loptop.
(4.2) 如果不想要100%usage, then not to refresh the screen constantly, but limit it to a framerate 60 or 30 Hz. But how? using timer, 方法一般是:
Use a timer to record the time at which you started rendering the current frame. Add 1/120th of a second to that, and you know when the next frame should start.
Once you've finished rendering the current frame, you take the current time, and check how far it is from the "next frame" time we computed.
Then you call Sleep(int) with the time difference.
同样地在上面提到的cbloomrants.blogspot.com那个link中有伪代码.

但是好像windows上的Sleep() is a huge disaster, it's not exact.

(5) What is IMGUI?
https://mollyrocket.com/forums/viewforum.php?f=10
http://sol.gfxile.net/imgui/
http://sol.gfxile.net/files/Assembly07_IMGUI.pdf

2009年3月26日星期四

Graphics Engine Architeture

2009-03-26

1. when i was trying to implement one paper and see how it work, most of the time, i use glut. Actually, the framework with trackball function in Meshcourse07 and Nvidia OpenGL SDK 10.5 is good enough to meet my this simple need.

2. 但是当设计的模块多了之后,之前简单的在一个framework中mix了数据和显示这方面会显得极为混乱.
例如有一个Bezier Curves class, only deal with the data and operators cared by the curve itself.
还有一个是复杂显示的RenderDevice class, wrapper for opengl commands and rendering engine.
为了做到两者可以互不相关,
需要提供一个中间的协调者:
#include "BezierCurve"
#include "RenderDevice"
class Whatever {
BezierCurve *;
render(RenderDevice *) {}
controlBezier(UserInput *) { // call the functions fo BezierCurves }
...
};

3. 更复杂的还设计GUI widgets模块,windows窗口模块等,这些还需要继续了解。现在正在看G3D graphics engine的实现.


> 09-04-17




1. The first is "Essential mathematics for games and interactive applications".

2. The second one is related to the "Wild Magic Game Engine", the third 貌似不是关于技术的,虽然其作者的 G3D Graphic Engine 很吸引。

>2009-5-29 OpenGL Windows GUI Application MVC框架,multi-thread, 结合opengl来讲,很好。But, still call the gl command in the Model part, what to do is the data in the Model needed to be render ?

2009年3月23日星期一

有用的文章链接

Better, smaller and faster random number generator

Using Namespaces Properly 减少namespace冲突的几率.
C++ Without Memory Errors :garbage collection, reference count, small pointer.
Smart Pointer Thread Safety

Minimum Distance between a Point and a Line
Minimum Distance between a Point and a Plane

Some thoughts on the compute shader and the future So what's separating a GPU from a CPU? The difference is in how it approaches long latency operations, in particular memory accesses. Cpu use a large mount of caches, while Gpu use multi-thread. what is a thread is Gpu? ....

Gaussian Blur Experiments
Fixing Pathfinding Once and For All

2009年3月5日星期四

Curve Bezier Patch, Tessellation

Main Point is:
输入: 给出一个初始的原始网格(一般是比较coarse的啦,否则就没有必要进行tessellation了)。
过程:微观上,对网格的中每一个面face(可能是triangle or quad),生成一个对应的控制面片,宏观上,这个原始网格就得到一个对应的控制网格了。
输出:上面生成的控制网格,要是看做是control points for bezier patches, then 给出参数坐标(u,v)不就对应于bezier patch上的某一个点了吗?整个控制网格得到的整个bezier曲面因此起到逼近approximate一开始作为输入的那个原始网格的效果。

难点在于怎么求控制网格/控制点,使得最好的patches直接能smooth, C1/G1。以及跟新的gpu pileline结合起来。

PN Triangles:

实现上本来很简单,但是我之前竟然弄了个很严重的错误,就是先求了原是网格的Loop limit surface再对这求PN。得到的PN triangle应该是interpolate原始网格的。
Reference:A.Vlachos, J.Peters, etc. Curved PN Triangles, 2001.
之后的工作还包括:怎么改善连续性,怎么加入sharp features,怎么扩展到triangle-quads等。详细的内容请google。


Tamy Boubekeur 的主页上继Scalar tagged PN, QAS, Subdivision Shading, Phong Tessellation之后又有新东西了,Realtime tessellation, 好像是他在这方面工作的一个总结,期待当中。
update 2009-05-10, quadratic-approximation-of-subdivision

Approximate Subdivision Shading 这篇文章提供了三方面的信息。1. 评论Subdivision Shading工作, 2. 将Subdivision Shading的方法跟下面将要提到的ACC结合起来,文中没有说得太仔细,但是我估计是在得到ACC的geometry patch之后,再求geometry patch上每一个顶点的normal(其one-ring faces的normals的avarage), 不需要求tangent patch了当然,在对geometry patch做evaluation的时候,同时对其上面的normals也做相同的evaluation。3. to achieve watertight surfaces when using displacement maps。


C. Loop & S. Schaefer的Approximation Catmull-Clark Subdivision surfaces with Bicubic Patches[ACC], 2007/2008. 现在的确比上面提到的PN, QAS都要热,一方面是因为现在DirectX11上新加入的tessellation功能. C. Loop本来就在Ms工作,估计这个ACC工作本来就跟D11的开发相结合的。 相关的连接(1).Tessellation of Displaced Subdivision Surfaces in DX11 (2).Siggraph 2008: Next-Generation Rendering of Subdivision Surfaces

ACC上面没有考虑到sharp features, 因此有了Real-time creased Approximatie subdivision surfaces,2009.
10 Fun Things to do with Tessellation Hardware tessellation这个new tool有什么好玩的功能呢? 看看这个文章啦:-)
[Mar 26,09 update]虽然比Nvidia慢,但是ATI/AMD终于就在HW上实现ACC了 "OpenGL Tessellation Samples", 看来ACC真的太hot了,刚下载了demo来编译运行, 可惜我的RV380(Radeon X600)不支持。另外,因为ACC的实现需要one-ring neighborhood的信息,而在GPU中怎么能看到一个primitive vertex/face的邻域信息呢,并且还是在pipeline的前段,在vertex unpacked之前?


http://www.cise.ufl.edu/research/SurfLab/pubs.shtml 其中一个做细分曲面做得最好的实验室,上面N多好papers。而其中就有1, Smooth surfaces from 4-sided facets 2008; 2. Fast Paralled construction of smooth surfaces for meshes with tri/quad/poly 2008等和就网格生成smooth的Bezier patches并用GPU加速相关的工作。


当然在Tessellation得到bezier patches之后,可以在上面使用normal mapping, displacement mapping等来加添显示效果。
另外这里涉及一个watertightness的问题,怎么样使得相邻的patches之间不出现缝隙,这个倒没有深究。

2009年3月3日星期二

Unified subdiviaion schemes based on the Sqrt2 subdivision operator

刚完成了相关的工作并submit了,希望有个好的结果啦。

我是January从Dr. Li那里接手这个工作的,当时刚完成了approximation of Loop subdivision surfaces的工作,开始时候怎么也看不懂,因为涉及到了box-spline,而我对b-spline也都一头雾水,去google这个什么box-spline,download下来的paper都是公式公式,唯一的收获还是“可惜自己不是数学系的”。但是也不想问老师,因为听老师说会上手得快很多,但是像吃饭,一口下去吞了也就吞了,什么味道都不知道呢。于是,一直拖到寒假,晚上在家里看看,推推导,画画图,慢慢竟然有点feel了。之后,就coding,一切都顺利,使得我以为也不着急。但是到了2月中旬,发现需要在3.1号之前搞定,马上进入crease features的处理,于是,意料之外的痛苦开始了……

two weeks以后,工作完了,文章submit了,虽然还是不知道什么是box-spline,但是貌似效果还不错的:


Main References:
1. on subdivision schemes generalizing uniform b-spline surfaces of arbitrary degree. J.Stam. 2001.
2. Composite sqrt2 subdivision surfaces. Guiqing Li and W. Ma. 2006/2007.