2013-04-21 4 views
2

Обновление: теперь я могу нарисовать несколько текстур, я понял, как работает glGenTextures и перезаписывает функцию loadtextures() и прочее. Однако нарисованы только несколько частей автомобиля; рулевое колесо, один колпачок ступицы и задние фонари (и, возможно, несколько мелких предметов). В файле collada несколько материалов никогда не ассоциируются с файлом текстуры. Я не думаю, что это проблема, потому что с первого раза я связал текстуры в списке с первой парой полилистов (5, всего 80), и я получил хороший автомобиль, который выглядел так, будто он использовал правильные текстуры, просто отсутствующие шины и, может быть, некоторые мелочи, которые я не заметил. Я думаю, может быть, это имеет какое-то отношение к текстурам, которые выломаны? В любом случае я хотел заменить все сетки, у которых нет файлов текстур с красным цветом, но я не уверен, как это сделать. Я начал использовать код в этом учебнике:Использование нескольких текстур в OpenGL

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

Я сделал буфер цветов, обвили его, и т.д., но потом я понял, что нужно отредактировать файлы шейдеров, и я не знаю, как сделать это.

One:

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, чтобы удерживать позиции и текс-координаты.

То, что я смог сделать до сих пор, - это нарисовать все биты, перейдя по карте и просто используя первый файл текстуры на карте (он сработает через несколько минут, но я узнаю об этом позже, Я просто рад, что что-то появилось на экране). Я попытался вызвать loadTextures() (и отправить в 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 (есть много больше, где она открывает файл и считывает через биты и т.д.)

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++; 

ответ

0

Там нет хорошего способа переключения текстур в середине рендеринга. Что вам нужно сделать, это разделить сетки по текстуре (материал), нарисовать их отдельно и переключить текстуру (и, возможно, равномерные значения для материала) между вызовами рисования с помощью glBindTexture(GL_TEXTURE_2D, id).

+0

Где в коде я бы перезвонил glBindTexture? В функции рисования? Я получаю только что-то на экране, если LoadTextures() вызывается в верхней части функции рисования или перед ней. Возможно ли перезаписать LoadTextures() для работы при вызове во время функции рисования? – Erin

0

Поздравляем с парсером Collada; это сложная задача; есть сторонние инструменты, которые вы можете использовать, которые делают это для вас, но я уверен, что это была хорошая практика и научиться делать это самостоятельно.

Что касается ваших текстур, одним из вариантов является использование текстурного атласа, в котором вы объединяете текстуры в единую текстуру, тогда вам нужно только привязать ее один раз и использовать разные координаты текстуры, что позволит вам нарисовать все ваши объекты, не делая любые изменения текстуры. Атлас текстуры поиска.

+0

Спасибо, я посмотрю, что и дайте знать, могу ли я использовать его, чтобы исправить мою проблему :-) – Erin

Смежные вопросы