用VC画三维图像

shenspring 2002-10-06 06:44:31
请问有没有现成的函数,可以将一个矩阵画成三维的图像,就像Matlab一样,如果有的花哪儿有下载呢?
...全文
655 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
LookSail 2002-10-13
  • 打赏
  • 举报
回复
opengl
warmworm 2002-10-13
  • 打赏
  • 举报
回复
自己做嘛
很简单的东西
看点计算机图形学里相关的东西和有一点解析几何的概念就行了
kwiner 2002-10-13
  • 打赏
  • 举报
回复
利用OpenGL实现三维绘图



前言:
在三维绘图蓬勃发展的过程中,计算机公司推出了大量的三维绘图软件包。其中
SGI公司推出的OpenGL,作为一个性能优越的图形应用程序设计界面(API)异军
突起,取得了很大的成就。它以高性能的交互式三维图形建模能力和易于编程开
发,得到了Microsoft、 IBM、 DEC、 Sun、 HP等大公司的认同。因此,OpenGL
已经成为一种三维图形开发标准,是从事三维图形开发工作的必要工具。

一.初始化OpenGL绘图环境
1. 定义颜色格式和缓冲模式
OpenGL提供两种颜色模式:RGB(RGBA)模式和颜色索引模式。在RGBA模式下所有
颜色的定义用RGB三个值来表示,有时也加上Alpha值(表示透明度)。RGB三个分
量值的范围都在0和1 之间,它们在最终颜色中所占的比例与它们的值成正比。如:
(1,1,0)表示黄色,(0,0,1)表示蓝色。颜色索引模式下每个象素的颜色是
用颜色索引表中的某个颜色索引值表示(类似于从调色板中选取颜色)。由于三维
图形处理中要求颜色灵活,而且在阴影,光照,雾化,融合等效果处理中RGBA 的效
果要比颜色索引模式好,所以,在编程时大多采用RGBA模式。
OpenGL提供了双缓存来绘制图像。即在显示前台缓存中的图像同时,后台缓存绘制
第二幅图像。当后台绘制完成后,后台缓存中的图像就显示出来,此时原来的前台
缓存开始绘制第三幅图像,如此循环往复,以增加图像的输出速度。
设置窗口显示模式函数:
void auxInitDisplayMode(
AUX_DOUBLE//双缓存方式
|AUX_RGBA);//RGBA颜色模式
2.设置光源
OpenGL的光源大体分为三种:环境光(Ambient light),即来自于周围环境没有固
定方向的光。漫射光(Diffuse light)来自同一个方向,照射到物体表面时在物体的
各个方向上均匀发散。镜面光(Specular light)则是来自于同一方向,也沿同一个方
向反射。全局环境光是一种特殊的环境光,它不来自特于某种定光源,通常做为场景
的自然光源。
指定光源函数:
Void glLightfv(Glenum light, //光源号
Glenum pname, //指明光源种类
//GL_DIFFUSE 光源为漫射光光源
//GL_AMBIENT 光源为环境光光源
//GL_SPECULAR 光源为镜面光光源
const Glfloat* params);//指向颜色向量的指针
设置全局环境光函数:
void glLightModelfv( GL_LIGHT_MODEL_
AMBIENT, const Glfloat* param );
//param 指向颜色向量的指针
起用光源函数:
void glEnable(GL_LIGHTING);
void glEnable(GL_enum cap);// cap :指明光源号
3. 设置材质
在OpenGL中,用材料对光的三原色(红绿蓝)的反射率大小来定义材料的颜色。与光
源相对应,材料的颜色,也分为环境色,漫反射色和镜面反射色,由此决定该材料
对应不同的光呈现出不同的反射率。由于人所看到物体的颜色是光源发出的光经物
体反射后进入眼睛的颜色。所以,物体的颜色是光源的环境光,漫反射光和镜面反
射光与材料的环境色,漫反射色和镜面反射色的综合。例如:OpenGL 的光源色是
(LR,LG,LB),材质色为(MR,MG,MB),那么,在忽略其他反射效果的情况下,
最终进入眼睛的颜色是(LR*MR,LG*MG,LB*MB)。
材质定义函数:
void glMaterialfv( GLenum face, //指明在设置材质
的哪个表面的颜色。可以是GL_FRONT, GL_BACK,或GL_FRONT_AND_BACK
GLenum pname,//与光源的pname参数相似
const float* params);//指向材质的颜色向量
4.定义投影方式
也即选择观察物体的角度和范围。由于我们是三维绘图,所以采用不同的视点和观
察范围,就会产生不同的观察效果。由于计算机只能显示二维图形,所以在表示真
实世界中的三维图形时,需将三维视景转换成二维视景。这是产生三维立体效果的
关键。OpenGL提供了两种将3D图形转换成2D图形的方式。正投影(Orthographic Projection)和透视投影(Perspective Projection)。其中,正投影指投影后物体的大小与视点的远近无关,通常用于CAD设计;而透视投影则符合人的心理习惯,离视点近的物体大,离视点远的物体小。此外,在OpenGL中还要定义投影范围,只有在该范围中的物体才会被投射到计算机屏幕上,投影范围外的物体将被裁减掉。
定义投影范围(不同的投影方式对应不同函数):
void glOrtho( GLdouble left, GLdouble right,
GLdouble bottom, GLdouble top,
GLdouble near,GLdouble far);
//(left,bottom,near)和(right,top,far)分别给出正射投
//影投影范围的左下角和右上角的坐标。

二.定义与Windows接口的系统函数
1.定义绘图窗口的位置:
void auxInitPosition(GLint x,GLint y,GLsizei width, GLsizei heigh);// (x,y)给出窗口左上角坐标
// width和 heigh给出窗口的宽高
2.定义绘图窗口的标题:
void auxInitWindow(GLbyte* 窗口标题字串);
3.定义绘图窗口改变时的窗口刷新函数:
void auxReshapeFunc(回调函数名称);
//当窗口改变形状时调指定的回调函数
4.定义空闲状态的空闲状态函数以实现动画:
void auxIdleFunc(回调函数名称);
//当系统空闲时调用指定的回调函数
5.定义场景绘制函数(当窗口更新或场景改变时调用):
void auxMainLoop(回调函数名称);
//当窗口需要更新或场景变化时调用

三.VC下实现
在VC编辑器下键入下述代码后,保存为后缀是cpp的C++文件。开始编译,在
The build command requires an active project workspace。 Would you like
to create a default project workspace? 的提示后,选择“是(Y)”。
进入Project菜单,选择Setting项,弹出Project Setting 对话框,选择Link项,
在Libaray栏目中加入OpenGL提供的函数库:“opengl32.lib glu32.lib glaux.lib”。
(注:在执行时,Windows 的system目录下要包含opengl32.dll和glu32.dll两个动态连接库)。


附源程序代码:
#include "windows.h" #include "gl/gl.h" #include "gl/glaux.h" #include "gl/glu.h" #include "math.h" void myinit()
{
glClearColor(1,1,0,0);
GLfloat ambient[]={.5,.5,.5,0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,
ambient);
GLfloat mat_ambient[]={.8,.8,.8,1.0};
GLfloat mat_diffuse[]={.8,.0,.8,1.0};
GLfloat mat_specular[]={1.0,.0,1.0,1.0};
GLfloat mat_shininess[]={50.0};
GLfloat light_diffuse[]={0,0,.5,1};
GLfloat light_position[]={0,0,1.0,0};
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,mat_ambient);
glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,mat_diffuse);
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,mat_specular);
glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,mat_shininess);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0,GL_POSITION, light_position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
}
void CALLBACK display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
auxSolidSphere(1.0);//绘制半径为1.0的实体球
glFlush(); //强制输出图像
auxSwapBuffers(); //交换绘图缓存
_sleep(100);}
void CALLBACK Idledisplay()
{
//x,y满足x2+y2=0.01。这样可以使物体沿该圆轨 //迹运动。
static float x=-.1,y=0.0;
static BOOL mark=TRUE;
static float step=.01;
x+=step;
if(x<=.1&&x>=-.1)
{
if(step>0)
y=sqrt(.01-x*x);
else
y=-sqrt(.01-x*x);
glTranslatef(x,y,0);
}
else
{
step=0-step;
}
display();
}
void CALLBACK myReshape(GLsizei w,GLsizei h)
{
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(w<=h)
glOrtho(-3.5,3.5,-3.5*(GLfloat)w/(GLfloat)h, 3.5*(GLfloat)w/(GLfloat)h,-10,10);
else
glOrtho(-3.5*(GLfloat)w/(GLfloat)h,3.5* (GLfloat)w/(GLfloat)h,-3.5,3.5,-10,10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void main()
{
auxInitDisplayMode(AUX_DOUBLE|AUX_RGBA);
auxInitPosition(0,0,400,400);
auxInitWindow(" circle ");
myinit();
auxReshapeFunc(myReshape);
auxIdleFunc(Idledisplay);
auxMainLoop(display);
}

shenspring 2002-10-13
  • 打赏
  • 举报
回复
请问谁做过这方面的编程,如果有,麻烦RE一下!
shenspring 2002-10-06
  • 打赏
  • 举报
回复
我希望能够用现成的vc代码,主要是想根据已经有的数组画出那种带有网格状的表面。http://www.codeproject.com/gdi/flowerpower.asp中的例子好像并不是通过数组生成的这种效果。
qing_li73 2002-10-06
  • 打赏
  • 举报
回复
u can see the example below :

http://www.codeproject.com/gdi/flowerpower.asp

bonnyone 2002-10-06
  • 打赏
  • 举报
回复
此等效果用opengl或directdraw都可以做

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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