Opengl: Как мне текстурировать модель, созданную с помощью массива вершин?

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

Вот код, который у меня есть:

GLfloat vertices[] = { 1, 1, 1,  -1, 1, 1,  -1,-1, 1,   1,-1, 1,   // v0,v1,v2,v3 (front)
1, 1, 1,   1,-1, 1,   1,-1,-1,   1, 1,-1,   // v0,v3,v4,v5 (right)
1, 1, 1,   1, 1,-1,  -1, 1,-1,  -1, 1, 1,   // v0,v5,v6,v1 (top)
-1, 1, 1,  -1, 1,-1,  -1,-1,-1,  -1,-1, 1,   // v1,v6,v7,v2 (left)
-1,-1,-1,   1,-1,-1,   1,-1, 1,  -1,-1, 1,   // v7,v4,v3,v2 (bottom)
1,-1,-1,  -1,-1,-1,  -1, 1,-1,   1, 1,-1 }; // v4,v7,v6,v5 (back)

// normal array
GLfloat normals[]  = { 0, 0, 1,   0, 0, 1,   0, 0, 1,   0, 0, 1,   // v0,v1,v2,v3 (front)
1, 0, 0,   1, 0, 0,   1, 0, 0,   1, 0, 0,   // v0,v3,v4,v5 (right)
0, 1, 0,   0, 1, 0,   0, 1, 0,   0, 1, 0,   // v0,v5,v6,v1 (top)
-1, 0, 0,  -1, 0, 0,  -1, 0, 0,  -1, 0, 0,   // v1,v6,v7,v2 (left)
0,-1, 0,   0,-1, 0,   0,-1, 0,   0,-1, 0,   // v7,v4,v3,v2 (bottom)
0, 0,-1,   0, 0,-1,   0, 0,-1,   0, 0,-1 }; // v4,v7,v6,v5 (back)

// color array
GLfloat colors[]   = { 1, 1, 1,   1, 1, 0,   1, 0, 0,   1, 0, 1,   // v0,v1,v2,v3 (front)
1, 1, 1,   1, 0, 1,   0, 0, 1,   0, 1, 1,   // v0,v3,v4,v5 (right)
1, 1, 1,   0, 1, 1,   0, 1, 0,   1, 1, 0,   // v0,v5,v6,v1 (top)
1, 1, 0,   0, 1, 0,   0, 0, 0,   1, 0, 0,   // v1,v6,v7,v2 (left)
0, 0, 0,   0, 0, 1,   1, 0, 1,   1, 0, 0,   // v7,v4,v3,v2 (bottom)
0, 0, 1,   0, 0, 0,   0, 1, 0,   0, 1, 1 }; // v4,v7,v6,v5 (back)

// index array of vertex array for glDrawElements() & glDrawRangeElement()
GLubyte indices[]  = { 0, 1, 2,   2, 3, 0,      // front
4, 5, 6,   6, 7, 4,      // right
8, 9,10,  10,11, 8,      // top
12,13,14,  14,15,12,      // left
16,17,18,  18,19,16,      // bottom
20,21,22,  22,23,20 };    // back

// Initialization routine.
void setup(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST); // Enable depth testing.}

// Drawing routine.
void drawScene()
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

// enable and specify pointers to vertex arrays
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glNormalPointer(GL_FLOAT, 0, normals);
glColorPointer(3, GL_FLOAT, 0, colors);
glVertexPointer(3, GL_FLOAT, 0, vertices);

glPushMatrix();
glTranslatef(0, 0, -5);

glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, indices);

glPopMatrix();

glDisableClientState(GL_VERTEX_ARRAY);  // disable vertex arrays
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);

glutSwapBuffers();
}

// OpenGL window reshape routine.
void resize (int w, int h)
{
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (float)w/(float)h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
}

// Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
exit(0);
break;
default:
break;
}
}

// Callback routine for non-ASCII key entry.
void specialKeyInput(int key, int x, int y)
{
//if(key == GLUT_KEY_UP) if (step < 180) step++;;
//if(key == GLUT_KEY_DOWN) if (step > 0) step--;;
glutPostRedisplay();
}

// Routine to output interaction instructions to the C++ window.
void printInteraction(void)
{
cout << "Interaction:" << endl;
}

// Main routine.
int main(int argc, char **argv)
{
printInteraction();
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("sphereInBox2.cpp");
setup();
glutDisplayFunc(drawScene);
glutReshapeFunc(resize);
glutKeyboardFunc(keyInput);
glutSpecialFunc(specialKeyInput);
glutMainLoop();

return 0;
}

Этот код создаст куб, поэтому я хотел бы знать, как текстурировать каждую сторону индивидуально и как текстурировать всю модель с 1 текстурой. Чтобы вы посоветовали?

3

Решение

Сначала вы должны указать координаты текстуры, которые можно определить как массив — точно так же, как вы уже использовали вершины, нормали и цвета.

GLfloat texcoords[] = {
0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
};

Для каждого вершина из лицо из куб Вы должны предоставить координаты UV, которые соответствуют некоторому размещению на текстуре. Вы должны предоставить координаты для всех 6 сторон, и большую часть времени они будут в другом порядке.

введите описание изображения здесь

Затем вам придется загрузить текстуру, используя другую библиотеку, например ПОЧВА. Он вернет вам указатель на пиксели, которые вы можете позже передать OpenGL.

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

glGenTextures(1, &testTexture);
glBindTexture(GL_TEXTURE_2D, testTexture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGB, size, size, 0, GL_RGB, GL_FLOAT, &texData[0]
);

Для окончательного рендеринга с этой текстурой вы должны связать ее как активную текстуру:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, testTexture);

Вы почти закончили! Но эта часть, пожалуй, самая сложная. Вам нужно будет загрузить свои шейдеры, создать программу, скомпилировать ее с помощью шейдеров и начать использовать программу. Как только это будет сделано, вы просто передадите свою текстуру как равномерный пробоотборник к программе.

8

Другие решения


По вопросам рекламы [email protected]