OpenGL Применение текстуры к тесселяции

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

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

Вот как я загружаю текстуру:

    GLuint texture;
int width, height;
BYTE * data;
FILE * file;

// open texture data
file = fopen( filename, "rb" );
if ( file == NULL ) return 0;

// allocate buffer
width = 256;
height = 256;
data = (BYTE *)malloc( width * height * 3 );

// read texture data
fread( data, width * height * 3, 1, file );
fclose( file );

glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap ? GL_REPEAT : GL_CLAMP );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap ? GL_REPEAT : GL_CLAMP );

gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width,height, GL_RGB, GL_UNSIGNED_BYTE, data );

free( data );

return texture;

Вот тесселяционная функция:

GLuint tessellate1()
{
GLuint id = glGenLists(1);  // create a display list
if(!id) return id;          // failed to create a list, return 0

GLUtesselator *tess = gluNewTess(); // create a tessellator
if(!tess) return 0;  // failed to create tessellation object, return 0

GLdouble quad1[4][3] = { {-1,3,0}, {0,0,0}, {1,3,0}, {0,2,0} };

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, GLTexture::LoadTextureRAW("texture.raw", true));

// register callback functions
gluTessCallback(tess, GLU_TESS_BEGIN, (void (CALLBACK *)())tessBeginCB);
gluTessCallback(tess, GLU_TESS_END, (void (CALLBACK *)())tessEndCB);
gluTessCallback(tess, GLU_TESS_ERROR, (void (CALLBACK *)())tessErrorCB);
gluTessCallback(tess, GLU_TESS_VERTEX, (void (CALLBACK *)())tessVertexCB);

glNewList(id, GL_COMPILE);
glColor3f(1,1,1);
gluTessBeginPolygon(tess, 0);                   // with NULL data
gluTessBeginContour(tess);
gluTessVertex(tess, quad1[0], quad1[0]);
gluTessVertex(tess, quad1[1], quad1[1]);
gluTessVertex(tess, quad1[2], quad1[2]);
gluTessVertex(tess, quad1[3], quad1[3]);
gluTessEndContour(tess);
gluTessEndPolygon(tess);
glEndList();

gluDeleteTess(tess);        // delete after tessellation

glDisable(GL_TEXTURE_2D);

setCamera(0, 0, 5, 0, 0, 0);

return id;      // return handle ID of a display list
}

Вот функция обратного вызова вершины тесселяции:

// cast back to double type
const GLdouble *ptr = (const GLdouble*)data;

double dImageX = -1, dImageY = -1;

//hardcoded extents of the polygon for the purposes of testing
int minX = 607011, maxX = 616590;
int minY = 4918219, maxY = 4923933;

//get the % coord of the texture for a poly vertex.  Assumes image and poly bounds are the same for the purposes of testing
dImageX = (ptr[0] - minX) / (maxX - minX);
dImageY = (ptr[1] - minY) / (maxY - minY);

glTexCoord2d(dImageX, dImageY);
glVertex2d(ptr[0], ptr[1]);

И вот обратный вызов дисплея:

void displayCB()
{
// clear buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

// save the initial ModelView matrix before modifying ModelView matrix
glPushMatrix();

// tramsform camera
glTranslatef(0, 0, cameraDistance);
glRotatef(cameraAngleX, 1, 0, 0);   // pitch
glRotatef(cameraAngleY, 0, 1, 0);   // heading

// draw meshes
glCallList(listId1);  //id of the tessellated poly

// draw info messages
showInfo();

glPopMatrix();

glutSwapBuffers();
}

Результатом этого является правильно нарисованный многоугольник без текстуры.

1

Решение

// init
glGenTextures( 1, &texture );

// vertex callback
glBindTexture(GL_TEXTURE_2D, 1);

Я не думаю, что первое удостоверение личности возвращается glGenTextures() должен быть 1,

Попробуйте использовать texture вместо 1 в вашем glBindTexture() вызов.

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

1

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

Вы не фиксируете привязку текстуры и включаете ее внутри списка отображения, поэтому она не будет учитываться при ее воспроизведении. Итак, либо:

  • Захват BindTexture и Включить в списке отображения, или
  • BindTexture и Enable (TEXTURE_2D) перед вызовом CallList
1

Проблема заключалась в вызове glDisable (GL_TEXTURE_2D) в функции тесселяции. После удаления текстура была применена правильно.

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