как рисовать объект с диффузной текстурой после мультитекстурированного объекта

Я рисую один объект, используя мультитекстурирование. Это нормально, но когда я рисую другие объекты после этого, используя только диффузную текстуру, эта диффузная текстура привязывается к предыдущей текстуре. Я знаю, что мне нужно деактивировать блоки текстур, отличные от стандартных, и я должен сделать активным блок текстур в GL_TEXTURE0, но это не работает.

Вот мой код

glClientActiveTexture(GL_TEXTURE0); // first texture
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, stride, texCoordOffset);
glClientActiveTexture(GL_TEXTURE1); // second texture
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, stride, texCoordLightOffset);

// Enable 2D texturing for the first texture.
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);

// Enable 2D texturing for the second texture.
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);

// We are trying for the multi-textured lighting effect from the OpenGL
// ES 2.0 book, page  223, Figure 10-3. The relevant shader equation is
// basecolor * (lightcolor + 0.25), so we set the constant as a base colour
glColor4f(0.25f, 0.25f, 0.25f, 1.0f);


// Set the light map has the current texture
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,m_new_tex);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,5.0f);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

// add the light map to the constant 0.25
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);

// Now set the background map (bricks) and modulate (multiply)
glActiveTexture(GL_TEXTURE1);
// we'll keep this code here as _texSelection will never be our lightmap
glBindTexture(GL_TEXTURE_2D, m_sky);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 5.0f);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

/* Set the texture environment mode for this texture to combine */
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);

/* Set the method we're going to combine the two textures by. */
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);

/* Use the previous combine texture as source 0*/
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);

/* Use the current texture as source 1 */
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);

/*
 Set what we will operate on, in this case we are going to use
 just the texture colours.
 */
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);


glBindBuffer(GL_ARRAY_BUFFER, drawable.VertexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drawable.IndexBuffer);

glDrawElements(GL_TRIANGLES, drawable.IndexCount, GL_UNSIGNED_SHORT, 0);

glDisable(GL_TEXTURE_2D);

Для простой диффузной текстуры, какие команды я должен написать перед привязкой текстуры?

Любой другой пример кода будет полезен.


person rocksvick    schedule 08.11.2011    source источник
comment
Получается, что мультитекстурирование работает? Кстати, состояние, измененное glTexParameter, является состоянием текстуры, а не состояния устройства, поэтому вам не нужно менять его каждый кадр, а только после создания текстуры.   -  person Christian Rau    schedule 08.11.2011


Ответы (1)


Прежде всего, вам нужно отключить текстурирование (glDisable(GL_TEXTURE_2D)) для каждого неиспользуемого текстурного блока, что вы уже делаете. И, конечно, вы также должны отключить массив координат текстуры для неиспользуемых текстурных модулей, поэтому вызовите glDisableClientState(GL_TEXTURE_COORD_ARRAY), когда активен второй текстурный модуль (после вызова glClientActiveTexture(GL_TEXTURE1)).

И когда вы закончите с мультитекстурированием, вам, конечно же, придется вызывать glActiveTexture(GL_TEXTURE0) и glClientActiveTexture(GL_TEXTURE0). В противном случае все следующие операции с текстурами применяются к текстурному блоку 1 вместо 0.

Но все это уже было сказано в моем ответе на другой ваш вопрос. Вы хоть это читали?

EDIT: И, кстати, состояние, измененное glTexParameter, сохраняется для каждого объекта текстуры, а не для единицы. Таким образом, вам не нужно вызывать их каждый кадр, достаточно одного раза после создания текстуры.

person Christian Rau    schedule 08.11.2011
comment
@rocksvick Если ответ был решением вашей проблемы, мы будем признательны за его принятие. Или я неправильно понял ваш комментарий, и вы сами решили его (хотя я сомневаюсь, что решение будет существенно отличаться от моего)? - person Christian Rau; 09.11.2011
comment
спасибо за ответ, и да, проблема была решена до того, как пришел ваш ответ... кстати, спасибо. - person rocksvick; 10.11.2011
comment
другие объекты визуализируются отлично, но когда я пытаюсь визуализировать объект в конце, который использует смешивание (объекты - это деревья, которые прозрачны), они не остаются прозрачными, вместо этого на этих объектах появляется текстура текстуры unit0 .. можете ли вы предложить некоторые решение ? - person rocksvick; 12.11.2011
comment
@rocksvick Трудно ответить. Но, как правило, всегда устанавливайте все необходимые состояния перед рендерингом и восстанавливайте его после рендеринга. OpenGL — это конечный автомат, в котором каждое состояние сохраняет свое значение до тех пор, пока вы не измените его снова. И он также не знает, что такое кадр рендеринга, и, конечно, сохраняет свое состояние между кадрами. - person Christian Rau; 12.11.2011
comment
Спасибо за ответ. у меня есть одно сомнение. я использовал glTexEnv во время мультитекстурирования. Когда я закончу мультитекстурирование, после отключения текстурного модуля 1 и активации текстурного модуля 0, нам нужно сбросить glTexEnv? если да то как это сделать? - person rocksvick; 13.11.2011
comment
@rocksvick Среда текстуры является состоянием для каждого устройства, поэтому при активации единицы 0 она имеет те же значения, которые вы установили в прошлый раз, когда вы вызывали glTenEnv, когда единица текстуры 0 была активна. - person Christian Rau; 13.11.2011