游戏开发论坛

 找回密码
 立即注册
搜索
楼主: jxk

请问OpenGL的投影平面--

[复制链接]

24

主题

110

帖子

110

积分

注册会员

Rank: 2

积分
110
发表于 2005-10-26 13:24:00 | 显示全部楼层

Re:请问OpenGL的投影平面--

D'Oh! I took a shower (always recommended when the brain is seized!) and I now get it. For some reason I'd got it into my head that the near plane was at z=0. Looking at the SuperBible again I see that I probably went off the track when I followed the advice of not bothering to figure out the glFrustum and use gluPerspective instead. The diagram for the gluPerspective is missing the all important '0' on the z-axis at the observer (it's there in the frustum diagram). (I should have remembered that by default the observer is at z=0 but there's a newbie for you!)

So the distance to the near plane from the observer is: (h/2)/ tan(fovy/2) ?

I might be misunderstanding you, but the distance to the near plane is just zNear.


Though again the perspective diagram is different from the frustum diagram as it shows the top of the near and far planes to be on the same plane as the observer whereas the frustum diagram shows the observer looking at the center of the planes. Is there a real difference?

Sounds like that diagram is misdrawn or misleading.

gluPersp creates a frustum that is symmetrical, whose apex is at the camera-space origin and whose near & far planes are perpendicular to and _centered on_ the camera-space z axis.

glFrustum can create any frustum that gluPersp can, but also lets you create asymmetrical frustums that simulate certain view-camera movements (shift/rise) in which the near & far planes are _not centered on_ the camera-space z-axis. But they still will be perpendicular to that axis (no tilt/swivel), and the apex still lies at the camera origin.

24

主题

110

帖子

110

积分

注册会员

Rank: 2

积分
110
发表于 2005-10-26 13:35:00 | 显示全部楼层

Re:请问OpenGL的投影平面--

同意dfq19 的说法,投影平面在哪没关系,,但是一定是平行与 near,和far 的,到时候 放大缩小就可以,,

1

主题

8

帖子

8

积分

新手上路

Rank: 1

积分
8
 楼主| 发表于 2005-10-26 14:47:00 | 显示全部楼层

Re:请问OpenGL的投影平面--

To hovers:我只是猜测在zNear处,但并不确定,你可有什么根据?
To huawenguang:在计算机图形学中,讲到透视投影的时候,涉及一点透视的定义,可以理解为:投影平面与一个坐标轴正交,与另外两个坐标轴平行.想必投影平面和投影中心对于透视投影是存在的;在数学上,除了用一个点和一个平面来定义透视投影,也许还是其它方式.
至于我的离谱的那一点想法,是在<<OpenGL编程指南>>(传说中的红宝书)的第三章第5节--变换的诊断中看到的,或许是我表达有误.这里请容许我作一下解释:
我在使用gluPerspctive()函数时,首先计算fovy的值,用tan(fovy/2) = (h/2)/distance;
(已知的只有物体的大小及其各顶点的世界坐标),aspect在我未定义Viewport的时候为了避免显示失真,用aspect = w/h计算.
To dfq19:我最终想得到空间物体投影到屏幕上的较为精确的坐标区域,这在三维数据场的体绘制中有很大作用.
To forcewall:谢谢.
To zhuyi8319:谢谢.

其实我用另外一种方式表示,大家可能更加明白:
有DitkCamera类如下:
#ifndef DITK_CAMERA_H
#define DITK_CAMERA_H

#include "DitkMatrix.h"

class DitkCamera
{
public:
        DitkCamera();

        //得到Camera中某点坐标在世界坐标中的坐标值
        //关于ViewMatrix矩阵:
        //它能够将世界坐标系中的点变换到Camera中
        void GetPosition(float& x, float& y, float& z)
        {
                x        =        this->m_InverseViewMatrix->ele[12];
                y        =        this->m_InverseViewMatrix->ele[13];
                z        =        this->m_InverseViewMatrix->ele[14];
        }
        void GetPosition(float x[3])
        {
                this->GetPosition(x[0],x[1],x[2]);
        }

        //获取Camera中焦点坐标
        void GetFocalPoint(float& x, float& y, float& z)
        {
                x        =        this->m_FocalPoint[0];
                y        =        this->m_FocalPoint[1];
                z        =        this->m_FocalPoint[2];
        }
        void GetFocalPoint(float f[3])
        {
                this->GetFocalPoint(f[0],f[1],f[2]);
        }
       
        //得到Camera的厚度,可以认为是其远近平面间的距离
        float GetThickness()
        {
                return this->m_Thickness;
        }

        int        IsParallelProjection()
        {
                return this->m_ParallelProjection;
        }

        //设置等效于OpenGL的一些与Camera相关的函数
        void LookAt(float eyex,float eyey,float eyez,float centerx,float centery,float centerz,float upx,float upy,float upz);
        void Ortho(float left,float right,float bottom,float top,float zNear,float zFar);
        void Frustum(float left,float right,float bottom,float top,float zNear,float zFar);
        void Perspective(float fovy,float aspect,float zNear,float zFar);

        void GetViewMatrix(DitkMatrix* m);
        void GetViewMatrix(float m[16]);
        void GetProjectionMatrix(DitkMatrix* m);
        void GetProjectionMatrix(float m[16]);
        void GetInverseOfViewMatrix(DitkMatrix* m);
        void GetInverseOfViewMatrix(float m[16]);
        void GetInverseOfProjectionMatrix(DitkMatrix* m);
        void GetInverseOfProjectionMatrix(float m[16]);

        //点在各种坐标系中的变换
        void        WorldToCamera(const float worldPoint[4], float cameraPoint[4]);
        void        WorldToView(const float worldPoint[4],float viewPoint[4]);
        void        CameraToView(const float cameraPoint[4],float viewPoint[4]);
        void        CameraToWorld(const float cameraPoint[4],float worldPoint[4]);
        void        ViewToWorld(const float viewPoint[4], float worldPoint[4]);
        void        ViewToCamera(const float viewPoint[4],float cameraPoint[4]);

protected:
        int m_ParallelProjection;
        float m_FocalPoint[3];
        float m_Thickness;

        //相关矩阵
        DitkMatrix        *m_ViewMatrix;                //世界坐标到观察坐标
        DitkMatrix        *m_ProjectionMatrix;                //观察坐标到投影坐标
        DitkMatrix        *m_InverseProjectionMatrix;        //投影坐标到观察坐标
        DitkMatrix        *m_InverseViewMatrix;                //观察坐标到世界坐标

        virtual ~DitkCamera();
       
private:
        DitkCamera(const DitkCamera&);
        DitkCamera& operator=(const DitkCamera& src);
};
我若调用gluPerspective()则会怎么样影响m_ViewMatrix和m_ProjectionMatrix?

再次感谢大家的热心---

2

主题

67

帖子

67

积分

注册会员

Rank: 2

积分
67
发表于 2005-10-26 15:51:00 | 显示全部楼层

Re: 请问OpenGL的投影平面--

感觉教科书上讲的图形输出流水线与OpenGL的关系就如同OSI七层结构与TCP/IP结构的关系一样,一个理论一个实现,不是什么都一一对应。

这方面感觉官方的red book和blue book说的也不是很详细,建议看一下Nate Robins的教程,里面有个projection的例子。

附件是Mesa 3D源代码中glu相关函数的实现代码,可以看看他们是怎么做的

为了不使M$灭绝OpenGL的阴谋得逞,都来支持一下,呵呵:)

sf_20051026155030.rar

3.5 KB, 下载次数:

5

主题

63

帖子

63

积分

注册会员

Rank: 2

积分
63
发表于 2005-10-26 16:15:00 | 显示全部楼层

Re:请问OpenGL的投影平面--

To dfq19:我最终想得到空间物体投影到屏幕上的较为精确的坐标区域,这在三维数据场的体绘制中有很大作用.
我靠,搞了半天不就是坐标变换么,modelview变换---投影变换---视口变换就可以得到3维空间某个点在屏幕上的位置.
vec4 pos=gl_ModeViewMatrix*gl_ProjectionMatrix*gl_Vertex;
这里gl_ModelViewMatrix是modelview矩阵,gl_projectionMatrix是投影矩阵,gl_vertex是顶点坐标
然后vec2 tmp=vec2(pos.x,pos.y)/pos.w
则tmp.x,tmp.y在-1到1之间
然后根据屏幕大小width和height,进行视口变换可以得到:
screenx=((tmp.x+1)/2)*width;screeny=((1-tmp.y)/2)*height;
这里假定视口函数是glViewPort(0,0,width,height)
如果看不懂就看一看那本书
稀里糊涂的问了这么一个问题,搞晕一大堆人

5

主题

63

帖子

63

积分

注册会员

Rank: 2

积分
63
发表于 2005-10-26 16:18:00 | 显示全部楼层

Re:请问OpenGL的投影平面--

如果是拾取,就逆向求取之

1

主题

8

帖子

8

积分

新手上路

Rank: 1

积分
8
 楼主| 发表于 2005-10-26 21:50:00 | 显示全部楼层

Re:请问OpenGL的投影平面--

forcewall,你提供的那个附件很有用,谢谢了
dfq,你讲的很仔细,也谢过了,不过我旨在求取gl_ModelViewMatrix和gl_projectionMatrix,
如你能提供相关方法,更是不胜感激--

5

主题

63

帖子

63

积分

注册会员

Rank: 2

积分
63
发表于 2005-10-26 22:08:00 | 显示全部楼层

Re:请问OpenGL的投影平面--

glGetFloatv 取得矩阵

24

主题

110

帖子

110

积分

注册会员

Rank: 2

积分
110
发表于 2005-10-27 12:21:00 | 显示全部楼层

Re:请问OpenGL的投影平面--

是啊,opengl 应该有个焦点的,,投影平面就在焦点那....焦点是可以任意定义的,

我那本engine书上是这样设置的
d=0.5*宽度*tan(fov/2);
我觉得有问题,应该是d=0.5*宽度 /tan(fov/2); 视角越大,焦距应该变小才对....大家认为呢,
opengl又是如何定义焦距的呢,,,看了 mesa的实现 ,也没找到,,,高手指点下...

24

主题

110

帖子

110

积分

注册会员

Rank: 2

积分
110
发表于 2005-10-27 12:24:00 | 显示全部楼层

Re:请问OpenGL的投影平面--

我喜欢把焦点设置为 1,透视变换 到屏幕坐标的时候再根据轴进行缩放
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-22 23:36

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表