2015-01-03 3 views
3

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

+0

Вам нужен массив текстурных координат, который будет отображаться на одной развернутой текстуре, содержащей все 6 граней вашего куба. Найдите 'УФ-картографирование' и' распаковка', это ключевые слова метода –

+0

Если я скажу вам 'glEnableClientState (GL_TEXTURE_COORD_ARRAY)' и 'glTexCoordPointer', это даст вам подсказку? ;-) – datenwolf

+0

@ datenwolf \t Я добавил оба из них в свой проект. Я сделал переменную texcoord для указателя координат, но я не вижу разницы. Что мне не хватает? – WhyYouNoWork

ответ

8

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

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

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

enter image description here

Вам будет нужно загрузить текстуру, используя другие библиотеки, как SOIL. Он вернет вам указатель на пиксели, которые вы можете позже передать 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); 

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

+0

Боюсь, что вы меня потеряли. Я понимаю текстуру. Требуется написать текстуру на лицо, и я понимаю, и она отображает определенный процент изображения. У меня есть несколько функций для загрузки png: codepad.org/ygG2U0cF. Однако я не знаю, что делать дальше. glActiveTexture не определено, и ваш последний абзац после этого прошел через мою голову. Не могли бы вы подробнее остановиться? – WhyYouNoWork

+0

@WhyYouNoWork Возможно, я мог бы отнести вас к [этому превосходному учебнику] (http://learnopengl.com/#!Getting-started/Textures)? – Iggy

+0

Я читаю учебник, но я застрял. Я не понимаю, как заставить SOIL работать. Я не могу заставить любой из файлов, включенных в него, запускаться. Он продолжает говорить мне, что файл развращает, когда я пытаюсь их преобразовать. Что происходит? – WhyYouNoWork

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