Обновление: теперь я могу нарисовать несколько текстур, я понял, как работает 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++;
Где в коде я бы перезвонил glBindTexture? В функции рисования? Я получаю только что-то на экране, если LoadTextures() вызывается в верхней части функции рисования или перед ней. Возможно ли перезаписать LoadTextures() для работы при вызове во время функции рисования? – Erin