簡體   English   中英

將紋理添加到由頂點構成的平面

[英]Adding texture to a plane made of vertices

我使用以下代碼在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();

現在我想在這個平面上應用紋理。

我在這里閱讀了這個教程但我已經停止了“在OpenGL中使用紋理”部分,因為我沒有UV坐標。

我知道我們必須導入紋理文件,在我的例子中是一個位圖文件。
加載器返回一個Glint,它是textureID,是全局的嗎? 在示例中,如果我需要加載該紋理,我只需要使用給定的ID調用綁定紋理函數?

無論如何,我怎樣才能將紋理應用到平面上?


編輯#1:現在發布的示例蚊子的紋理有效。
我發現的是我將紋理加載到類的構造函數中,我不應該因為該對象是公共的而且是在OpenGL初始化之前構造的。
所以紋理現在加載四個例子:)

現在的問題是我試圖在我的飛機上使用它,它看起來很扭曲。 對此的解決方案可能是將紋理加載多次,但保持原始大小(雖然我不知道如何做到這一點)

另外,我在當前的一個平面旁邊創建了另一個帶有奶油色的平面,但在紋理化之后它看起來像這樣: 在此輸入圖像描述

所以現在有兩個問題:

  • 紋理必須保持原始分辨率,但顯示覆蓋整個平面的次數
  • 它旁邊的飛機失去了它的顏色(為什么會發生這種情況?如何解決它? - 我也可以使用這個平面的紋理)

編輯#2:

由於蚊子,第2個問題現在已經解決了! 但是平鋪仍然不起作用。 這就是它現在的樣子: 在此輸入圖像描述

這是我用過的紋理:
在此輸入圖像描述
它的尺寸是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的加載器,它可能已經負責加載圖像數據,設置屬性並將其存儲為真正的紋理以供進一步使用。 所以我將繼續將紋理綁定到紋理目標。

如果你有這個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范圍以及為特定頂點設置的紋理坐標:

在此輸入圖像描述

PS。 為了顯示紋理,您必須首先通過調用以下方式啟用此功能:

glEnable(GL_TEXTURE_2D);

每次用紋理繪制對象時都不必調用它。 在繪圖之前可能只調用一次。


編輯

  1. 根據你的下一個問題:你想要的是實現平鋪效果,這可以在創建紋理時輕松完成。 在您的裝載機中,在此行之后:

    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相同,依此類推。

  2. 你的第二個問題是存在的,因為你仍然有你的紋理綁定並且你已經啟用了紋理(請記住你使用了glEnable(GL_TEXTURE_2D); ),所以基本上你現在繪制的所有內容都會被紋理所覆蓋。

    但是,如果你現在想要繪制一些沒有紋理的東西,你基本上必須在繪制第二個平面之前禁用紋理,並在繪制之后再次啟用它:

     glDisable(GL_TEXTURE_2D); // Draw your second plane here glEnable(GL_TEXTURE_2D); 

EDIT2

好吧,我覺得你誤解了我一點。 在這種情況下,平鋪無法工作,因為您指定紋理坐標最大為1.0,這是紋理的結束。 我准備了一張圖片,可以告訴你我的意思:

在此輸入圖像描述

在那些中間有紅色的圖片中,我標記了紋理坐標和黑色 - 頂點坐標。

所以基本上如果你像現在這樣設置你的紋理坐標(最大值為1.0),你可以讓你的紋理在你的平面上伸展。 現在想象一下這個平面非常大 - 如果紋理分辨率低,它只會造成丑陋的拉伸效果。

為了實現平鋪效果,你必須設置高於1.0的值,就像在我的例子中 - 2.0導致紋理重復兩次。

由於沒有神奇的方法可以讓你的紋理在飛機上看起來“漂亮”,你必須使用一些數學來實現它。 現在我留給你。

您需要為每個頂點指定一個uv坐標。 你可以使用函數glTexCoord2f();
該函數有兩個參數,第一個是你,另一個是v。你的繪圖代碼會變成這樣:

glBegin(GL_TRIANGLE_STRIP);
glColor4f(0.8, 0.8, 0.5, 1.0);
glTexCoord2f(0.0f, 0.0f); glVertex3f(startlen, height, startwid);
glTexCoord2f(0.0f, 1.0f); glVertex3f(startlen, height, startwid + width);
glTexCoord2f(1.0f, 1.0f); glVertex3f(startlen + length, height, startwid);
glTexCoord2f(1.0f, 0.0f); glVertex3f(startlen + length, height, startwid + width);
glEnd();

您可能會稍微切換它們,我不知道您想如何將紋理映射到它。 您可以在紋理上看到u為x,其中0.0 =左,1.0 =右,您可以在紋理上看到v為y,其中0.0 = top,1.0 = bottom。
現在,還有一些你需要的東西,首先,需要啟用紋理:

glEnable(GL_TEXTURE_2D); //call this once, during initialization

需要加載紋理,就像你已經說過的那樣:

glGenTextures(1, &MyTexture);
glBindTexture(GL_TEXTURE_2D, MyTexture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); //data is a gluByte array of your image data

在繪制四邊形之前必須綁定它:

glBindTexture(GL_TEXTURE_2D, MyTexture);

我會讓紋理的實際加載到你這里,因為這將是一個完全不同的問題,並在此廣泛討論。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM