1、初始化OpenGL绘图环境
1.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颜色模式
)
1.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:指明光源号
1.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 // 指向材质的颜色向量
)
1.4 定义投影方式
也即选择观察物体的角度和范围。由于我们是三维绘图,所以采用不同的视点和观察范围,就会产生不同的观察效果。由于计算机只能显示二维图形,所以在表示真实世界中的三维图形时,需将三维视景转换成二维视景。这是产生三维立体效果的关键。OpenGL提供了两种将3D图形转换成2D图形的方式。正投影(Orthographic Projection)和透视投影(Perspective Projection)。其中,正投影指投影后物体的大小与视点的远近无关,通常用于CAD设计;而透视投影则符合人的心理习惯,离视点近的物体大,离视点远的物体小。此外,在OpenGL中还要定义投影范围,只有在该范围中的物体才会被投射到计算机屏幕上,投影范围外的物体将被裁减掉。
定义投影范围(不同的投影方式对应不同函数):
void glOrtho(
GLdouble left, GLdouble right,
// (left,bottom,near)及(right,top,far)分别给出正射投
GLdouble bottom, GLdouble top, // 影投影范围的左下角和右上角的坐标。
GLdouble near,GLdouble far)
2、定义与Windows接口的系统函数
2.1 定义绘图窗口的位置
// (x,y)给出窗口左上角坐标
// width及heigh给出窗口的宽高
void auxInitPosition(GLint x,GLint y,GLsizei width, GLsizei heigh)
2.2 定义绘图窗口的标题
// STR表示窗口标题字串
void auxInitWindow(GLbyte* STR)
2.3 定义绘图窗口改变时的窗口刷新函数
// 当窗口改变形状时调指定的回调函数
// NAME表示回调函数名称
void auxReshapeFunc(NAME)
2.4 定义空闲状态的空闲状态函数以实现动画
// 当系统空闲时调用指定的回调函数
// NAME表示回调函数名称
void auxIdleFunc(NAME)
2.5 定义场景绘制函数(当窗口更新或场景改变时调用)
// 当窗口需要更新或场景变化时调用
// NAME表示回调函数名称
void auxMainLoop(NAME)
在VC编辑器下键入下述代码后,保存为后缀是.cpp的C++文件。开始编译,在“The build command requires an active project workspace”。“Would you like to create a default project workspace”? 的提示后,选择“是(Y)”。进入“Project”菜单,选择“Setting”项,d出“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)
}
给你一个关于VC和OPENGL的网站,不错的
http://dev.yesky.com/402/2084902.shtml
1. 抽象形状类package com
//抽象的形状类
public abstract class Shape{
}
2. 显示接口
package com
//接口
public interface IDisplay{
void display() //显示图形的基本信息
double getArea() //计算面积
double getGirth() //计算周长
}
3. 三角形类
package com.tri
import com.*
//三角形类
public class Triangle extends Shape implements IDisplay{
protected double a
protected double b
protected double c
public Triangle(double a, double b, double c){
this.a = a
this.b = b
this.c = c
}
@Override
public double getArea() {
double s = (a + b + c) / 2
return Math.sqrt(s*(s-a)*(s-b)*(s-c))
}
@Override
public double getGirth() {
return this.a + this.b + this.c
}
@Override
public void display() {
System.out.println("三角形")
System.out.println("边长:" + a + ", " + b + ", " + c)
}
}
4. 矩形类
package com.rec
import com.*
//矩形类
public class Rectangle extends Shape implements IDisplay {
protected double width
protected double height
public Rectangle(double width, double height){
this.width = width
this.height = height
}
@Override
public double getArea() {
return this.width * this.height
}
@Override
public double getGirth() {
return 2 * ( this.width + this.height)
}
@Override
public void display() {
System.out.println("矩形")
System.out.println("宽:" + this.width + ", 高:" + this.height)
}
}
5. 圆类
package com.cir
import com.*
//圆类
public class Circle extends Shape implements IDisplay {
protected double radius
public Circle(double radius){
this.radius = radius
}
@Override
public double getArea() {
return Math.PI * this.radius * this.radius
}
@Override
public double getGirth() {
return 2 * Math.PI * this.radius
}
@Override
public void display() {
System.out.println("圆")
System.out.println("半径:" + this.radius)
}
}
6. 正多边形类
package com.mul
import com.*
//正多边形类
public class MulSide extends Shape implements IDisplay {
protected double side //边长
protected int n //边数
public MulSide(double side, int n){
this.side = side
this.n = n
}
@Override
public double getArea() {
return n * side * side * Math.tan((n-2) * Math.PI / (2 * n)) / 4
}
@Override
public double getGirth() {
return this.side * this.n
}
@Override
public void display() {
System.out.println("正多边形")
System.out.println("连长:" + this.side + ", 边数:" + this.n)
}
}
7. 主类(测试类)
package com
import java.util.Scanner
import com.cir.Circle
import com.mul.MulSide
import com.rec.Rectangle
import com.tri.Triangle
public class Test22 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in)
double a, b, c
double width, height
double radius
double side
int n
IDisplay s
System.out.println("请输入三角形的基本信息")
System.out.print("边长1:")
a = scan.nextDouble()
System.out.print("边长2:")
b = scan.nextDouble()
System.out.print("边长3:")
c = scan.nextDouble()
s = new Triangle(a, b, c)
s.display()
System.out.println("三角形的面积:" + s.getArea())
System.out.println("三角形的周长:" + s.getGirth())
System.out.println("请输入矩形的基本信息")
System.out.print("宽:")
width = scan.nextDouble()
System.out.print("高:")
height = scan.nextDouble()
s = new Rectangle(width, height)
s.display()
System.out.println("矩形的面积:" + s.getArea())
System.out.println("矩的周长:" + s.getGirth())
System.out.println("请输入圆的基本信息")
System.out.print("半径:")
radius = scan.nextDouble()
s = new Circle(radius)
s.display()
System.out.println("圆的面积:" + s.getArea())
System.out.println("圆的周长:" + s.getGirth())
System.out.println("请输入正多边形的基本信息")
System.out.print("边长:")
side = scan.nextDouble()
System.out.print("边数:")
n = scan.nextInt()
s = new MulSide(side, n)
s.display()
System.out.println("正多边形的面积:" + s.getArea())
System.out.println("正多边形的周长:" + s.getGirth())
}
}
运行测试:
请输入三角形的基本信息
边长1:3
边长2:4
边长3:5
三角形
边长:3.0, 4.0, 5.0
三角形的面积:6.0
三角形的周长:12.0
请输入矩形的基本信息
宽:3
高:4
矩形
宽:3.0, 高:4.0
矩形的面积:12.0
矩的周长:14.0
请输入圆的基本信息
半径:2
圆
半径:2.0
圆的面积:12.566370614359172
圆的周长:12.566370614359172
请输入正多边形的基本信息
边长:2
边数:6
正多边形
连长:2.0, 边数:6
正多边形的面积:10.39230484541326
正多边形的周长:12.0
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)