#ifdef _WINDOWS
#include <windows.h>
#endif
#include "MyOpenGL.h"
#include <math.h>
#include <string.h>
#include <fstream>
#include <iostream>
#include <iterator>
#define RANDOM_COLOR
const Color objectColor={100,100,200};
ObjModel::ObjModel()
{
}
ObjModel::~ObjModel()
{
}
int charToInt(char *&pt)
{
int x=0;
while(*pt>='0'&&*pt<='9')
{
x=x*10+(*pt-'0');
pt++;
}
return x;
}
DataIndex extract(char * buf)
{
DataIndex index;
char *pt=buf;
index.faceIndex=charToInt(pt);
*pt++;
if (*pt>='0'&&*pt<='9')
index.coordIndex=charToInt(pt);
*pt++;
if (*pt>='0'&&*pt<='9')
index.normalIndex=charToInt(pt);
return index;
}
bool ObjModel::Read(const char *filename)
{
bool flag=TRUE;
std::ifstream input;
input.open(filename);
if (!input)
return 0;
// read the data of the object
char buf[256];
DataIndex tempIndex;
std::vector<int> tempfaceIndex; // maybe triangles , quards , or polygons
std::vector<int> tempNormalIndex;
std::vector<int> tempCoordIndex;
// buffer of the data
Point temp;
input>>buf;
while((buf[0])!=EOF)
{
switch (buf[0])
{
// this may be a point,a vertex normal,a texture coord or just a letter
case 'v':
switch (buf[1])
{
case 'n':
input>>temp.x>>temp.y>>temp.z>>buf;
vertexNormals.push_back(temp);
break;
case 't':
input>>temp.x>>temp.y>>temp.z>>buf;
textureCoords.push_back(temp);
break;
case '\0':
input>>temp.x>>temp.y>>temp.z>>buf;
vertices.push_back(temp);
if (flag)
{
maxx=minx=temp.x;
maxy=miny=temp.y;
flag=!flag;
}
if (temp.x>maxx) maxx=temp.x;
if (temp.y>maxy) maxy=temp.y;
if (temp.x<minx) minx=temp.x;
if (temp.y<miny) miny=temp.y;
break;
default:
input>>buf;
break;
}
break;
case 'f':
switch (buf[1])
{
case '\0':
input>>buf;
while (buf[0]>'0'&&buf[0]<='9')
{
tempIndex=extract(buf);
tempfaceIndex.push_back(tempIndex.faceIndex);
tempNormalIndex.push_back(tempIndex.normalIndex);
tempCoordIndex.push_back(tempIndex.coordIndex);
input>>buf;
}
faceIndex.push_back(tempfaceIndex);
normalIndex.push_back(tempNormalIndex);
coordIndex.push_back(tempCoordIndex);
tempfaceIndex.clear();
tempNormalIndex.clear();
tempCoordIndex.clear();
break;
default:
input>>buf;
break;
}
break;
default:
input>>buf;
break;
}//switch
if (input.eof())
break;
}//while
numVertices=vertices.size();
numVertexNormals=vertexNormals.size();
numTextureCoords=textureCoords.size();
numFaces=faceIndex.size();
return 1;
}
MyOpenGL::MyOpenGL()
{
}
MyOpenGL::~MyOpenGL()
{
}
bool MyOpenGL::Init(const char *filename)
{
glClearColor(0.0,0.0,0.0,0.0);
m_angle=0.0f;
model=new ObjModel();
model->Read(filename);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
return true;
}
bool MyOpenGL::Shutdown()
{
return true;
}
void MyOpenGL::SetupProjection(int width,int height)
{
if (height==0)
height=1;
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(52.0f,(GLfloat)width/(GLfloat)height,1.0f,1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
m_windowWidth=width;
m_windowHeight=height;
}
void MyOpenGL::Prepare(float dt)
{
m_angle+=0.1f;
}
void MyOpenGL::setToScreenCoordinate()
{
double scale,xoffset,yoffset;
//首先判断物体的纵横比与窗口的比例,较长的物体按长度来放缩否则按高度放缩
/******按y方向缩放至屏幕大小,其中计算后的y坐标范围在[0,m_windowHeight-1]之间,可以避免z_buffer越界******/
if (((model->maxx-model->minx)*m_windowHeight)<((model->maxy-model->miny)*m_windowWidth))
scale=(m_windowHeight-1)/(model->maxy-model->miny);
else scale=(m_windowWidth-1)/(model->maxx-model->minx);
xoffset=(m_windowWidth-1-scale*(model->maxx-model->minx))/2-model->minx*scale;
yoffset=(m_windowHeight-1-scale*(model->maxy-model->miny))/2-model->miny*scale;
for (std::vector<Point>::iterator it=model->vertices.begin();it!=model->vertices.end();it++)
{
it->x=doubleToInt(it->x*scale+xoffset);
it->y=doubleToInt(it->y*scale+yoffset);
it->z=doubleToInt(it->z*scale);
}
model->maxy=model->maxy*scale+yoffset;
model->miny=model->miny*scale+yoffset;
model->maxx=model->maxx*scale+xoffset;
model->minx=model->minx*scale+xoffset;
}
void MyOpenGL::z_buffer()
{
//第一步,将物体坐标进行简单的投影变换,将其坐标转换为屏幕坐标,使其大小符合窗口的大小,并固定我们所看到的为物体的正视图,可以通过旋转物体来观察其他表面。
setToScreenCoordinate();
//首先建立分类的多边形表和边表l扫描顺序从上到下:在处理最上面一条扫
//描线之前,活化的多边形表和边表是空的l在处理每条扫描线时,作如下工作
//l 把帧缓冲器的相应行置成底色l 把z缓冲器的各个单元置成最小值(表示离视
//点最远)
constructSortTable();
//开两个一维数组(xresolution)分别作为当前扫描线的z缓冲器和帧缓冲器,z缓冲器初始值为最小值,帧缓冲器为背景色
double z_depth[800];
Color frameBuf[800];
std::vector<SortEdgeTable>::iterator tempEdgeTable[3];
ActivePolygonTable tempActivePolygonTable;
int lines=0;
double zx;
bool flag=false;
std::vector<ActivePolygonTable>::iterator activePolygonPtr;
Color aa;
int stopline=256;
/*********逐扫描线进行处理********/
for (int scanLine=m_windowHeight-1;scanLine>=0;scanLine--)
{
if (scanLine==stopline)
stopline-=1;
/*********把帧缓冲器的相应行置成底色 把z缓冲器的各个单元置成最小值(表示离视点最远)*********/
for (int i=0;i<m_windowWidth;i++)
{
z_depth[i]=-99999999;
image[scanLine][i].r=0;
image[scanLine][i].g=0;
image[scanLine][i].b=0;
}
/******检查分类的多边形表,如果有新的多边形涉及该扫描线,则把它放入活化的多边形表中******/
for (std::vector<SortPolygonTable>::iterator polygonPtr=sortPolygonTable[scanLine].begin();polygonPtr!=sortPolygonTable[scanLine].end();)
{
//将该多边形加入活化多边形表中
tempActivePolygonTable.a=polygonPtr->a;
tempActivePolygonTable.b=polygonPtr->b;
tempActivePolygonTable.c=polygonPtr->c;
tempActivePolygonTable.d=polygonPtr->d;
tempActivePolygonTable.dy=polygonPtr->dy;
tempActivePolygonTable.id=polygonPtr->id;
tempActivePolygonTable.color=polygonPtr->color;
if (tempActivePolygonTable.id==2)
tempActivePolygonTable.id=2;
lines=0;
///******把该多边形在oxy平面上的投影和扫描线相交的边加入到活化边表中,必定有两条边******/
for (std::vector<SortEdgeTable>::iterator edgePtr=sortEdgeTable[scanLine].begin();edgePtr!=sortEdgeTable[scanLine].end();)
{
if (edgePtr->id==polygonPtr->id)
lines++;
if (lines==1&&edgePtr->id==polygonPtr->id)
{
tempActivePolygonTable.activeEdgeTable.xl=edgePtr->x;
tempActivePolygonTable.activeEdgeTable.dxl=edgePtr->dx;
tempActivePolygonTable.activeEdgeTable.dyl=edgePtr->dy;
tempActivePolygonTable.activeEdgeTable.xr=edgePtr->x;
tempActivePolygonTable.activeEdgeTable.dxr=edgePtr->dx;
tempActivePolygonTable.activeEdgeTable.dyr=edgePtr->dy;
tempActivePolygonTable.activeEdgeTable.dzx=-polygonPtr->a/polygonPtr->c;
tempActivePolygonTable.activeEdgeTable.dzy=polygonPtr->b/polygonPtr->c;
tempActivePolygonTable.activeEdgeTable.id=polygonPtr->id;
sortEdgeTable[scanLine].erase(edgePtr,edgePtr+1);
edgePtr=sortEdgeTable[scanLine].begin();
continue;
}
if (lines==2&&edgePtr->id==polygonPtr->id)
{
//temp中0号位存左边
if (tempActivePolygonTable.activeEdgeTable.xl>edgePtr->x||(abs(tempActivePolygonTable.activeEdgeTable.xl-edgePtr->x)<1e-8&&tempActivePolygonTable.activeEdgeTable.dxl>edgePtr->dx))
{
tempActivePolygonTable.activeEdge
没有合适的资源?快使用搜索试试~ 我知道了~
z_buffer(vc+opengl)
共45个文件
obj:20个
pdb:3个
manifest:2个
5星 · 超过95%的资源 需积分: 9 62 下载量 132 浏览量
2010-04-08
15:05:40
上传
评论 2
收藏 6.3MB RAR 举报
温馨提示
注:所读obj文件中需为如下形式 # object objBox01 to come ... # v -139.147125 -22.288633 1686.136963 v -110.396103 -3.807856 1664.112427 。。。 v -139.147125 -22.288633 1686.136963v ... 此类的无法读 即v与前一排数据必须有空格或者回车符 可以使用3d max2009导出的obj即可使用
资源推荐
资源详情
资源评论
收起资源包目录
z_buffer.rar (45个子文件)
z_buffer
MyOpenGL.cpp 19KB
main.cpp 5KB
z_buffer.suo 14KB
z_bufferStructure.h 29B
z_buffer.dsp 4KB
z_buffer.vcproj.asus-PC.asus.user 1KB
z_buffer.vcproj 6KB
model
cube.obj 839B
box2.obj 1KB
box4.obj 1KB
torus.obj 33KB
sphere.obj 56KB
teapot.obj 60KB
box3.obj 1KB
venusm.obj 2.94MB
box1.obj 923B
zz2.obj 18KB
torusknot.obj 176KB
zz1.obj 20KB
cone.obj 16KB
box7.obj 1KB
box.obj 1012B
box0.obj 1KB
test.obj 2.94MB
box5.obj 1KB
Debug
z_buffer.pdb 5.25MB
vc60.pdb 196KB
vc60.idb 217KB
vc90.idb 547KB
BuildLog.htm 6KB
z_buffer.exe 773KB
z_buffer.exe.embed.manifest.res 472B
mt.dep 65B
MyOpenGL.obj 1.22MB
main.obj 28KB
z_buffer.exe.embed.manifest 406B
vc90.pdb 356KB
z_buffer.ilk 1.68MB
z_buffer.exe.intermediate.manifest 381B
z_buffer.plg 1KB
MyOpenGL.h 3KB
z_buffer.sln 881B
z_buffer.ncb 15.46MB
z_buffer.opt 50KB
z_buffer.dsw 541B
共 45 条
- 1
ZZ198763
- 粉丝: 1
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于matlab实现电力系统仿真计算软件包,包括潮流计算,最优潮流计算等.rar
- 基于matlab实现电力系统各种故障波形仿真,单相接地故障,两相间短路,两相接地短路,三相短路等.rar
- 基于matlab实现电动汽车动力性,爬坡性,续驶里程等性能仿真.rar
- Python动态烟花代码.pdf
- 基于matlab实现串口发送接收数据 可配置端口,波特率等 发送可选择ASCII方式或HEX方式
- matlab基于BP神经网络手写字母识别(单一).zip代码9
- 基于matlab实现编写的串口调试工具,数据接收部分采用中断方式,保证了实时的数据显示
- 基于matlab实现39节点电力系统合闸角调控过程中的机组和负荷的灵敏度计算.rar
- HBase数据库性能调优
- 原生微信小程序源码 - -首字母排序选择
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
前往页