opengl三维模型正交投影得到3幅图

chaochupin 2011-08-12 09:50:40
现在opengl能展示三维模型,也找到提取三维模型图片的函数,但是无法设置视角,调整得到三幅图片。我首先把模型放在坐标原点,但是glReadPixels只能显示坐标原点以下的模型,不能显示整个模型。求助。
...全文
370 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
chaochupin 2011-08-14
  • 打赏
  • 举报
回复
谢谢你了,我现在根据你提供的思路先做做看。
ri_aje 2011-08-14
  • 打赏
  • 举报
回复
OpenGL没有内建的专门的函数执行你想要的功能,但它提供了实现你需求所需要的一切功能。你需要把这些零散底层的功能组装起来,来实现你自己的需求。具体而言,就是,
(1) 用 glOrtho 或 gluOrtho2D 设置好正交投影。
(2) 设置好模型,利用 glRotate 旋转模型,使得模型位置与摄像机位置形成的向量垂直于 XOY,具体怎么旋转,与你模型的设置有直接关系,我不知道你的模型是什么,所以没法说到底应该用什么旋转参数。
(3) 都设置好了以后,渲染模型一次。这时候 framebuffer 里存储的图片就是模型 XOY 方向的正交投影。
(4) 用与主楼意图相同但行为正确的函数把 framebuffer 中的内存读到主内存,并存储。
(5) 跳到 (2),施加不同的旋转,渲染 YOZ 和 ZOX 对应的图片。
chaochupin 2011-08-14
  • 打赏
  • 举报
回复
我可能没有表达清楚,我再重述一遍。我的任务就是能得到一个三维模型的XOY,XOZ,YOZ三个平面的投影,然后我想到用场景保存试试。在网上搜了一些代码,可用的就是上面的代码。不过用此代码只能得到任意方向的投影,就不会是正交方向的,所以我不知道该怎么设置抓取正交的图片。
ri_aje 2011-08-13
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 chaochupin 的回复:]

抓取的图片是不是和GL_VIEWPORT有关,而又是
glGetIntegerv(GL_VIEWPORT,pView);这个函数控制?
[/Quote]
There are many factors that can affect glReadPixels and the effect that you are after. To get an XOY, YOZ and XOZ projection, you probably want to use glOrtho or gluOrtho2D to set up an orthographic projection and then render the scene from positive x, y and z directions respectively, which is most graphics softwares doing.

That said, you used the word "投影" in your original post. I am not sure I got it exactly. There seems to be at least another way to understand your saying, i.e., you want to get a shadow projected from your model onto one of the axis planes. If that were the case, however, an even more contrived strategy must be employed. You'd better make yourself clear before any further discussions.
ri_aje 2011-08-12
  • 打赏
  • 举报
回复
有代码吗?glReadPixels 的具体参数是什么?
eye_119_eye 2011-08-12
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 ri_aje 的回复:]

有看了一下你下面的代码,感觉整个逻辑都是混乱的。这里
C/C++ code

int **p=new int *[row];
for (int i=0;i<row;i++)
{
p[i]=new int[col];
}


分配的内存明显不够,因为每个像素有三个通道。这里
C/C++ code

for (int i=0;i<row;i++)
{
for (int j=0;j<col;……
[/Quote]
++
chaochupin 2011-08-12
  • 打赏
  • 举报
回复
抓取的图片是不是和GL_VIEWPORT有关,而又是
glGetIntegerv(GL_VIEWPORT,pView);这个函数控制?
chaochupin 2011-08-12
  • 打赏
  • 举报
回复
ri_aje,你好。我刚依你指出的几点一一改正了,终于出来正确的图像了。现在还有问题麻烦你,就是我现在显示三维模型后抓取的图片,我想怎么样调整视角依次抓取XOY,XOZ,YOZ平面下的投影图片呢?
chaochupin 2011-08-12
  • 打赏
  • 举报
回复
太谢谢你了,我改改试试,因为初次接触这些,完全没有头绪,只是从网上找些代码,跑通了就去理解代码。再次谢谢你了,如果还有问题,我想继续请教你。
ri_aje 2011-08-12
  • 打赏
  • 举报
回复
有看了一下你下面的代码,感觉整个逻辑都是混乱的。这里

int **p=new int *[row];
for (int i=0;i<row;i++)
{
p[i]=new int[col];
}

分配的内存明显不够,因为每个像素有三个通道。这里

for (int i=0;i<row;i++)
{
for (int j=0;j<col;j++)
{
p[i][j]=data[i*col+j];
}
}

对 data 数组通道读取的偏移也计算错了,应该是 data[(i*col+j)*3],难怪你只能看到模型下半边,因为程序只输出了 viewport 的下面 1/3。
ri_aje 2011-08-12
  • 打赏
  • 举报
回复
上贴有个地方说错了,多余的乘数是 sizeof(GLfloat),因此是 4 倍于你需要的 GLfloat 数目。
ri_aje 2011-08-12
  • 打赏
  • 举报
回复
这几句不配套

GLsizei bufferSize = pView[2]*pView[3]*sizeof(GLfloat)*numComponet;
GLfloat* _data = new GLfloat[bufferSize];
unsigned char* data = new unsigned char[bufferSize];
glReadPixels(pView[0],pView[1],pView[2],pView[3],GL_BGR_EXT,GL_FLOAT,_data);
for (int i = 0 ; i <bufferSize ; i ++)
{
{
data[i] = _data[i] * 256;
}
}

你需要存储 pView[2]*pView[3]*numComponent 个浮点数,它们总共占用的内存是 pView[2]*pView[3]*sizeof(GLfloat)*numComponet 字节。
这句
GLfloat* _data = new GLfloat[bufferSize];
分配了 3 倍与你需要的 GLfloat 数目。因此,下面这句读取的时候,
glReadPixels(pView[0],pView[1],pView[2],pView[3],GL_BGR_EXT,GL_FLOAT,_data);
只是把 _data 数组的前 1/3 填充了有效的值。下面的 for 循环,则把 _data 中后 2/3 无用的随机值也强行写入了 data 数组。
另外,我还是头一次见到有人用 GL_BGR_EXT,你要是没什么特别需求的话,真看不出来读取这种格式有什么好处。而且你最后还要自己转换成 unsigned char 输出,何必不用 GL_BYTE,读取呢。
chaochupin 2011-08-12
  • 打赏
  • 举报
回复
我就想3d模型水平投影到XOY平面,XOZ,YOZ平面各得到一副图片。
chaochupin 2011-08-12
  • 打赏
  • 举报
回复
上面是抓取图片的函数。 void glReadPixels(GLint x, GLint y,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
GLvoid *pixels )

x,y指定从框架缓存中读取的第一个像素的窗口坐标。位置是位于正方

形的块的左下角的像素。

width,height指定正方形块的的尺度。

format指定像素数据的格式。参数为:

GL_COLOR_INDEX,GL_STENCIL_INDEX, GL_DEPTH_COMPONENT, GL_RED,

GL_GREEN,GL_BLUE,GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE, and
GL_LUMINANCE_ALPHA.

type指定像素数据的数据类型。参数为:
GL_UNSIGNED_BYTE, GL_BYTE, GL_BITMAP,GL_UNSIGNED_SHORT, GL_SHORT,

GL_UNSIGNED_INT, GL_INT,or GL_FLOAT.

pixels返回像素数据。这个glreadpixels的函数说明。
talentzxf 2011-08-12
  • 打赏
  • 举报
回复
一般用gluLookAt来设置视角。
虽然还是不知道你想干嘛。
chaochupin 2011-08-12
  • 打赏
  • 举报
回复
void saveSceneImage(string name)
{
GLint pView[4];
glGetIntegerv(GL_VIEWPORT,pView);
GLsizei numComponet = 3;
GLsizei bufferSize = pView[2]*pView[3]*sizeof(GLfloat)*numComponet;
GLfloat* _data = new GLfloat[bufferSize];
unsigned char* data = new unsigned char[bufferSize];
glReadPixels(pView[0],pView[1],pView[2],pView[3],GL_BGR_EXT,GL_FLOAT,_data);
for (int i = 0 ; i <bufferSize ; i ++)
{
{
data[i] = _data[i] * 256;
}
}
int row=pView[3];
int col=pView[2];
int **p=new int *[row];
for (int i=0;i<row;i++)
{
p[i]=new int[col];
}
for (int i=0;i<row;i++)
{
for (int j=0;j<col;j++)
{
p[i][j]=255;
}
}
for (int i=0;i<row;i++)
{
for (int j=0;j<col;j++)
{
p[i][j]=data[i*col+j];
}
}
saveBMP(pView[2],pView[3],p,name);
delete[] data;
delete[] _data;
}

64,649

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧