Hey guys, I’m trying to texture map an image onto a sphere in OpenGL 3.3. But instead of showing the image it’s showing something like this:
[ATTACH=CONFIG]1602[/ATTACH]
I’m trying to map the face of buzz light year which is a 512x512 bmp image, and I don’t know why it isn’t texture mapping like it should on the sphere. It’s coming out fine on a cube or any flat surface, but I’m having trouble mapping it to a sphere. Here’s the code I’m using.
double Radius = 0.5;
int Lat = 10;
int Long = 10;
glm::vec2 t_coords[4] = {
glm::vec2( 0.0, 0.0),
glm::vec2( 0.0, 1.0),
glm::vec2( 1.0, 0.0),
glm::vec2( 1.0, 1.0)
};
void sphere(double radius, int Lats, int Longs)
{
float lats,longs;
float slices=(180/(float(Lats)*10))/2;
float sectors=(180/(float(Longs)*10))/2;
float l;int i=0;
for (lats = 0.0; lats <= PI; lats+=sectors)
{
for(longs = 0.0; longs <= 2.0*PI; longs+=slices)
{
float x = radius * sin(lats) * cos(longs);
float y = radius * sin(lats) * sin(longs);
float z = radius * cos(lats);
glm::vec4 pt(x, y, z, 1.0);
if(i>3) i=0;
v_colors[tri_idx] = white; v_positions[tri_idx] = pt; tex_coords[tri_idx] = t_coords[i];
v_normals[tri_idx] = pt; tri_idx++; i++;
w_colors[wire_idx] = black; w_positions[wire_idx] = pt;
w_normals[wire_idx] = pt; wire_idx++;
if(lats+sectors>PI)
l=PI;
else
l=lats+sectors;
x = radius * sin(l) * cos(longs);
y = radius * sin(l) * sin(longs);
z = radius * cos(l);
pt =glm::vec4(x, y, z, 1.0);
if(i>3) i=0;
v_colors[tri_idx] = white; v_positions[tri_idx] = pt; tex_coords[tri_idx] = t_coords[i];
v_normals[tri_idx] = pt; tri_idx++; i++;
w_colors[wire_idx] = black; w_positions[wire_idx] = pt;
w_normals[wire_idx] = pt; wire_idx++;
}
}
// To Complete the wireframe
for (lats = 0.0; lats <= PI; lats+=sectors)
{
for(longs = 0.0; longs <= 2.0*PI; longs+=slices)
{
float x = radius * sin(lats) * cos(longs);
float y = radius * sin(lats) * sin(longs);
float z = radius * cos(lats);
glm::vec4 pt(x, y, z, 1.0);
w_colors[wire_idx] = black; w_positions[wire_idx] = pt;
w_normals[wire_idx] = pt; wire_idx++;
}
}
}
void initBuffersGL(void)
{
// Load shaders and use the resulting shader program
std::string vertex_shader_file("vshader.glsl");
std::string fragment_shader_file("fshader.glsl");
std::vector<GLuint> shaderList;
shaderList.push_back(csX75::LoadShaderGL(GL_VERTEX_SHADER, vertex_shader_file));
shaderList.push_back(csX75::LoadShaderGL(GL_FRAGMENT_SHADER, fragment_shader_file));
shaderProgram = csX75::CreateProgramGL(shaderList);
glUseProgram( shaderProgram );
// getting the attributes from the shader program
GLuint vPosition = glGetAttribLocation( shaderProgram, "vPosition" );
GLuint vColor = glGetAttribLocation( shaderProgram, "vColor" );
GLuint vNormal = glGetAttribLocation( shaderProgram, "vNormal" );
GLuint texCoord = glGetAttribLocation( shaderProgram, "texCoord" );
uModelViewMatrix = glGetUniformLocation( shaderProgram, "uModelViewMatrix");
normalMatrix = glGetUniformLocation( shaderProgram, "normalMatrix");
viewMatrix = glGetUniformLocation( shaderProgram, "viewMatrix");
// Load Textures
GLuint tex=LoadTexture("images/buzz_face.bmp",512,512);
glBindTexture(GL_TEXTURE_2D, tex);
//Ask GL for two Vertex Attribute Objects (vao) , one for the colorcube and one for the plane.
glGenVertexArrays (2, vao);
//Ask GL for two Vertex Buffer Object (vbo)
glGenBuffers (2, vbo);
//Set 0 as the current array to be used by binding it
glBindVertexArray (vao[0]);
//Set 0 as the current buffer to be used by binding it
glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
// Call the sphere function
Lat = tesselation;
Long = tesselation;
sphere(Radius, Lat, Long);
//Copy the points into the current buffer
glBufferData (GL_ARRAY_BUFFER, sizeof (v_positions) + sizeof(v_colors) + sizeof(v_normals), NULL, GL_STATIC_DRAW);
glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(v_positions), v_positions );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(v_positions), sizeof(v_colors), v_colors );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(v_colors)+sizeof(v_positions), sizeof(v_normals), v_normals );
// set up vertex array
glEnableVertexAttribArray( vPosition );
glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
//Textures
glEnableVertexAttribArray( texCoord );
glVertexAttribPointer( texCoord, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(v_positions)) );
// glEnableVertexAttribArray( vColor );
// glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(v_positions)) );
// glEnableVertexAttribArray( vNormal );
// glVertexAttribPointer( vNormal, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(v_positions) + sizeof(v_colors)) );
//Normal
glEnableVertexAttribArray( vNormal );
glVertexAttribPointer( vNormal, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(v_positions)+sizeof(tex_coords)) );
// For The Wireframe too ... --------
//Set 1 as the current array to be used by binding it
glBindVertexArray (vao[1]);
//Set 1 as the current buffer to be used by binding it
glBindBuffer (GL_ARRAY_BUFFER, vbo[1]);
//Copy the points into the current buffer
glBufferData (GL_ARRAY_BUFFER, sizeof (w_positions) + sizeof(w_colors) + sizeof(w_normals), NULL, GL_STATIC_DRAW);
glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof(w_positions), w_positions );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(w_positions), sizeof(w_colors), w_colors );
glBufferSubData( GL_ARRAY_BUFFER, sizeof(w_colors)+sizeof(w_positions), sizeof(w_normals), w_normals );
// set up vertex array
glEnableVertexAttribArray( vPosition );
glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
glEnableVertexAttribArray( vColor );
glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(w_positions)) );
glEnableVertexAttribArray( vNormal );
glVertexAttribPointer( vNormal, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(w_positions) + sizeof(w_colors)) );
}
GLuint LoadTexture( const char * filename, int width, int height )
{
GLuint texture;
unsigned char header[54];// 54 Byte header of BMP
int pos;
unsigned int w,h;
unsigned int size; //w*h*3
unsigned char * data; // Data in RGB FORMAT
FILE * file;
file = fopen( filename, "rb" );
if ( file == NULL ) return 0; // if file is empty
if (fread(header,1,54,file)!=54)
{
printf("Incorrect BMP file
");
return 0;
}
// Read MetaData
pos = *(int*)&(header[0x0A]);
size = *(int*)&(header[0x22]);
w = *(int*)&(header[0x12]);
h = *(int*)&(header[0x16]);
//Just in case metadata is missing
if(size == 0)
size = w*h*3;
if(pos == 0)
pos = 54;
data = new unsigned char [size];
fread( data, size, 1, file ); // read the file
fclose( file );
//////////////////////////
glGenTextures( 1, &texture );
glBindTexture( GL_TEXTURE_2D, texture );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
free( data );
return texture;// return the texture id
}