1

I am trying to map a texture image to a sphere.

I have vertices and texture coords in different vectors, that's why I am using glBufferSubData.

std::vector<glm::vec3> sphere_vertices;
std::vector<int> sphere_indices;
std::vector<glm::vec2> sphere_texcoords;

I don't use any colors , only vertices,indices,textures.

I am using:

// upload geometry to GPU
glBindVertexArray(sphere_VAO);
glGenBuffers(1, &sphere_vertices_VBO);
glBindBuffer(GL_ARRAY_BUFFER, sphere_vertices_VBO);


glBufferData(GL_ARRAY_BUFFER, sizeof(float) * sphere_vertices.size() + sizeof(float) * sphere_texcoords.size(),
            0, GL_STATIC_DRAW);

glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * sphere_vertices.size(), sphere_vertices.data());

glBufferSubData(GL_ARRAY_BUFFER, sizeof(float) * sphere_vertices.size(), sizeof(float) * sphere_texcoords.size(), sphere_texcoords.data());

glGenBuffers(1, &sphere_indices_VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sphere_indices_VBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * sphere_indices.size(), sphere_indices.data(), GL_STATIC_DRAW);


// setup vertex attributes
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

// texture coords attrib
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float) , (void*)(sizeof(float) * sphere_vertices.size()));

and the image does not map correctly on the sphere.

The image I am receiving:

ball

-- UPDATE ---

I used sphere_texcoords.push_back((glm::vec2((x + 1) / 2.0, (y + 1) / 2.0))); for texcoords and it works now!

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
George
  • 5,808
  • 15
  • 83
  • 160

1 Answers1

0

The size of the buffer and the buffer offsets have to be specified in bytes.
Note, the size of an element is sizeof(glm::vec3) respectively sizeof(glm::vec2) rather than sizeof(float):

size_t vertices_size  = sizeof(glm::vec3) * sphere_vertices.size();
size_t texcoords_size = sizeof(glm::vec2) * sphere_texcoords.size();

glBufferData(GL_ARRAY_BUFFER, vertices_size + texcoords_size, 0, GL_STATIC_DRAW);

glBufferSubData(GL_ARRAY_BUFFER, 0, vertices_size, sphere_vertices.data());

glBufferSubData(GL_ARRAY_BUFFER, vertices_size, texcoords_size, sphere_texcoords.data());

When named buffer object is bound the the last parameter of glVertexAttribPointer is treated as a byte offset into this buffer. The offset of the texture coordinates has to be:

glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(glm::vec2), (void*)vertices_size);

In general the size of the data of a std::vector<T> v in bytes can be get by:

size_t size = sizeof(T) * v.size();

respectively

size_t size = sizeof(*v.data()) * v.size();
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Hi, still the same results.The image does not map correctly.I am not sure if I handle correctlt the `sphere_indices_VBO` where I call the ` glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * sphere_indices.size(), sphere_indices.data(), GL_STATIC_DRAW); ` – George Sep 06 '19 at 06:38
  • @George The indices are correct. What does it mean *"The image does not map correctly"*? Where do the texture coordinates from? Possibly the image is mapped correctly to but the texture coordinates are not correct. – Rabbid76 Sep 06 '19 at 06:45
  • I am using texcoords as in [this] (https://stackoverflow.com/questions/5988686/creating-a-3d-sphere-in-opengl-using-visual-c/5989676) code.I want to map a ball image on to the sphere. – George Sep 06 '19 at 06:56
  • Ok, I uploaded an image, thanks.(Note that, the sphere is black that's why it shows black) – George Sep 06 '19 at 07:15
  • @George It's just a guess, but what happens if you swap the u and v coordinates? – Rabbid76 Sep 06 '19 at 07:32
  • If by u and v coordinates you mean the texcoords , still the image is not mapped correctly. – George Sep 06 '19 at 07:36
  • 1
    I used`sphere_texcoords.push_back((glm::vec2((x + 1) / 2.0, (y + 1) / 2.0)));` for texcoords and it works! But, when I move the camera , the image is distorted again.. – George Sep 06 '19 at 09:12