Проблемы с MIP-картой OpenGL

У меня мипмэппинг работает нормально. Но по какой-то причине после того, как я наложил текстуру, все остальные объекты в моем приложении приобретают цвет, который кажется средним цветом текстуры. Даже HUD. Есть ли что-то, что мне нужно учитывать? Вот код:

GLuint LoadTexture( const char * filename, int width, int height )
{
    GLuint texture;
    unsigned char * data;
    FILE * file;

    file = fopen( filename, "rb" );
    if ( file == NULL ) return 0;
    data = (unsigned char *)malloc( width * height * 3 );
    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_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR );

    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

    gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data ); 
    free( data );
    return texture;
}

Это вызывается перед циклом и освобождается после слов. Эта следующая часть кода происходит внутри моего цикла while. Он вызывается перед всеми остальными объектами сцены.

void makeGround() {

    glBindTexture( GL_TEXTURE_2D, texture );

    GLfloat mat_specular[]      = { 0.5, 0.5, 0.5, 1.0 };
    GLfloat mat_diffuse[]       = { 0.8, 0.8, 0.8, 1.0 };
    GLfloat mat_shininess[]     = { 100.0 };

    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

    //glColor3f(1.0, 1.0, 1.0);

    glPushMatrix();
        glTranslatef(-(size/2), 0.0f, -(size/2));
        glCallList(LIST1);
    glPopMatrix();
}

Что я должен делать между рисованием разных элементов, чтобы этого не произошло?


person grep    schedule 01.12.2011    source источник
comment
Два комментария: 1) не должен ли языковой тег быть c? В этом коде не так много С++. 2) Я очень надеялся, что фиксированный конвейер и все остальное, удаленное из opengl, уже мертво и похоронено. По крайней мере, я бы не стал больше рассчитывать на то, что эти вещи будут очень оптимизированы для нового оборудования и драйверов.   -  person Grizzly    schedule 02.12.2011
comment
Вы не можете использовать LINEAR_MIPMAP_LINEAR с TEXTURE_MAG_FILTER. В любом случае это не имеет смысла; TEXTURE_MAG_FILTER означает увеличение: сделать текстуру больше, чем базовый слой (самый большой слой в цепочке mipmap). Вы не можете использовать мип-карты, которые больше базового слоя, поэтому вы не можете фильтровать мип-карты с помощью TEXTURE_MAG_FILTER. Возможно, это не ваша проблема, но вы все равно должны это знать.   -  person Nicol Bolas    schedule 02.12.2011
comment
@Grizzly: Мертв или похоронен? Ты смеешься? Люди, которые используют OpenGL, делают это только потому, что либо 1) они учатся на онлайн-ресурсе, который почти наверняка не основан на шейдерах, 2) они используют старую кодовую базу на основе OpenGL, которая также не основана на шейдерах. или 3) они занимаются кроссплатформенной разработкой. А поскольку так много учебных ресурсов GL имеют фиксированную функцию, то и их кроссплатформенные пользователи тоже будут.   -  person Nicol Bolas    schedule 02.12.2011
comment
@Nicol Bolas: Ха, на самом деле все три. Не удалось найти хороших ресурсов по GLSL. Но я действительно стремлюсь к кросс-платформенной совместимости.   -  person grep    schedule 02.12.2011
comment
@Nicol Bolas: На мой взгляд, ваш первый пункт — это наиболее распространенный сценарий, приводящий к использованию устаревшей части opengl, поэтому мне нравится хотя бы упоминать, что эти части немного устарели, когда я говорю об opengl (в надежде на некоторые люди, изучая его, переключатся на более современные функции). По моему опыту, изучение этого с помощью фиксированного конвейера часто приводит к проблемам при попытке попробовать более сложные вещи, где было бы проще использовать шейдеры. Головоломка: правда? Я бы подумал, что такие существуют. К сожалению, я узнал от нескольких немецких сторон, поэтому я не могу предоставить английский ресурс.   -  person Grizzly    schedule 02.12.2011
comment
Я не не согласен с вами; В конце концов, я пишу это руководство. Я вношу свой вклад в обеспечение лучших ресурсов GL. Я хочу сказать, что ваши ожидания ошибочны, пока NeHe и другие сайты онлайн и работают.   -  person Nicol Bolas    schedule 02.12.2011


Ответы (1)


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

person Grizzly    schedule 01.12.2011
comment
Если я рисую землю, то отключаю 2D-текстуру, прежде чем рисовать что-либо еще, это просто предотвратит текстурирование пола. - person grep; 02.12.2011
comment
Так что, если вы отключите текстурирование после рисования земли (и снова включите его перед рисованием земли в следующий раз, земля не будет текстурирована? Это кажется немного странным, не забудьте рассказать немного больше о том, что именно вы делаете (показывая, где вы включаете/отключаете текстурирование). и так далее) - person Grizzly; 02.12.2011
comment
Ах, знаете что, в какой-то момент я закомментировал повторное включение. Спасибо! это решило мою проблему. - person grep; 02.12.2011
comment
Я примерно так и предполагал (поэтому и упомянул об этом). Так что добро пожаловать. Если вы пишете на С++, я бы предложил использовать для этого RAII, поэтому напишите класс, который включает его в конструкторе и отключает в деструкторе (надуманный пример, который я знаю, на самом деле может подойти что-то более гибкое). - person Grizzly; 02.12.2011
comment
В начале моего цикла я вызываю функцию сброса, которая очищает буфер цвета и глубины, загружает идентичность и т. д. Поэтому я добавил к этому включение текстуры и просто отключил ее в конце функции, рисующей пол. В конце концов я надеюсь сделать что-то более надежное, например, класс списка отображения, который справится с этим за меня. Спасибо за совет! - person grep; 02.12.2011