小白我最近在学习GLSL,绝对的菜鸟级别啊~
今天遇到了一个问题,我用 texture[1] 在程序中存储了一个纹理,然后使用了下面两行代码将纹理传递给片段着色器,程序是可以运行的
texUnitLoc = glGetUniformLocation(p, "tex");
glUniform1i(texUnitLoc, 0);
但是当我在程序中存储两个纹理以后,想要将两个纹理都传递到着色器时,应该怎么办啊??将上面代码中的‘0’换做‘texture[0]’也不管用啊,什么都不管用啊,glUniform究竟是怎么一回事啊?求大神指点~~T_T
附代码如下:
#include
#include
#include
#include
#include
#include "textfile.h"
#include "printInfoLog.h"
GLfloat LightAmbient0[]= {1, 1, 1, 1.0f };
GLfloat LightDiffuse0[]= {1.0f, 1.0f, 1.0f, 1.0f };
GLfloat LightSpecular0[]={1.0f, 1.0f, 1.0f, 1.0f};
GLfloat LightPosition0[]= {3.0f, 3.0f, 3.0f, 0.0f };
GLfloat MaterialAmbient[] = {0.3, 0.3, 0.3, 1.0f};
GLfloat MaterialDiffuse[] = {0.7, 0.7, 0.7, 1.0f};
GLfloat MaterialSpecular[] ={0.3, 0.3, 0.3, 1.0f};
GLfloat MaterialSe = 64.0f;
GLUquadricObj *quadratic;
GLuint texture[2]; // 存储一个纹理
GLint texUnitLoc,l3dUnitLoc;
float a = 0.0f;
GLuint v,f,p;
float t = 0;
GLint loc;
AUX_RGBImageRec *LoadBMP(char *Filename) // 载入位图图象
{
FILE *File=NULL; // 文件句柄
if (!Filename) // 确保文件名已提供
{
return NULL; // 如果没提供,返回 NULL
}
File=fopen(Filename,"r"); // 尝试打开文件
if (File) // 文件存在么?
{
fclose(File); // 关闭句柄
return auxDIBImageLoad(Filename);// 载入位图并返回指针
}
return NULL; // 如果载入失败,返回 NULL
}
int LoadGLTextures() // 载入位图(调用上面的代码)并转换成纹理
{
int Status=FALSE; // 状态指示器
AUX_RGBImageRec *TextureImage[2]; // 创建纹理的存储空间
memset(TextureImage,0,sizeof(void *)*1); // 将指针设为 NULL
// 载入位图,检查有无错误,如果位图没找到则退出
if (TextureImage[0]=LoadBMP("Data/Crate.bmp"))
{
Status=TRUE; // 将 Status 设为 TRUE
glGenTextures(1, &texture[0]); // 创建纹理
// 创建 MipMapped 纹理
glBindTexture(GL_TEXTURE_2D, texture[0]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
}
if (TextureImage[0]) // 纹理是否存在
{
if (TextureImage[0]->data) // 纹理图像是否存在
{
free(TextureImage[0]->data); // 释放纹理图像占用的内存
}
free(TextureImage[0]); // 释放图像结构
}
if (TextureImage[1]=LoadBMP("Data/1.bmp"))
{
Status=TRUE; // 将 Status 设为 TRUE
glGenTextures(1, &texture[1]); // 创建纹理
// 创建 MipMapped 纹理
glBindTexture(GL_TEXTURE_2D, texture[1]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[1]->sizeX, TextureImage[1]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[1]->data);
}
if (TextureImage[1]) // 纹理是否存在
{
if (TextureImage[1]->data) // 纹理图像是否存在
{
free(TextureImage[1]->data); // 释放纹理图像占用的内存
}
free(TextureImage[1]); // 释放图像结构
}
return Status; // 返回 Status
}
void changeSize(int w, int h)
{
float ratio = 1.0* w / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(45,ratio,1,100);
glMatrixMode(GL_MODELVIEW);
}
void init()
{
glEnable(GL_DEPTH_TEST);
glClearColor(0.0,0.0,0.0,0.0);
glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse0);
glLightfv(GL_LIGHT0,GL_SPECULAR, LightSpecular0);
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition0);
glEnable(GL_LIGHT0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, MaterialAmbient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, MaterialDiffuse);
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR, MaterialSpecular);
glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS, MaterialSe);
quadratic=gluNewQuadric();
gluQuadricNormals(quadratic, GLU_SMOOTH);
gluQuadricTexture(quadratic, GL_TRUE);
LoadGLTextures(); // 调用纹理载入子例程
glEnable(GL_TEXTURE_2D); // 启用纹理映射
}
void renderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0,0.0,5.0, 0.0,0.0,-1.0, 0.0f,1.0f,0.0f);
a += 0.35f;
if(a > 360)
a -= 360.0f;
glRotatef(a, 0, 1, 0);
glRotatef(0, 1, 0, 0);
//glBindTexture(GL_TEXTURE_2D, texture[0]);
gluSphere(quadratic, 1, 32, 16);
t+=0.01;
glutPostRedisplay();
glutSwapBuffers();
}
int main(int argc, char **argv)
{
void setShaders();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutCreateWindow("GLSL DEMO");
init();
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
glewInit();
if (glewIsSupported("GL_VERSION_2_0"))
printf("Ready for OpenGL 2.0\n");
else
{
printf("OpenGL 2.0 not supported\n");
exit(1);
}
setShaders();
texUnitLoc = glGetUniformLocation(p, "tex");
glUniform1i(texUnitLoc, 0);
//l3dUnitLoc = glGetUniformLocation(p, "l3d");
//glUniform1i(l3dUnitLoc, texture[1]);
glutMainLoop();
return 0;
}
void setShaders()
{
char *vs = NULL,*fs = NULL,*fs2 = NULL;
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
vs = textFileRead("vs.txt");
fs = textFileRead("fs.txt");
const char * vv = vs;
const char * ff = fs;
glShaderSource(v, 1, &vv,NULL);
glShaderSource(f, 1, &ff,NULL);
free(vs);free(fs);
glCompileShader(v);
glCompileShader(f);
printShaderInfoLog(v);
printShaderInfoLog(f);
p = glCreateProgram();
glAttachShader(p,v);
glAttachShader(p,f);
glLinkProgram(p);
printProgramInfoLog(p);
glUseProgram(p); //将p改为0表示使用固定的管线
}
Gint t1 = glGetUniformLocation(p, "tex1");
Gint t2 = glGetUniformLocation(p, "tex2");
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,texture[0] );
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glUniform1i(t1, 0);
glUniform1i(t2, 1);
GL_TEXTURE0对应0,GL_TEXTURE1对应1,着色器中应该有unifrom变量 tex1,tex2,与上面的代码相对应,着色器如下面示例:
precision mediump float;
uniform sampler2D tex1;
uniform sampler2D tex2;
void main()
{
vec4 finalColor=texture2D(tex1, vTextureCoord);
vec4 finalColor1=texture2D(tex2, vTextureCoord);
gl_FragColor = finalColor * 0.1 + finalColor1 * 0.9;
}