﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-snail-文章分类-计算机图形学与OPENGL</title><link>http://www.cppblog.com/snail/category/10215.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 11 Sep 2009 17:20:25 GMT</lastBuildDate><pubDate>Fri, 11 Sep 2009 17:20:25 GMT</pubDate><ttl>60</ttl><item><title>在制作Bejeweled游戏过程中遇到的问题及解决方法 2</title><link>http://www.cppblog.com/snail/articles/95521.html</link><dc:creator>walking snail</dc:creator><author>walking snail</author><pubDate>Mon, 07 Sep 2009 17:42:00 GMT</pubDate><guid>http://www.cppblog.com/snail/articles/95521.html</guid><wfw:comment>http://www.cppblog.com/snail/comments/95521.html</wfw:comment><comments>http://www.cppblog.com/snail/articles/95521.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/snail/comments/commentRss/95521.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/snail/services/trackbacks/95521.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 在上一节里，本以为绘制图片的透明效果需要当前屏幕的显示内容作为加工条件，但是在NEHE的教程32里才发现其实没那么麻烦，关键要做两件事：<br>&nbsp;&nbsp;&nbsp;&nbsp; 1、在将图片的RGBA值读取到数组里后，根据其对应的mask图片，修改图片的alpha值；&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; 2、函<span style="font-weight: bold;">数</span><span style="color: #0aa614; font-weight: bold;">glAlphaFunc(GL_NOTEQUAL,0.0f)&nbsp;</span> （0.0f是完全透明，1.0f是完全不透明）可以保证根据参数的设置来过滤掉不满足条件的像素点，但此时必须打开混合函数<span style="color: #0aa614; font-weight: bold;">glEnable(GL_BLEND)</span>,且混合函数必须设为<span style="color: #0aa614; font-weight: bold;">glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)</span>，即，仅仅将源图和目的图的alpha值进行混合，这样就很容易的将图片的半透明或透明部分给做出来了。<br>&nbsp;&nbsp;&nbsp; 在制作云层不断的循环飘动的时候，起初以为需要两个纹理连在一起来循环显示，其实只要做一个变量来调节纹理的映射起始坐标就可以了：<br>&nbsp;&nbsp;&nbsp;
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080;">1</span>&nbsp;<span style="color: #0000ff;">float</span><span style="color: #000000;">&nbsp;textureScrollPos[</span><span style="color: #000000;">4</span><span style="color: #000000;">][</span><span style="color: #000000;">2</span><span style="color: #000000;">]&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;{</span><span style="color: #000000;">0.0f</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;xScroll,&nbsp;</span><span style="color: #000000;">0.0f</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;yScroll},<br></span><span style="color: #008080;">2</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</span><span style="color: #000000;">1.0f</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;xScroll,&nbsp;</span><span style="color: #000000;">0.0f</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;yScroll},<br></span><span style="color: #008080;">3</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</span><span style="color: #000000;">1.0f</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;xScroll,&nbsp;</span><span style="color: #000000;">1.0f</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;yScroll},<br></span><span style="color: #008080;">4</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{</span><span style="color: #000000;">0.0f</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;xScroll,&nbsp;</span><span style="color: #000000;">1.0f</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;yScroll}&nbsp;};<br></span><span style="color: #008080;">5</span>&nbsp;<span style="color: #000000;"><br></span><span style="color: #008080;">6</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;glTexCoord2f(textureScrollPos[</span><span style="color: #000000;">0</span><span style="color: #000000;">][</span><span style="color: #000000;">0</span><span style="color: #000000;">],&nbsp;textureScrollPos[</span><span style="color: #000000;">0</span><span style="color: #000000;">][</span><span style="color: #000000;">1</span><span style="color: #000000;">]);&nbsp;glVertex3f(temp.left,&nbsp;temp.bottom,&nbsp;_view_depth);<br></span><span style="color: #008080;">7</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;glTexCoord2f(textureScrollPos[</span><span style="color: #000000;">1</span><span style="color: #000000;">][</span><span style="color: #000000;">0</span><span style="color: #000000;">],&nbsp;textureScrollPos[</span><span style="color: #000000;">1</span><span style="color: #000000;">][</span><span style="color: #000000;">1</span><span style="color: #000000;">]);&nbsp;glVertex3f(temp.right,&nbsp;temp.bottom,&nbsp;_view_depth);<br></span><span style="color: #008080;">8</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;glTexCoord2f(textureScrollPos[</span><span style="color: #000000;">2</span><span style="color: #000000;">][</span><span style="color: #000000;">0</span><span style="color: #000000;">],&nbsp;textureScrollPos[</span><span style="color: #000000;">2</span><span style="color: #000000;">][</span><span style="color: #000000;">1</span><span style="color: #000000;">]);&nbsp;glVertex3f(temp.right,&nbsp;temp.top,&nbsp;_view_depth);<br></span><span style="color: #008080;">9</span>&nbsp;<span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;glTexCoord2f(textureScrollPos[</span><span style="color: #000000;">3</span><span style="color: #000000;">][</span><span style="color: #000000;">0</span><span style="color: #000000;">],&nbsp;textureScrollPos[</span><span style="color: #000000;">3</span><span style="color: #000000;">][</span><span style="color: #000000;">1</span><span style="color: #000000;">]);&nbsp;glVertex3f(temp.left,&nbsp;temp.top,&nbsp;_view_depth);<br></span></div>
&nbsp;&nbsp;&nbsp; 简单吧?天空里漫天星星的循环移动也是同样的方法实现的。<br><br>&nbsp;&nbsp;&nbsp; 当要映射的纹理仅仅是二维性的时候，即仅仅考虑屏幕的x、y像素时，应该怎么办呢？原来这时候可以用glVertex2i(GLint x, GLint y)来指定在屏幕上的坐标，但是必须切换到平行投影模式下才行。这样以来，第一篇里所写的部分内容就要修正了，因为背景等对象完全是不用考虑3d坐标的，完全可以按照当前视口的大小进行映射了！而且即使处于平行投影模式下，依然可以用glTranslatef来使其平移，不过不能在Z轴方向上看出变化罢了（平行投影当然不会了，不过可以调节其映射的2D区域来表现出放大和缩小）。<br>&nbsp;&nbsp;&nbsp; <br><br><img src ="http://www.cppblog.com/snail/aggbug/95521.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/snail/" target="_blank">walking snail</a> 2009-09-08 01:42 <a href="http://www.cppblog.com/snail/articles/95521.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在制作Bejeweled游戏过程中遇到的问题及解决方法 1</title><link>http://www.cppblog.com/snail/articles/91935.html</link><dc:creator>walking snail</dc:creator><author>walking snail</author><pubDate>Sat, 01 Aug 2009 20:34:00 GMT</pubDate><guid>http://www.cppblog.com/snail/articles/91935.html</guid><wfw:comment>http://www.cppblog.com/snail/comments/91935.html</wfw:comment><comments>http://www.cppblog.com/snail/articles/91935.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/snail/comments/commentRss/91935.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/snail/services/trackbacks/91935.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 其实第一次尝试开始制作Bejeweled这个游戏是在年初，安装了这个游戏后发现所有的资源都在安装目录里，所以借clone这个游戏的过程来学习C++和OpenGL。由于之前遇到的阻碍使自己灰心下来，现在我又重新开始了，即使不能完全、完整、完美的把这个游戏给克隆下来，只要在这个过程中能学到新的知识，也是值得铭记的，不是吗？<br><br>&nbsp;&nbsp;&nbsp; 虽然用到了OpenGL，但是这个游戏本质上还是2D的，其中会有部分特效（虫洞）需要借助于3D环境，起初我总想弄明白，如何调节视场的参数，来达到这样的效果：当我要画一个背景图的时候，使这个背景图的大小正好与当前程序的窗口大小相吻合？也就是说，让这幅图全屏显示。因为当把一幅图作为纹理来画的时候，必须要通过<span style="color: #301fa8; font-weight: bold;"> glTexCoord2f (GLfloat s, GLfloat t)</span>;
为他指定图片四个角的坐标，而这里的参数都是float型的空间坐标（虽然有<span style="color: #301fa8; font-weight: bold;">glTexCoord2i (GLint s, GLint t)</span>, 但是我还没搞明白是否是对应着像素的），所以，我觉得无法用一个float型的值来使他对应到当前所创建的窗口坐标的（1024 * 768的窗口，怎么对应?）。最后，我还是先把一个背景图先画上去，然后通过慢慢的调节当前镜头的远近，使其正好和当前窗口相吻合来得到的。这时，我也慢慢明白，作为3D坐标系里的物体，他在窗口里的大小，或者能否与窗口完全吻合，其实的确无法事先确定，就好比你拿着一台DV去录一个物体，当物体的位置已经确定的时候，只能通过调节镜头的焦距来调节它在DV显示屏上的大小。<br>&nbsp;&nbsp;&nbsp; 当然，这些都是些细枝末节，整个程序的结构，各个类之间的组织结构、耦合，一句话---设计模式，才是最整棵树的躯干呢。不过，这个问题还真不是我现在能整理清楚的，慢慢来吧，先把今天遇到的几个小问题做下总结：<br>&nbsp;<br>&nbsp;&nbsp;&nbsp; 1、原来在一个程序里，并不是在平行投影和正交投影间二选一的。在程序中，完全可以根据需要进行两者的切换，这样就方便了做一些2D界面上的东西了，比如文本。 但是发现这个秘密的初衷却是在寻找如何画经由MASK雕镂的图片时知道的，对于背景是纯黑色，或者本身需要一张由黑白两色组成的mask图来决定其形状的图片，最开始我认为应该完全可以通过融合<span style="color: #301fa8; font-weight: bold;">glBlendFunc (GLenum sfactor, GLenum dfactor)
</span>来实现，但是我穷绝了这两个参数的所有配对，结果都不能达到预期的效果，后来仔细想想，既然是融合，那么就必须要是当前图片和缓冲里的图进行融合，而我的目的其实是要做到：凡是mask遮住的部分都不画出来，并且画出的部分是不透明的，这其实是做透明处理啊。 虽然，我不知道一个带有透明部分的图片要画出来的OpenGL方法是什么，但我知道，要想做到这样的效果，就必须拿到当前屏幕上的图片数据，再根据mask将相应部分画到屏幕上去。 而要获得当前屏幕上数据，就必须转换到2D坐标下（Beginning OpenGL Game Programming --- chapter 6 ）。<br><br>&nbsp;&nbsp;&nbsp; 2、为了印证在两种投影模式下可以互相切换，我又根据 Beginning 书 ch6 里提到的例子，先在屏幕上以像素为单位画一个数组形式组织数据的位图。结果又遇到两个小问题：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.1&nbsp; 发现在创建一个图的纹理之后，位图就画不出。原因是这个纹理创建的时用的&nbsp; 是<span style="color: #301fa8; font-weight: bold;">glTexImage2D
</span>，这个函数要求图片的尺寸必须是<font color="#000000"><span style="color: #0fa618; font-style: italic; font-weight: bold;">2的幂 （网上有说必须是64&#215;64、128&#215;128、256&#215;256</span>三种格式， 这个以后待证。），所以当这张图的尺寸小于当前可支持的最大纹理尺寸（<span style="color: #313de4; font-weight: bold;">glGetIntegerv(GL_MAX_TEXTURE_SIZE, &amp;glMaxTexDim)</span>）时，就要对其进行适当的转换使他变为最接近的那个2的幂的数。 而这张图</font>的长和宽都不是2的幂，纹理创建后，就会出现上述问题，奇怪的是，如果至少有一条边长满足2的幂就不会，而且，两条边都不满足时，当且仅当他最后一个创建纹理才会出上述问题，否则只要最后一个创建纹理图片至少有一条边满足2的幂这个条件，就不会出问题。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.2 终于搞清楚导致画位图出问题的原因了，但是在画位图时，有条颜色设置函数<span style="color: #313de4; font-weight: bold;">glColor3f(1.0, 0.0, 1.0)</span>，在这之后，整个窗口都蒙上这个颜色了，像雾！你懂我意思吗？ 最后也是在网上查到 再做下<span style="color: #313de4; font-weight: bold;">glColor3f(1.0, 1.0, 1.0)</span>就恢复正常了。<br><br><br><br>  <img src ="http://www.cppblog.com/snail/aggbug/91935.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/snail/" target="_blank">walking snail</a> 2009-08-02 04:34 <a href="http://www.cppblog.com/snail/articles/91935.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>