PDA

View Full Version : multitexturing



sajis997
11-25-2014, 11:48 AM
Hello forum,

i am trying to implement a simple multi-texturing sample as follows, but i just see output of one texture:



void startup()
{
loadShaders();

glEnable(GL_DEPTH_TEST);

//initiate the cube to render
cube = new VboCube(shader);

//create ids for 2 texture object
glGenTextures(2,textureIDs);

int textureWidth = 0;
int textureHeight = 0;
int channels = 0;

//load the brick texture into channel 0
glActiveTexture(GL_TEXTURE0);
std::string fileName = "images/brick1.tga";

GLubyte *data = SOIL_load_image(fileName.c_str(),
&textureWidth,
&textureHeight,
&channels,
SOIL_LOAD_AUTO);

if(data == NULL)
{
std::cerr << "Failed to load the texture image: " << fileName << std::endl;
exit(EXIT_FAILURE);
}

glBindTexture(GL_TEXTURE_2D,textureIDs[0]);

//allocate storage
glTexStorage2D(GL_TEXTURE_2D,1,GL_RGB8,textureWidt h,textureHeight);

//copy the data to the storage
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,textureWidth,t extureHeight,GL_RGB,GL_UNSIGNED_BYTE,data);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);

//free the soil image data
SOIL_free_image_data(data);

//load the moss texture in the channel 1
glActiveTexture(GL_TEXTURE1);

textureWidth = 0;
textureHeight = 0;
channels = 0;
data = NULL;

fileName = "images/moss.tga";

data = SOIL_load_image(fileName.c_str(),
&textureWidth,
&textureHeight,
&channels,
SOIL_LOAD_AUTO);

if(data == NULL)
{
std::cerr << "Failed to load the texture image: " << fileName << std::endl;
exit(EXIT_FAILURE);
}

glBindTexture(GL_TEXTURE_2D,textureIDs[1]);

//allocate storage
glTexStorage2D(GL_TEXTURE_2D,1,GL_RGBA8,textureWid th,textureHeight);

//copy the image to the storage
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,textureWidth,t extureHeight,GL_RGBA,GL_UNSIGNED_BYTE,data);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);

//free the soil image data
SOIL_free_image_data(data);

}


The above snippet shows the texture image loading, creation of texture object and activating the channels. Check out the following shader entries:

Vertex shader


#version 430 core

//vertex attributes from the application
in vec3 vertexPosition;
in vec3 vertexNormal;
in vec2 vertexTexCoord;

out VS_OUT
{
vec3 position;
vec3 normal;
vec2 texCoord;
} vs_out;

//uniform values from the application
uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 ModelViewProjectionMatrix;

void main()
{
//pass through the texture coordinate
vs_out.texCoord = vertexTexCoord;

//transform the normal and store it
vs_out.normal = normalize(NormalMatrix * vertexNormal);

//model position in the camera coordinates
vs_out.position = vec3(ModelViewMatrix * vec4(vertexPosition,1.0));

//model position in the clip coordinates
gl_Position = ModelViewProjectionMatrix * vec4(vertexPosition,1.0);
}



Fragment shader



#version 430 core

in VS_OUT
{
vec3 position;
vec3 normal;
vec2 texCoord;
} fs_in;

uniform sampler2D BrickTex;
uniform sampler2D MossTex;

struct LightInfo
{
// light position in eye coordinates
vec4 position ;

// A,D,S intensity
vec3 intensity;
};

uniform LightInfo light;

struct MaterialInfo
{
vec3 ka; // ambient reflectivity
vec3 kd; // diffuse reflectivity
vec3 ks; // specular reflectivity
float shininess; // specular shininess factor
};

uniform MaterialInfo material;

out vec4 color;


void phongModel( vec3 pos, vec3 norm, out vec3 ambAndDiff, out vec3 spec)
{
//vector to the light source
vec3 s = normalize(vec3(light.position) - pos);

vec3 v = normalize(-pos.xyz);

vec3 r = reflect( -s, norm);

vec3 ambient = light.intensity * material.ka;

float sDotN = max(dot(s,norm),0.0);

vec3 diffuse = light.intensity * material.kd * sDotN;

spec = vec3(0.0);

if( sDotN > 0.0 )
spec = light.intensity * material.ks * pow(max(dot(r,v),0.0),material.shininess);

ambAndDiff = ambient + diffuse;
}

void main()
{
vec3 ambAndDiff, spec;

vec4 brickTexColor = texture(BrickTex,fs_in.texCoord);

vec4 mossTexColor = texture(MossTex,fs_in.texCoord);

phongModel(fs_in.position,
fs_in.normal,
ambAndDiff,
spec);

vec4 texColor = mix(brickTexColor,mossTexColor,mossTexColor.a);

color = vec4(ambAndDiff,1.0) * texColor + vec4(spec,1.0);
}


Check the image :

http://i.imgur.com/PuTOji4.png

I can only see the brick pattern and the other one is not visible.

Any hint on what i might be missing ?

Thanks

GClements
11-25-2014, 05:37 PM
I don't see where you assign the texture units to BrickTex and MossTex.

If you're not actually assigning them, it's entirely possible that both variables refer to texture unit zero (the brick texture).

sajis997
11-25-2014, 06:54 PM
Actually i am , sorry that i did not upload them in my last post. Here it goes:



void loadShaders()
{
shader = new GLSLShader();

shader->LoadFromFile(GL_VERTEX_SHADER,"shaders/multitexture.vert");
shader->LoadFromFile(GL_FRAGMENT_SHADER,"shaders/multitexture.frag");

shader->CreateAndLinkProgram();

shader->Use();

shader->AddAttribute("vertexPosition");
shader->AddAttribute("vertexNormal");
shader->AddAttribute("vertexTexCoord");

shader->AddUniform("ModelViewMatrix");
shader->AddUniform("NormalMatrix");
shader->AddUniform("ModelViewProjectionMatrix");

shader->AddUniform("BrickTex");
shader->AddUniform("MossTex");

shader->AddUniform("light.intensity");
shader->AddUniform("light.position");

shader->AddUniform("material.kd");
shader->AddUniform("material.ks");
shader->AddUniform("material.ka");
shader->AddUniform("material.shininess");

glUniform1f((*shader)("BrickTex"),0);
glUniform1f((*shader)("MossTex"),1);

glUniform3fv((*shader)("light.intensity"),1,glm::value_ptr(glm::vec3(1.f,1.f,1.0f)));
glUniform4fv((*shader)("light.position"),1,glm::value_ptr(glm::vec4(1.0f,1.25f,1.25f,1.0f )));

glUniform3fv((*shader)("material.kd"),1,glm::value_ptr(glm::vec3(0.9f,0.9f,0.9f)));
glUniform3fv((*shader)("material.ks"),1,glm::value_ptr(glm::vec3(0.95f,0.95f,0.95f)));
glUniform3fv((*shader)("material.ka"),1,glm::value_ptr(glm::vec3(0.1f,0.1f,0.1f)));
glUniform1f((*shader)("material.shininess"),100.0f);

shader->UnUse();
}


Check the snippet from above:



glUniform1f((*shader)("BrickTex"),0);
glUniform1f((*shader)("MossTex"),1);


Is not that enough ?

sajis997
11-25-2014, 10:24 PM
Hi again,

Since i did not get any response from the forum for a while, i thought of posting the whole source for your review:



#include "defines.h"
#include "GLSLShader.h"
#include "VboCube.h"

int winWidth = 512;
int winHeight = 512;

GLFWwindow *window = NULL;

GLSLShader *shader = NULL;

VboCube *cube = NULL;

GLuint textureIDs[2];

float zoom = 1.f;

glm::mat4 ViewMatrix = glm::mat4(1.0f);
glm::mat4 ModelMatrix = glm::mat4(1.0f);
glm::mat4 ModelViewMatrix = glm::mat4(1.0f);
glm::mat4 ProjectionMatrix = glm::mat4(1.0f);
glm::mat3 NormalMatrix = glm::mat3(1.0f);

void loadShaders();
void startup();
void shutdown();
void render(float);

static void framebuffer_size_callback(GLFWwindow *window,int width,int height);
static void scroll_callback(GLFWwindow *window,double x,double y);

int main()
{
// Initialise GLFW before using any of its function
if( !glfwInit() )
{
std::cerr << "Failed to initialize GLFW." << std::endl;
exit(EXIT_FAILURE);
}

glfwWindowHint(GLFW_SAMPLES, 4);
//we want the opengl 4
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
//we do not want the old opengl
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

// Open a window and create its OpenGL context
window = glfwCreateWindow( winWidth, winHeight, "Teapot Tessellation", NULL, NULL);

if( window == NULL )
{
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 4.3 compatible. Try the 2.1 version of the tutorials.\n" );

//we could not initialize the glfw window
//so we terminate the glfw
glfwTerminate();
exit(EXIT_FAILURE);
}


glfwSetFramebufferSizeCallback(window,framebuffer_ size_callback);
glfwSetScrollCallback(window,scroll_callback);

//make the current window context the current one
glfwMakeContextCurrent(window);
glfwSwapInterval(1);

glfwGetFramebufferSize(window,&winWidth,&winHeight);
framebuffer_size_callback(window,winWidth,winHeigh t);

//initialize glew
//needed for the core profile
glewExperimental = true;

if(glewInit() != GLEW_OK)
{
std::cerr << "Failed to initialize GLEW" << std::endl;
exit(EXIT_FAILURE);
}

if(!glewIsSupported("GL_VERSION_4_4"))
{
std::cerr << "OpenGL version 4.4 is yet to be supported" << std::endl;
exit(EXIT_FAILURE);
}

while(glGetError() != GL_NO_ERROR) {}

std::cout << "**************** OpenGL Driver Information *********************" << std::endl;

std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl;
std::cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;
std::cout << "GLEW version: " << glewGetString(GLEW_VERSION) << std::endl;
std::cout << "OpenGL vendor: " << glGetString(GL_VENDOR) << std::endl;
std::cout << "Renderer: " << glGetString(GL_RENDERER) << std::endl;

std::cout << "************************************************** **************" << std::endl;

//call some initialization function
startup();


do
{
render((float)glfwGetTime());
glfwSwapBuffers(window);
glfwPollEvents();
} while(glfwGetKey(window,GLFW_KEY_ESCAPE) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0);

//once the following function is called
//no more events will be dilivered for that
//window and its handle becomes invalid
glfwDestroyWindow(window);

// Close OpenGL window and terminate GLFW
glfwTerminate();

//release all the resources that are allocated
shutdown();

exit(EXIT_SUCCESS);
}

void loadShaders()
{
shader = new GLSLShader();

shader->LoadFromFile(GL_VERTEX_SHADER,"shaders/multitexture.vert");
shader->LoadFromFile(GL_FRAGMENT_SHADER,"shaders/multitexture.frag");

shader->CreateAndLinkProgram();

shader->Use();

shader->AddAttribute("vertexPosition");
shader->AddAttribute("vertexNormal");
shader->AddAttribute("vertexTexCoord");

shader->AddUniform("ModelViewMatrix");
shader->AddUniform("NormalMatrix");
shader->AddUniform("ModelViewProjectionMatrix");

shader->AddUniform("BrickTex");
shader->AddUniform("MossTex");

shader->AddUniform("light.intensity");
shader->AddUniform("light.position");

shader->AddUniform("material.kd");
shader->AddUniform("material.ks");
shader->AddUniform("material.ka");
shader->AddUniform("material.shininess");

glUniform1f((*shader)("BrickTex"),0);
glUniform1f((*shader)("MossTex"),1);

glUniform3fv((*shader)("light.intensity"),1,glm::value_ptr(glm::vec3(1.f,1.f,1.0f)));
glUniform4fv((*shader)("light.position"),1,glm::value_ptr(glm::vec4(1.0f,1.25f,1.25f,1.0f )));

glUniform3fv((*shader)("material.kd"),1,glm::value_ptr(glm::vec3(0.9f,0.9f,0.9f)));
glUniform3fv((*shader)("material.ks"),1,glm::value_ptr(glm::vec3(0.95f,0.95f,0.95f)));
glUniform3fv((*shader)("material.ka"),1,glm::value_ptr(glm::vec3(0.1f,0.1f,0.1f)));
glUniform1f((*shader)("material.shininess"),100.0f);

shader->UnUse();
}

void startup()
{
loadShaders();

glEnable(GL_DEPTH_TEST);

//initiate the cube to render
cube = new VboCube(shader);

//create ids for 2 texture object
glGenTextures(2,textureIDs);

int textureWidth = 0;
int textureHeight = 0;
int channels = 0;
GLubyte *data = NULL;

//load the brick texture into channel 0
glActiveTexture(GL_TEXTURE0);
std::string fileName = "images/brick1.tga";

data = SOIL_load_image(fileName.c_str(),
&textureWidth,
&textureHeight,
&channels,
SOIL_LOAD_AUTO);

if(data == NULL)
{
std::cerr << "Failed to load the texture image: " << fileName << std::endl;
exit(EXIT_FAILURE);
}

glBindTexture(GL_TEXTURE_2D,textureIDs[0]);

//allocate storage
glTexStorage2D(GL_TEXTURE_2D,1,GL_RGB8,textureWidt h,textureHeight);

//copy the data to the storage
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,textureWidth,t extureHeight,GL_RGB,GL_UNSIGNED_BYTE,data);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);

//free the soil image data
SOIL_free_image_data(data);

//load the moss texture in the channel 1
glActiveTexture(GL_TEXTURE1);

textureWidth = 0;
textureHeight = 0;
channels = 0;
data = NULL;

fileName = "images/moss.tga";

data = SOIL_load_image(fileName.c_str(),
&textureWidth,
&textureHeight,
&channels,
SOIL_LOAD_AUTO);

if(data == NULL)
{
std::cerr << "Failed to load the texture image: " << fileName << std::endl;
exit(EXIT_FAILURE);
}

glBindTexture(GL_TEXTURE_2D,textureIDs[1]);

//allocate storage
glTexStorage2D(GL_TEXTURE_2D,1,GL_RGBA8,textureWid th,textureHeight);

//copy the image to the storage
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,textureWidth,t extureHeight,GL_RGBA,GL_UNSIGNED_BYTE,data);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);

//free the soil image data
SOIL_free_image_data(data);

}

void shutdown()
{
if(shader)
{
shader->DeleteShaderProgram();
delete shader;
shader = NULL;
}

if(cube)
{
delete cube;
cube = NULL;
}

glDeleteTextures(2,textureIDs);
}

void render(float currentTime)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glm::mat4 translation = glm::translate(glm::mat4(1.0f),glm::vec3(0.0f,0.0f ,-zoom));
glm::mat4 rotY = glm::rotate(glm::mat4(1.0f),currentTime,glm::vec3( 0.0f,1.0f,0.0f));
glm::mat4 rotX = glm::rotate(glm::mat4(1.0f),currentTime,glm::vec3( 1.0f,0.0f,0.0f));

ModelMatrix = translation * rotY * rotX;


ModelViewMatrix = ViewMatrix * ModelMatrix;

//calculate the normal matrix from the modelview matrix
NormalMatrix = glm::inverseTranspose(glm::mat3(ModelViewMatrix));

shader->Use();

glUniformMatrix4fv((*shader)("ModelViewMatrix"),1,GL_FALSE,glm::value_ptr(ModelViewMatrix));
glUniformMatrix3fv((*shader)("NormalMatrix"),1,GL_FALSE,glm::value_ptr(NormalMatrix));
glUniformMatrix4fv((*shader)("ModelViewProjectionMatrix"),1,GL_FALSE,glm::value_ptr(ProjectionMatrix * ModelViewMatrix));

cube->render();

shader->UnUse();
}

void framebuffer_size_callback(GLFWwindow *window,int width,int height)
{
if(height < 1)
height = 1;

winWidth = width;
winHeight = height;


GLfloat aspect = (GLfloat)winWidth/(GLfloat)winHeight;

//setup the projection matrix
ProjectionMatrix = glm::perspective(30.0f,aspect,0.1f,1000.0f);

glViewport(0,0,winWidth,winHeight);
}

void scroll_callback(GLFWwindow *window,double x,double y)
{
//increase/decrease the field of view
zoom += (float)y/4.f;

if(zoom < 0)
zoom = 0;
}

sajis997
11-26-2014, 08:45 AM
Sorry Folks ,

To get you into this.

It was a tiny mistake. It was before :



glUniform1f((*shader)("BrickTex"),0);
glUniform1f((*shader)("MossTex"),1);


It must be the following:



glUniform1i((*shader)("BrickTex"),0);
glUniform1i((*shader)("MossTex"),1);


Now it is solved. Thanks