OpenGL:ios 上的 MultiTexture 行为异常
OpenGL: MultiTexture misbehaving on ios
我在向片段着色器发送多个纹理时遇到问题。附件是准系统测试脚本。我正在使用 GLProgram 脚本来加载着色器 (http://iphonedevelopment.blogspot.com.au/2010/11/opengl-es-20-for-ios-chapter-4.html)。
您会在片段着色器中看到我只是使用 mix 将两个纹理组合在一起,但似乎我为 texture1 和 texture2 获得了相同的纹理。
// Extends GLKViewController
#import "ViewControllerImage.h"
#import <OpenGLES/ES2/glext.h>
#import "GLProgram.h"
typedef struct {
float Position[2];
float UV[2];
} VertexStruct;
const VertexStruct TestData[] = {
{{-1.0, 1.0},{0.0, 0.0}},
{{-1.0, -1.0},{0.0, 1.0}},
{{1.0, -1.0},{1.0, 1.0}}
};
const GLuint TestIndices[] = {
0,1,2
};
@implementation ViewControllerImage{
GLProgram *glProgram;
EAGLContext *context;
GLuint uvBuffer;
GLuint indexBuffer;
GLuint positionBuffer;
GLint positionID;
GLuint uvID;
GLint textureID1;
GLint textureID2;
int indiciesCount;
int vertexCount;
GLKTextureInfo *textureInfo1;
GLKTextureInfo *textureInfo2;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setupContext];
[self setupShaderProgram];
[self setupGL];
}
- (void) setupContext{
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:context];
GLKView *glkView = (GLKView *)self.view;
glkView.context = context;
}
-(void) setupShaderProgram{
glProgram = [[GLProgram alloc] initWithVertexShaderFilename:@"TestVertex" fragmentShaderFilename:@"TestFragment"];
//reguster Shader attributes
[glProgram addAttribute:@"position"];
[glProgram addAttribute:@"uvPosition"];
[glProgram addAttribute:@"texture1"];
[glProgram addAttribute:@"texture2"];
// Link Program and output log if fails
if (![glProgram link]){
NSLog(@"Failed to link");
glProgram = nil;
return;
}
[glProgram use];
//retireve attribute indicies
positionID = [glProgram attributeIndex:@"position"];
uvID = [glProgram attributeIndex:@"uvPosition"];
textureID1 = [glProgram attributeIndex:@"texture1"];
textureID2 = [glProgram attributeIndex:@"texture2"];
}
-(void) setupGL{
vertexCount = sizeof(TestData)/sizeof(TestData[0]);
indiciesCount = sizeof(TestIndices)/sizeof(TestIndices[0]);
glGenBuffers(1, &positionBuffer);
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexStruct)*vertexCount, &TestData[0].Position, GL_STATIC_DRAW);
glGenBuffers(1, &uvBuffer);
glBindBuffer(GL_ARRAY_BUFFER, uvBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexStruct)*vertexCount, &TestData[0].UV, GL_STATIC_DRAW);
glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(TestIndices), &TestIndices[0], GL_STATIC_DRAW);
//Bind indicies
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
//Bind position and UV buffers
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glVertexAttribPointer(positionID, 2, GL_FLOAT, GL_FALSE, sizeof(VertexStruct), 0);
glEnableVertexAttribArray(positionID);
glBindBuffer(GL_ARRAY_BUFFER, uvBuffer);
glVertexAttribPointer(uvID, 2, GL_FLOAT, GL_FALSE, sizeof(VertexStruct), 0);
glEnableVertexAttribArray(uvID);
//Load textures
NSError *error;
textureInfo1 = [GLKTextureLoader textureWithCGImage:[[UIImage imageNamed:@"image1.png"] CGImage] options:nil error:&error];
if(error.description) NSLog(@"Texture 1 error: %@", error.description);
textureInfo2 = [GLKTextureLoader textureWithCGImage:[[UIImage imageNamed:@"image2.png"] CGImage] options:nil error:&error];
if(error.description) NSLog(@"Texture 2 error: %@", error.description);
//Bind Textures
glActiveTexture(GL_TEXTURE0);
glBindTexture(textureInfo1.target, textureInfo1.name);
glUniform1i( textureID1, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(textureInfo2.target, textureInfo2.name);
glUniform1i( textureID2, 1);
}
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear( GL_COLOR_BUFFER_BIT );
glDrawElements(GL_TRIANGLES, indiciesCount, GL_UNSIGNED_INT, 0);
}
@end
顶点着色器:
precision mediump float;
attribute vec4 position;
attribute vec2 uvPosition;
varying vec2 uv;
void main(void){
uv = uvPosition;
gl_Position = position;
}
片段着色器
precision mediump float;
uniform sampler2D texture1;
uniform sampler2D texture2;
varying vec2 uv;
void main(void){
gl_FragColor = mix(texture2D(texture1, uv),texture2D(texture2, uv),0.5);
}
如果有人能帮助我解决我遇到的这个问题,我将不胜感激。我相信这一定很简单。我还检查了 GL_MAX_TEXTURE_IMAGE_UNITS 其中 returns 8.
好的,我想我已经解决了。我需要从 1 而不是 0 开始纹理单元索引。否则 TEXTURE1 与 TEXTURE0 是相同的纹理!!
不正确:
glActiveTexture(GL_TEXTURE0);
glBindTexture(textureInfo1.target, textureInfo1.name);
glUniform1i(textureID1, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(textureInfo2.target, textureInfo2.name);
glUniform1i( textureID2, 1);
正确:
glActiveTexture(GL_TEXTURE1);
glBindTexture(textureInfo1.target, textureInfo1.name);
glUniform1i(textureID1, 1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(textureInfo2.target, textureInfo2.name);
glUniform1i( textureID2, 2);
奇怪。
快点!我想到了。我错误地访问了属性和统一位置。属性使用 glBindAttribLocation 制服使用 glGetUniformLocation 我正在使用 GLProgram class,它使用方便的方法 addAttribute / attributeIndex 和 uniformIndex
这是违规代码:
-(void) setupShaderProgram{
glProgram = [[GLProgram alloc] initWithVertexShaderFilename:@"TestVertex" fragmentShaderFilename:@"TestFragment"];
//reguster Shader attributes
[glProgram addAttribute:@"position"];
[glProgram addAttribute:@"uvPosition"];
[glProgram addAttribute:@"texture1"]; //wrong - this is not an attribute
[glProgram addAttribute:@"texture2"]; //wrong - this is not an attribute
// Link Program and output log if fails
if (![glProgram link]){
NSLog(@"Failed to link");
glProgram = nil;
return;
}
[glProgram use];
//retireve attribute indicies
positionID = [glProgram attributeIndex:@"position"];
uvID = [glProgram attributeIndex:@"uvPosition"];
textureID1 = [glProgram attributeIndex:@"texture1"]; //Wrong - this is a uniform
textureID2 = [glProgram attributeIndex:@"texture2"];//Wrong - this is a uniform
}
它应该是这样的:
-(void) setupShaderProgram{
glProgram = [[GLProgram alloc] initWithVertexShaderFilename:@"EmptyVertex" fragmentShaderFilename:@"EmptyFragment"];
//register Shader attributes
[glProgram addAttribute:@"position"];
[glProgram addAttribute:@"uvPosition"];
// Link Program and output log if fails
if (![glProgram link]){
NSLog(@"Failed to link");
glProgram = nil;
return;
}
[glProgram use];
//retrieve attribute indicies
positionID = [glProgram attributeIndex:@"position"];
uvID = [glProgram attributeIndex:@"uvPosition"];
//retrieve uniform indicies
textureID1 = [glProgram uniformIndex:@"texture1"];
textureID2 = [glProgram uniformIndex:@"texture2"];
}
我真是个菜鸟
我在向片段着色器发送多个纹理时遇到问题。附件是准系统测试脚本。我正在使用 GLProgram 脚本来加载着色器 (http://iphonedevelopment.blogspot.com.au/2010/11/opengl-es-20-for-ios-chapter-4.html)。
您会在片段着色器中看到我只是使用 mix 将两个纹理组合在一起,但似乎我为 texture1 和 texture2 获得了相同的纹理。
// Extends GLKViewController
#import "ViewControllerImage.h"
#import <OpenGLES/ES2/glext.h>
#import "GLProgram.h"
typedef struct {
float Position[2];
float UV[2];
} VertexStruct;
const VertexStruct TestData[] = {
{{-1.0, 1.0},{0.0, 0.0}},
{{-1.0, -1.0},{0.0, 1.0}},
{{1.0, -1.0},{1.0, 1.0}}
};
const GLuint TestIndices[] = {
0,1,2
};
@implementation ViewControllerImage{
GLProgram *glProgram;
EAGLContext *context;
GLuint uvBuffer;
GLuint indexBuffer;
GLuint positionBuffer;
GLint positionID;
GLuint uvID;
GLint textureID1;
GLint textureID2;
int indiciesCount;
int vertexCount;
GLKTextureInfo *textureInfo1;
GLKTextureInfo *textureInfo2;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self setupContext];
[self setupShaderProgram];
[self setupGL];
}
- (void) setupContext{
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:context];
GLKView *glkView = (GLKView *)self.view;
glkView.context = context;
}
-(void) setupShaderProgram{
glProgram = [[GLProgram alloc] initWithVertexShaderFilename:@"TestVertex" fragmentShaderFilename:@"TestFragment"];
//reguster Shader attributes
[glProgram addAttribute:@"position"];
[glProgram addAttribute:@"uvPosition"];
[glProgram addAttribute:@"texture1"];
[glProgram addAttribute:@"texture2"];
// Link Program and output log if fails
if (![glProgram link]){
NSLog(@"Failed to link");
glProgram = nil;
return;
}
[glProgram use];
//retireve attribute indicies
positionID = [glProgram attributeIndex:@"position"];
uvID = [glProgram attributeIndex:@"uvPosition"];
textureID1 = [glProgram attributeIndex:@"texture1"];
textureID2 = [glProgram attributeIndex:@"texture2"];
}
-(void) setupGL{
vertexCount = sizeof(TestData)/sizeof(TestData[0]);
indiciesCount = sizeof(TestIndices)/sizeof(TestIndices[0]);
glGenBuffers(1, &positionBuffer);
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexStruct)*vertexCount, &TestData[0].Position, GL_STATIC_DRAW);
glGenBuffers(1, &uvBuffer);
glBindBuffer(GL_ARRAY_BUFFER, uvBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(VertexStruct)*vertexCount, &TestData[0].UV, GL_STATIC_DRAW);
glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(TestIndices), &TestIndices[0], GL_STATIC_DRAW);
//Bind indicies
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
//Bind position and UV buffers
glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
glVertexAttribPointer(positionID, 2, GL_FLOAT, GL_FALSE, sizeof(VertexStruct), 0);
glEnableVertexAttribArray(positionID);
glBindBuffer(GL_ARRAY_BUFFER, uvBuffer);
glVertexAttribPointer(uvID, 2, GL_FLOAT, GL_FALSE, sizeof(VertexStruct), 0);
glEnableVertexAttribArray(uvID);
//Load textures
NSError *error;
textureInfo1 = [GLKTextureLoader textureWithCGImage:[[UIImage imageNamed:@"image1.png"] CGImage] options:nil error:&error];
if(error.description) NSLog(@"Texture 1 error: %@", error.description);
textureInfo2 = [GLKTextureLoader textureWithCGImage:[[UIImage imageNamed:@"image2.png"] CGImage] options:nil error:&error];
if(error.description) NSLog(@"Texture 2 error: %@", error.description);
//Bind Textures
glActiveTexture(GL_TEXTURE0);
glBindTexture(textureInfo1.target, textureInfo1.name);
glUniform1i( textureID1, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(textureInfo2.target, textureInfo2.name);
glUniform1i( textureID2, 1);
}
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear( GL_COLOR_BUFFER_BIT );
glDrawElements(GL_TRIANGLES, indiciesCount, GL_UNSIGNED_INT, 0);
}
@end
顶点着色器:
precision mediump float;
attribute vec4 position;
attribute vec2 uvPosition;
varying vec2 uv;
void main(void){
uv = uvPosition;
gl_Position = position;
}
片段着色器
precision mediump float;
uniform sampler2D texture1;
uniform sampler2D texture2;
varying vec2 uv;
void main(void){
gl_FragColor = mix(texture2D(texture1, uv),texture2D(texture2, uv),0.5);
}
如果有人能帮助我解决我遇到的这个问题,我将不胜感激。我相信这一定很简单。我还检查了 GL_MAX_TEXTURE_IMAGE_UNITS 其中 returns 8.
好的,我想我已经解决了。我需要从 1 而不是 0 开始纹理单元索引。否则 TEXTURE1 与 TEXTURE0 是相同的纹理!!
不正确:
glActiveTexture(GL_TEXTURE0);
glBindTexture(textureInfo1.target, textureInfo1.name);
glUniform1i(textureID1, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(textureInfo2.target, textureInfo2.name);
glUniform1i( textureID2, 1);
正确:
glActiveTexture(GL_TEXTURE1);
glBindTexture(textureInfo1.target, textureInfo1.name);
glUniform1i(textureID1, 1);
glActiveTexture(GL_TEXTURE2);
glBindTexture(textureInfo2.target, textureInfo2.name);
glUniform1i( textureID2, 2);
奇怪。
快点!我想到了。我错误地访问了属性和统一位置。属性使用 glBindAttribLocation 制服使用 glGetUniformLocation 我正在使用 GLProgram class,它使用方便的方法 addAttribute / attributeIndex 和 uniformIndex
这是违规代码:
-(void) setupShaderProgram{
glProgram = [[GLProgram alloc] initWithVertexShaderFilename:@"TestVertex" fragmentShaderFilename:@"TestFragment"];
//reguster Shader attributes
[glProgram addAttribute:@"position"];
[glProgram addAttribute:@"uvPosition"];
[glProgram addAttribute:@"texture1"]; //wrong - this is not an attribute
[glProgram addAttribute:@"texture2"]; //wrong - this is not an attribute
// Link Program and output log if fails
if (![glProgram link]){
NSLog(@"Failed to link");
glProgram = nil;
return;
}
[glProgram use];
//retireve attribute indicies
positionID = [glProgram attributeIndex:@"position"];
uvID = [glProgram attributeIndex:@"uvPosition"];
textureID1 = [glProgram attributeIndex:@"texture1"]; //Wrong - this is a uniform
textureID2 = [glProgram attributeIndex:@"texture2"];//Wrong - this is a uniform
}
它应该是这样的:
-(void) setupShaderProgram{
glProgram = [[GLProgram alloc] initWithVertexShaderFilename:@"EmptyVertex" fragmentShaderFilename:@"EmptyFragment"];
//register Shader attributes
[glProgram addAttribute:@"position"];
[glProgram addAttribute:@"uvPosition"];
// Link Program and output log if fails
if (![glProgram link]){
NSLog(@"Failed to link");
glProgram = nil;
return;
}
[glProgram use];
//retrieve attribute indicies
positionID = [glProgram attributeIndex:@"position"];
uvID = [glProgram attributeIndex:@"uvPosition"];
//retrieve uniform indicies
textureID1 = [glProgram uniformIndex:@"texture1"];
textureID2 = [glProgram uniformIndex:@"texture2"];
}
我真是个菜鸟