我用这段代码在 OpenGL 中创建了一个平面:
glBegin(GL_TRIANGLE_STRIP);
glColor4f(0.8, 0.8, 0.5, 1.0);
glVertex3f(startlen, height, startwid);
glVertex3f(startlen, height, startwid + width);
glVertex3f(startlen + length, height, startwid);
glVertex3f(startlen + length, height, startwid + width);
glEnd();
现在我想在这个平面上应用纹理。
我已阅读本教程 here但我在“在 OpenGL 中使用纹理”部分停了下来,因为我没有 UV 坐标。
我知道我们必须导入纹理文件,在我的例子中是位图文件。
loader返回一个Glint,也就是textureID,是全局的吗?例如,如果我需要加载该纹理,我只需要使用给定的 ID 调用绑定(bind)纹理函数?
无论如何,我怎样才能将纹理应用到平面上?
编辑#1:
蚊子发布的示例中的纹理现在可以使用了。
我发现我正在将纹理加载到类的构造函数中,但我不应该这样做,因为该对象是公共(public)的,并且它是在 OpenGL 初始化之前构造的。
所以纹理现在可以在四边形示例中正常加载 :)
现在的问题是我试过在我的飞机上使用它,但它看起来变形了。 对此的解决方案可能是允许多次加载纹理,但保持其原始大小(虽然我不知道该怎么做)。
此外,我在当前平面旁边创建了另一个奶油色平面,但在纹理化之后它看起来像这样:
所以现在有2个问题:
编辑#2:
第二个问题现在已经解决了,感谢 mosquito!
但是平铺仍然不起作用。
这是它现在的样子:
这是我用过的纹理:
它的尺寸为 256x256(我使用图像编辑器对其进行了裁剪)
编辑#3:
这些是 glTexCoord2f 坐标及其匹配的顶点(对于内边距):
glTexCoord2f(0.0f, 0.0f); glVertex3f(startlen, height, startwid);
glTexCoord2f(0.0f, 1.0f); glVertex3f(startlen, height, startwid - width/2);
glTexCoord2f(1.0f, 0.0f); glVertex3f(startlen + length, height, startwid);
glTexCoord2f(1.0f, 1.0f); glVertex3f(startlen + length, height, startwid - width/2);
最佳答案
如果您有返回 textureID 的加载程序,那么它可能已经负责加载图像数据、设置属性并将其存储为真实纹理以供进一步使用。所以我将继续将纹理绑定(bind)到您的纹理目标。
如果你有这个 id,你基本上必须在绘制三角形带之前调用 glBindTexture() 函数:
glBindTexture(GL_TEXTURE_2D, id); // where id is GLuint returned by your loader
现在对于您绘制的每个顶点,您还应该为这些顶点指定纹理坐标。为此,您可以使用 glTexCoord2f() 函数。对于简单的四边形,它可能看起来像这样:
glBegin(GL_QUADS);
// Bottom left
glTexCoord2f(0.0f, 1.0f);
glVertex2i(0.0f, 10.0f);
// Top left
glTexCoord2f(0.0f, 0.0f);
glVertex2i(0.0f, 0.0f);
// Top right
glTexCoord2f(1.0f, 0.0f);
glVertex2i(10.0f, 0.0f);
// Bottom right
glTexCoord2f(1.0f, 1.0f);
glVertex2i(10.0f, 10.0f);
glEnd();
如您所见,每个顶点都附有纹理“点”。它会告诉 OpenGL 如何显示你的纹理。
现在您可以通过指定适当的顶点坐标来选择您希望纹理在平面上的分布方式。
你要记住的是纹理坐标从 0.0 开始到 1.0 结束。将此值增加到 1.0 以上将导致行为取决于您的纹理设置(例如平铺)。
在您的教程中,您有非常漂亮的图片,显示纹理坐标在 0.0 到 1.0 范围内,以及为特定顶点设置的纹理坐标:
附言。为了显示纹理,您必须首先通过调用启用此功能:
glEnable(GL_TEXTURE_2D);
您不必每次绘制带有纹理的对象时都调用它。它可能只在您绘图之前调用一次。
编辑
根据你的下一个问题:你想要的是实现平铺 效果,这可以在创建纹理时轻松完成。 在你的加载器中,在这一行之后:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
你应该像这样设置下一个纹理参数:
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
在这种情况下,GL_REPEAT 用于在任何时候重复纹理
它的坐标高于 1.0。例如,如果您指定
纹理坐标为 2.0 与您设置的 1.0 相同,因此
上。
你的第二个问题存在是因为你仍然有你的纹理绑定(bind)
并且您启用了纹理(请记住您使用
glEnable(GL_TEXTURE_2D);),所以基本上你现在画的所有东西,
将被纹理覆盖。
但是如果你现在想画一些没有纹理的东西,你 基本上必须在绘制第二个平面之前禁用纹理 并在绘制后再次启用它:
glDisable(GL_TEXTURE_2D);
// Draw your second plane here
glEnable(GL_TEXTURE_2D);
EDIT2
嗯,我想你有点误解我了。在这种情况下,平铺无法工作,因为您将纹理坐标指定为最大值 1.0,这是纹理的末尾。我准备了一张图片,可以向您展示我的意思:
在中间的那些图片中,我用红色标记了纹理坐标,用黑色标记了顶点坐标。
所以基本上,如果您像现在这样设置纹理坐标(最大值为 1.0),您的纹理就会围绕您的平面拉伸(stretch)。现在想象这个平面非常大 - 如果纹理分辨率低,它只会导致丑陋的拉伸(stretch)效果。
为了实现平铺效果,您必须将值设置为高于 1.0,就像在我的示例中一样 - 2.0 会导致纹理重复两次。
由于没有神奇的方法可以让您的纹理在您的平面上看起来“漂亮”,您必须使用一些数学来实现它。现在我留给你了。
关于c++ - 向由顶点构成的平面添加纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14740331/
当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/
我有一个ModularSinatra应用程序,我正在尝试将Bootstrap添加到应用程序中。get'/bootstrap/application.css'doless:"bootstrap/bootstrap"end我在views/bootstrap中有所有less文件,包括bootstrap.less。我收到这个错误:Less::ParseErrorat/bootstrap/application.css'reset.less'wasn'tfound.Bootstrap.less的第一行是://CSSReset@import"reset.less";我尝试了所有不同的路径格式,但它
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
当谈到运行时自省(introspection)和动态代码生成时,我认为ruby没有任何竞争对手,可能除了一些lisp方言。前几天,我正在做一些代码练习来探索ruby的动态功能,我开始想知道如何向现有对象添加方法。以下是我能想到的3种方法:obj=Object.new#addamethoddirectlydefobj.new_method...end#addamethodindirectlywiththesingletonclassclass这只是冰山一角,因为我还没有探索instance_eval、module_eval和define_method的各种组合。是否有在线/离线资
我注意到类定义,如果我打开classMyClass,并在不覆盖的情况下添加一些东西我仍然得到了之前定义的原始方法。添加的新语句扩充了现有语句。但是对于方法定义,我仍然想要与类定义相同的行为,但是当我打开defmy_method时似乎,def中的现有语句和end被覆盖了,我需要重写一遍。那么有什么方法可以使方法定义的行为与定义相同,类似于super,但不一定是子类? 最佳答案 我想您正在寻找alias_method:classAalias_method:old_func,:funcdeffuncold_func#similartoca
我有带有Logo图像的公司模型has_attached_file:logo我用他们的Logo创建了许多公司。现在,我需要添加新样式has_attached_file:logo,:styles=>{:small=>"30x15>",:medium=>"155x85>"}我是否应该重新上传所有旧数据以重新生成新样式?我不这么认为……或者有什么rake任务可以重新生成样式吗? 最佳答案 参见Thumbnail-Generation.如果rake任务不适合你,你应该能够在控制台中使用一个片段来调用重新处理!关于相关公司
我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我正在开发一个创建网络博客的RubyonRails项目。我希望将一个名为featured的boolean数据库字段添加到Post模型中。该字段应该可以通过我添加的事件管理界面进行编辑。我使用了以下代码,但我什至没有在网站上显示另一列。$railsgeneratemigrationaddFeaturedfeatured:boolean$rakedb:migrate我是RubyonRails的新手,非常感谢任何帮助。我的index.html.erb文件中的相关代码(views):FeaturedPost架构.rb:ActiveRecord::Schema.define(:version=>