2 papersilence papersilence 于 2013.06.30 18:31 提问

请问如何将OpenGL中的纹理单元传递给片段着色器???

小白我最近在学习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表示使用固定的管线
}

1个回答

huimingjack
huimingjack   2014.06.24 17:52

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;
}

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!