簡體   English   中英

在OpenGL中使用多個紋理

[英]Using multiple textures in OpenGL

更新:我現在可以繪制多個紋理,弄清楚glGenTextures等如何工作,並重寫了loadtextures()函數和其他東西。 但是,只繪制了汽車的一些零件。 方向盤,一個輪轂蓋和后燈(也許還有一些小東西)。 在collada文件中,一些材質永遠不會與紋理文件關聯。 我不認為這是問題所在,因為在我第一次嘗試時,我便將列表中的紋理與前兩個多列表關聯起來(5個,總共有80個),並且我得到了一輛看起來像是在使用正確的紋理,只是缺少輪胎,也許還有一些我沒有注意到的小東西。 我認為也許與平鋪的紋理有關? 無論如何,我想用紅色替換所有沒有紋理文件的網格,但是我不確定該怎么做。 我在本教程中開始使用代碼:

http://www.opengl-tutorial.org/beginners-tutorials/tutorial-4-a-colored-cube/

我做了一個顏色緩沖區,將它綁定等等,但是后來我意識到我需要編輯着色器文件,但我不確定該怎么做。

一:

attribute vec3 vPosition;
attribute vec2 vTextureCoord;
varying  vec2 vTexCoord; 
uniform  mat4 modelview_matrix;

void main(void)  
{     
   vTexCoord =  vTextureCoord;
   gl_Position =  modelview_matrix*vec4(vPosition,1.0);
}

另一個:

varying  vec2 vTexCoord; 
uniform sampler2D myTexture;
void main (void)  
{  
   gl_FragColor =  texture2D(myTexture, vTexCoord);     
}

/////原始問題

我正在做一個uni作業,其中我將不得不繪制一些帶有紋理的對象(而且我必須能夠在場景和東西周圍移動,但是當我到達它時,我將越過那座橋)。 我有一個教程作為基礎,它將從單個頂點數組和單個紋理文件(從.obj文件)繪制對象(我為上一教程編寫了解析器)。

該作業使用collada文件,因此我編寫了collada解析器。 這真的很辛苦! 我的collada解析器生成了一個包含Material對象的映射,該對象具有很多名稱和id變量(在main.cpp中未使用,它們僅用於在collada文件的各個部分之間關聯內容),一個m_TgaFile變量,用於保存紋理文件名稱為字符串,以及一個m_Mesh變量,該變量保存一個Vertex對象的矢量,該對象只有兩個浮點數組,即m_Positions和m_Textures,用於保存位置和tex坐標。

因此,到目前為止,我能夠做的是通過遍歷地圖並僅使用地圖中的第一個紋理文件來繪制所有位(幾分鍾后崩潰,但我會發現以后很高興屏幕上出現了一些東西)。 我嘗試在地圖上循環調用loadTextures()(並發送一個Material),以便可以使用每個Material的紋理文件,但一點都沒畫(白屏)。 那么,如何為繪圖的每一位加載每種紋理?

我已經嘗試研究它,並且得出一個事實,我需要使用glBindTexture,glTexImage2D和我不記得的另一個。 前兩個在我的教程隨附的TgaParser中。 在繪圖代碼中再次使用glBindTexture,第二個參數為零。 根據我的收集,這意味着使用已加載的默認紋理。 我無法弄清楚如何在需要時加載每個紋理,我不了解紋理名稱的含義以及將其與紋理數據關聯的方式。

哦,我嘗試過在OpenGl主函數中進行循環,並將pMaterial作為變量發送到顯示函數,但它不是那樣的,我認為它不會起作用,但我認為我至少會嘗試。

這是一些代碼。

OpenGL主要功能:

int main(int argc, char **argv)
{

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

glutInitWindowSize(screenWidth, screenHeight);
glutCreateWindow("Intro to shading");
glewInit();

init();
glutDisplayFunc(forward_display);
glutIdleFunc(forward_animate);

glutMainLoop();
/*
    DONT DO THINGS HERE
*/
return 0;
}

繪圖功能:

void forward_display()
{
glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

//glScalef(0.5,0.5,0.5);
glScalef(0.005,0.005,0.005);
glRotatef(timeGetTime()*0.01,0,1,0);
GLfloat m[16];
glGetFloatv (GL_MODELVIEW_MATRIX, m);
glUniformMatrix4fv(gvModelMatrixHandle,1,false,m);


glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,0);

colladaObject->m_MaterialMap.StartIterator ();

while(!colladaObject->m_MaterialMap.IsEOM ())
{
    shared_ptr<Material> pMaterial = colladaObject->m_MaterialMap.Get ();

    if(pMaterial->m_Mesh.size () != 0)
    {
        glVertexAttribPointer(gvPositionHandle, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), &pMaterial->m_Mesh[0].m_Positions);//v[0].pos

        glEnableVertexAttribArray(gvPositionHandle);

        glVertexAttribPointer(gvTextureCoordhandle, 2, GL_FLOAT, GL_FALSE,sizeof(Vertex), &pMaterial->m_Mesh[0].m_Textures);//&v[0].texCoords
        glEnableVertexAttribArray(gvTextureCoordhandle);

        glDrawArrays(GL_TRIANGLES, 0, pMaterial->m_Mesh.size());
    }
    colladaObject->m_MaterialMap.MoveNext ();
}

glutSwapBuffers();
}

初始化函數:

void init()
{
char  * vertexShaderBuffer =       readFileData("../resources/shaders/IntroToShaders.vs");
char  * pixelShaderBuffer  =   readFileData("../resources/shaders/IntroToShaders.ps");

gProgram = createProgram(vertexShaderBuffer, pixelShaderBuffer);

//We have finished  compiling the shader now delete the char arrays with the source code
delete [] vertexShaderBuffer;
delete [] pixelShaderBuffer;

gvPositionHandle        = glGetAttribLocation(gProgram, "vPosition");
gvTextureCoordhandle    = glGetAttribLocation(gProgram, "vTextureCoord");
gvModelMatrixHandle     = glGetUniformLocation(gProgram, "modelview_matrix");
if (gvPositionHandle==-1)
    printf("gvPositionHandle is bad\n");

if (gvTextureCoordhandle==-1)
    printf("gvTextureCoordhandle is bad\n");

if (gvModelMatrixHandle==-1)
    printf("gvModelMatrixHandle is bad\n");
glUseProgram(gProgram);

//cube = new ObjParser("../resources/mesh/cube.obj");
colladaObject = new ColladaParser("../resources/mesh/car.dae");
loadTextures();

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

loadTextures函數:

void loadTextures ()
{
//just try loading the first texture to make sure all the other code changes work before playing with this one.
colladaObject->m_MaterialMap.StartIterator ();
shared_ptr<Material> pMaterial = colladaObject->m_MaterialMap.Get ();
while(pMaterial->m_TgaFile == "")
{
    colladaObject->m_MaterialMap.MoveNext ();
    pMaterial = colladaObject->m_MaterialMap.Get ();
}

char tgafile [100];
strcpy(tgafile, "../resources/textures/");
strcat(tgafile, pMaterial->m_TgaFile.c_str ());
TgaParser explosion(tgafile);
}

TgaParser構造函數的END(實際上還有很多地方可以打開文件並讀取位等)

unsigned char * imageData = (unsigned char*)getData (fp, size, imageBits);
myId=id;

glBindTexture (GL_TEXTURE_2D, id);
    glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    /* glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); */
    glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
/* glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); */
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexImage2D (GL_TEXTURE_2D, 0, texFormat, imageWidth, imageHeight, 0, texFormat, GL_UNSIGNED_BYTE, imageData);

    /* release data, its been uploaded */
    free (imageData);

fclose(fp);

id++;

在渲染過程中沒有很好的方法來切換紋理。 您需要做的是按紋理(材質)分開網格,分別繪制它們,並使用glBindTexture(GL_TEXTURE_2D, id)在繪制調用之間切換紋理(以及材質的均勻值glBindTexture(GL_TEXTURE_2D, id)

恭喜您的Collada解析器; 當然,這是一項復雜的任務; 您可以使用第三方工具為您做到這一點,但是我敢肯定,這是一種很好的做法,需要您自己學習。

關於紋理,一種選擇是使用紋理圖集,將紋理組合成單個紋理,然后只需綁定一次並使用不同的紋理坐標,這將使您繪制所有對象而無需進行任何紋理更改。 查找紋理圖集。

暫無
暫無

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

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