OpenGL学习笔记3 —— 绘制3D物体、鼠标交互、反向变换


/*  reference http://nehe.gamedev.net/article/using_gluunproject/16013/
*/

#include <windows.h> // windows系统要加这个。因为下面2个头文件的一些宏是在这个文件中定义的
#include <gl/Gl.h>
#include <gl/glut.h> //这两个头文件在OpenGL程序中几乎必加。

#include <cstdio> //标准输入输出,用来打印坐标
//<<<<<<<<<<<<<<<<<<<<<<< myInit >>>>>>>>>>>>>>>>>>>> 初始化
void myInit(void)
{
glClearColor(0.0,0.0,0.0,0.0); // 设置背景色:黑色。
glShadeModel(GL_SMOOTH); // 设置着色模式,可选GL_SMOOTH(默认)或GL_FLAT。采用恒定着色时(即GL_FLAT),使用图元中某个顶点的颜色来渲染整个图元。

}
//<<<<<<<<<<<<<<<<<<<<<<<< myDisplay >>>>>>>>>>>>>>>>> 绘制
void myDisplay(void)
{
glEnable(GL_DEPTH_TEST); //开启深度测试
glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT); // 将屏幕清除为背景色
glColor3f(1.0f, 0.0f, 0.0f); // 绘制颜色:红色
glLoadIdentity();

gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0 ,1.0, 0.0); //设置eye,相机位置,和向上up向量,可调不同参数来观察会有什么变化
glScalef(1.0, 2.0, 1.0); //表示y坐标值扩大两倍,这样原本方的物体就变成长的了。
glutSolidSphere(1.0, 30, 50); //cube的边长

glFlush(); // send all output to display 把数据从缓冲区弄到屏幕上
}

//<<<<<<<<<<<<<<<<<<<<<<<< reshape >>>>>>>>>>>>>>>>> 视图变换
void myReshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h); //设置视口大小
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0); //将当前矩阵与一个透视矩阵相乘,把当前矩阵转变成透视矩阵
glMatrixMode(GL_MODELVIEW);
}

//<<<<<<<<<<<<<<<<<<<<<<<< GetOGLPos >>>>>>>>>>>>>>>>> 由屏幕坐标得到OpenGL坐标
void GetOGLPos(int x, int y)
{
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
GLdouble posX, posY, posZ;

glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetIntegerv( GL_VIEWPORT, viewport );

winX = (float)x;
winY = (float)viewport[3] - (float)y;
glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );

gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);

//return CVector3(posX, posY, posZ);
printf("x:%f y:%f z:%f\n",posX, posY, posZ);
return;

}

//<<<<<<<<<<<<<<<<<<<<<<<< reshape >>>>>>>>>>>>>>>>> 鼠标点击
void myMouse(int button, int state, int x, int y)
{
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
GetOGLPos(x,y);

}

//<<<<<<<<<<<<<<<<<<<<<<<< main >>>>>>>>>>>>>>>>>>>>>>
void main(int argc, char** argv)
{
glutInit(&argc, argv); // ***对GLUT进行初始化
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA |GLUT_DEPTH); // ***set display mode,单缓冲/双缓冲,颜色索引模式,深度等
glutInitWindowSize(480,480); // ***设置窗口大小
glutInitWindowPosition(100, 150); // ***设置窗口位置
glutCreateWindow("my cube attempt"); // ***创建窗口
myInit();

glutDisplayFunc(myDisplay); // 显示事件回调函数
glutReshapeFunc(myReshape); //当窗口改变时的回调函数
glutMouseFunc(myMouse); //当鼠标交互时的回调函数
glutMainLoop(); // ***启动程序,检测事件并进行处理
}

OpenGL学习笔记3 —— 绘制3D物体、鼠标交互、反向变换,布布扣,bubuko.com

时间: 2024-10-03 22:42:07

OpenGL学习笔记3 —— 绘制3D物体、鼠标交互、反向变换的相关文章

OpenGL学习笔记:拾取与选择

转自:OpenGL学习笔记:拾取与选择 在开发OpenGL程序时,一个重要的问题就是互动,假设一个场景里面有很多元素,当用鼠标点击不同元素时,期待作出不同的反应,那么在OpenGL里面,是怎么知道我当前鼠标的位置是哪一个物体呢? OpenGL有一套机制,叫做Picking, 里面涉及到几个核心概念: 1. selection mode. 选择模式 2. name stack. 名字栈 3. hit record. 命中记录 4. viewing volume. 视角范围 在OpenGL的pick

【OpenGL 学习笔记02】宽点画线

我们要知道,有三种绘图操作是最基本的:清除窗口,绘制几何图形,绘制光栅化对象. 光栅化对象后面再解释. 1.清除窗口 比如我们可以同时清除颜色缓冲区和深度缓冲区 glClearColor (0.0, 0.0, 0.0, 0.0);//指定颜色缓冲区清除为黑色 glClearDepth(1.0);//指定深度缓冲区的清除值为1.0 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//指定要清除的缓冲区并清除 2.绘制几何图形 先要设置绘制颜色,

OpenGL学习笔记2 —— 画立方体

#include <windows.h> // windows系统要加这个.因为下面2个头文件的一些宏是在这个文件中定义的 #include <gl/Gl.h> #include <gl/glut.h> //这两个头文件在OpenGL程序中几乎必加. //<<<<<<<<<<<<<<<<<<<<<<< myInit >>&

【opengl 学习笔记01】HelloWorld示例

<<OpenGL Programming Guide>>这本书是看了忘,忘了又看,赶脚还是把笔记做一做心里比较踏实,哈哈. 我的主题是,好记性不如烂笔头. ================================================================ 1. 下载glut库 glut库地址为:www.opengl.org/resources/libraries/glut/glutdlls37beta.zip glut全称为:OpenGL Utilit

【OpenGL 学习笔记04】顶点数组

通过之前的学习,我们知道,如果要绘制一个几何图形,那就要不断的调用绘制函数,比如绘制一个20条边的多边形,起码要调用22条函数(包含glBegin和glEnd). 所以OpenGL提供了一系列的顶点数组函数减少函数调用的次数来提高性能.而且使用顶点还可以避免顶点共享的冗余处理. 1.简单示例 先来回顾一下之前我们是怎么画直线的: void drawOneLine(GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2) { glBegin(GL_LINES); g

【OpenGL 学习笔记03】点画多边形

1.点画多边形 //定义填充多边形的点画模式.mask为32 x 32 的位图指针,1画0不画,使用前必须启用多边形点画功能 void glPloygonStipple(const GLubyte* mask); //绘制一个矩形 void glRectf(GLfloat x1,GLfloat y1,GLfloat x2,GLfloat y2); 2.示例 #include <GL/glut.h> #include <stdlib.h> void display(void) { G

OpenGL学习笔记1 —— 画点

#include <windows.h> // windows系统要加这个.因为下面2个头文件的一些宏是在这个文件中定义的 #include <gl/Gl.h> #include <gl/glut.h> //这两个头文件在OpenGL程序中几乎必加. //<<<<<<<<<<<<<<<<<<<<<<< myInit >>&

PHP学习笔记-PHP与Web页面的交互2

转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/51761308 本文出自:[顾林海的博客] 前言 在<PHP学习笔记-PHP与Web页面的交互1>笔记中讲解了form表单的一些属性,包括它的输入域标记.选择域标记和文字域标记的写法,接下来的内容就是讲如何获取表单数据以及PHP数据的传递,包括对各种控件值的获取. 插入表单 提交表单之前一定得有表单,当我们的表单创建完毕后可以将表单插入Web页中,代码如下: <

OpenGL学习笔记4:纹理

原始图像数据 像素包装 图像数据在内存中很少以紧密包装的形式存在.在许多硬件平台上,处于性能上的考虑,一幅图像的每一行都应该从一种特定字节对齐地址开始.绝大多数编译器会自动把变量和缓冲区放置在一个针对该架构对齐优化的地址上. 例如一个包含3个分量的rgb图像,每个分量存储在一个字节中,如果图像有199个像素,那么一行需要597个像素.如果硬件本身的体系结构是4字节排列,那么图像每一行的末尾将由额外的3个空字符进行填充达到600字节. 我们可以使用下列函数改变或者回复像素的存储方式. void g