LINUX.ORG.RU

OpenGL ES2, передача текстур в шейдер


0

1

Вот код с двумя текстурами:


GLuint _textures[2];

glEnable(GL_TEXTURE_2D);
		
glGenTextures(2, _textures);
glActiveTexture(GL_TEXTURE0);
bump = [self loadTextureWithName: @"normal.jpg"];
//bump = [self loadTextureWithName: @"specular.jpg"];
glUniform1i(bump, 0);
		
glActiveTexture(GL_TEXTURE1);
diffuse = [self loadTextureWithName2: @"diffuse.jpg"];
glUniform1i(diffuse, 0);

Функции loadTextureWithName делают следующее:

- (GLuint) loadTextureWithName: (NSString*) filename{
	
	CGImageRef textureImage = [UIImage imageNamed: filename].CGImage;
	NSInteger texWidth = CGImageGetWidth(textureImage);
	NSInteger texHeight = CGImageGetHeight(textureImage);
	GLubyte *textureData =  (GLubyte *)malloc(texWidth * texHeight * 4*sizeof(GLubyte));
	memset((void*) textureData, 0, texWidth * texHeight * 4*sizeof(GLubyte));
	CGContextRef textureContext = CGBitmapContextCreate(textureData,texWidth,texHeight,8, texWidth * 4,CGImageGetColorSpace(textureImage),kCGImageAlphaPremultipliedLast);
	
	CGContextDrawImage(textureContext,CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight),textureImage);
	
	CGContextRelease(textureContext);
	//glActiveTexture(GL_TEXTURE0);
	//glShadeModel(GL_FLAT);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	
	//glGenTextures(1, &TEX);
	glBindTexture(GL_TEXTURE_2D, _textures[0]);
	
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
	free(textureData);
	//texId = [NSNumber numberWithInt:TEX];
	//[textureImage release];//
	//[textureContext release];//
	return _textures[0];
}

- (GLuint) loadTextureWithName2: (NSString*) filename{
	
	CGImageRef textureImage = [UIImage imageNamed: filename].CGImage;
	NSInteger texWidth = CGImageGetWidth(textureImage);
	NSInteger texHeight = CGImageGetHeight(textureImage);
	GLubyte *textureData =  (GLubyte *)malloc(texWidth * texHeight * 4*sizeof(GLubyte));
	memset((void*) textureData, 0, texWidth * texHeight * 4*sizeof(GLubyte));
	CGContextRef textureContext = CGBitmapContextCreate(textureData,texWidth,texHeight,8, texWidth * 4,			CGImageGetColorSpace(textureImage),kCGImageAlphaPremultipliedLast);
	
	CGContextDrawImage(textureContext,CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight),textureImage);
	
	CGContextRelease(textureContext);
	//glActiveTexture(GL_TEXTURE1);
	//glShadeModel(GL_FLAT);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	
	//glGenTextures(1, &TEX);
	glBindTexture(GL_TEXTURE_2D, _textures[1]);
	
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
	free(textureData);

	return _textures[1];
}

Проблема в том, что у нас в шейдере две переменные типа sampler2D. И какую текстуру я бы не подставлял, все равно получаю первую с изображением normal.jpg. Буду очень признателен за помощь. Заранее спасибо.


Наверное нужно сделать glEnable(GL_TEXTURE_2D) и на втором TMU тоже?

Deleted
()

> glUniform1i(diffuse, 0);

glUniform1i(bump, 0);

Ты привязываешь один и тот-же 0-ой текстурный юнит ( с bump текстурой -

glActiveTexture(GL_TEXTURE0); bump = [self loadTextureWithName: @«normal.jpg»];

) к разным униформам.

Исправь glUniform1i(diffuse, 0) на glUniform1i(diffuse, 1);

rip86oz
()
Ответ на: комментарий от ECLIPSE

Поленился и не посмотрел весь код.

Конечно не заработает. :-) Ещё повезло, что и одна-то «заработала», стала показываться.

Советую почитать как устроен и работает опенЖЛ.

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

//glActiveTexture(GL_TEXTURE0);

и др.

Сейчас ошибка именно в передаче этих текстурных юнитов (0-ого и 1-ого). В щейдере каждая униформ переменная умеет своё место\адрес - location. Этот «адрес» должен указываться первым параметром в функциях установки значения униформы - glUniform. Т.е. у тебя в glUniform1i(bump, 0) это переменная bump. Но в bump у тебя хранится не адрес униформы в шейдере, а идентификатор текстуры - который ты возвращаешь из функции loadTextureWithName.

Чтобы узнать адрес униформы используй функцию glGetUniformLocation.

rip86oz
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.