0

I'm currently drawing a sphere but I would like to have options to have 3D coloring and textures on the sphere. I'm aware that my code right know allows me to insert textures because I have u, v coordinates but I'm not sure how to do this.

Sphere Calculations

    const float pi = 3.1414927f;
GLint layers = 100;
GLint circumferenceTiles = 100;
std::vector<float> va;
std::vector<int> ia;

// create the vertex attributes
va.reserve((layers + 1)* (circumferenceTiles + 1) * 5);  // 5 floats: x, y, z, u, v 
for (int il = 0; il <= layers; ++il)
{
    float layer_rel = (float)il / (float)layers;
    float layer_ang = (1.0f - 2.0f * layer_rel) * pi / 2.0f;
    float layer_sin = std::sin(layer_ang);
    float layer_cos = std::cos(layer_ang);
    for (int ic = 0; ic <= circumferenceTiles; ic++)
    {
        float circum_rel = (float)ic / (float)circumferenceTiles;
        float cricum_ang = circum_rel * 2.0f * pi - pi;
        float circum_sin = std::sin(cricum_ang);
        float circum_cos = std::cos(cricum_ang);

        va.push_back(layer_cos * circum_cos); // x
        va.push_back(layer_cos * circum_sin); // y
        va.push_back(layer_sin);              // z
        va.push_back(circum_rel);             // u
        va.push_back(1.0f - layer_rel);       // v
    }
}

// create the face indices 
ia.reserve(layers * circumferenceTiles * 6);
for (int il = 0; il < layers; ++il)
{
    for (int ic = 0; ic < circumferenceTiles; ic++)
    {
        int i0 = il * (circumferenceTiles + 1) + ic;
        int i1 = i0 + 1;
        int i3 = i0 + circumferenceTiles + 1;
        int i2 = i3 + 1;

        int faces[]{ i0, i1, i2, i0, i2, i3 };
        ia.insert(ia.end(), faces + (il == 0 ? 3 : 0), faces + (il == layers - 1 ? 3 : 6));
    }
}

Binding

    // Vertex Array
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

// Vertex Buffer
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, va.size() * sizeof(*va.data()), va.data(), GL_STATIC_DRAW);

// Index Buffer
GLuint ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ia.size() * sizeof(*ia.data()), ia.data(), GL_STATIC_DRAW);

GLuint v_attr_inx = 0;
glVertexAttribPointer(v_attr_inx, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), 0);
glEnableVertexAttribArray(v_attr_inx);

GLuint t_attr_inx = 1;
glVertexAttribPointer(t_attr_inx, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (GLvoid*)(3 * sizeof(float)));
glEnableVertexAttribArray(t_attr_inx);

glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

Drawing

        glBindVertexArray(vao);
    glDrawElements(GL_TRIANGLES, (GLsizei)ia.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);

Fragment Shader

    #version 330 core

// Interpolated values from the vertex shaders
in vec3 fragmentColor;

// Ouput data
layout(location = 0) out vec4 color;
uniform vec4 u_Color;

void main(){

    // Output color = color specified in the vertex shader, 
    // interpolated between all 3 surrounding vertices
    color = u_Color;

}

Vertex Shader

    #version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 texcoord;

// Output data ; will be interpolated for each fragment.
out vec3 fragmentColor;
// Values that stay constant for the whole mesh.
uniform mat4 MVP;

void main(){    
    // The color of each vertex will be interpolated
    // to produce the color of each fragment
    fragmentColor = texcoord;

    // Output position of the vertex, in clip space : MVP * position
    gl_Position =  MVP * vec4(vertexPosition_modelspace,1);
}

Currently when I write vec3 texcoord I can change the colors but cannot show the the sphere in wire mode. But when I change it to vec2 I'm able to change it to wire mode but unable to change the colors.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Cancasim
  • 13
  • 3
  • here [example shader using texture](https://stackoverflow.com/a/34708022/2521214) You simply load&decode the image to 1D array of colors (I use 32bit uint per color) create GL texture ID , bind it, set its properties and pass the array of colors to it once... then before rendering bind it and in shaders use it. On top of all this you need to pass used texture unit (probably `0`) as uniform `sampler2D` variable in fragment... Here [CPU side code for the texture creation](https://stackoverflow.com/a/31804515/2521214) look for ` if (texture!="")` in code – Spektre May 31 '21 at 08:03
  • also take a look at this [Texturing a cube with different images using OpenGL](https://stackoverflow.com/a/65276638/2521214) it contains both CPU and GPU side code (complete), simple 2D texture atlas , simple lighting ... – Spektre May 31 '21 at 08:13

0 Answers0