PDA

View Full Version : Mesh generation for Cube, Sphere etc with Vertices, UV's Normals, Tangent & Bitangent



paul_g_griffiths
01-20-2017, 06:17 AM
Can someone help me out here for good code or library for mesh generation of cube, sphere, code etc. including Tangent & Bitangent?
It's for parallax mapping.

Thanks.

paul_g_griffiths
01-20-2017, 08:25 AM
I've pinched some code for a cube but it's not rendering anything. Can you spot what's wrong?


GLuint vertexbuffer = 0;
GLuint uvbuffer = 0;
GLuint normalbuffer = 0;
void RenderCube()
{
// Initialize (if necessary)
if (vertexbuffer == 0)
{
GLfloat cubeVertices[] = { -1.0f, -1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f, +1.0f, -1.0f, -1.0f, +1.0f,

-1.0f, +1.0f, -1.0f, +1.0f, -1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, -1.0f, +1.0f,

-1.0f, -1.0f, -1.0f, +1.0f, -1.0f, +1.0f, -1.0f, +1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f, -1.0f, -1.0f, +1.0f,

-1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f,

-1.0f, -1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f, +1.0f, -1.0f, +1.0f, -1.0f, +1.0f,

+1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, +1.0f, -1.0f, +1.0f };


GLfloat cubeNormals[] = { 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f,

0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f,

0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f,

0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f,

-1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,

+1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f };

GLfloat cubeTangents[] = { +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f,

+1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f,

-1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,

+1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f,

0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f, 0.0f, 0.0f, +1.0f,

0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, -1.0f };

GLfloat cubeTexCoords[] =
{ 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,

0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,

1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,

0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,

0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,

1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f };

GLint cubeIndices[] = { 0, 2, 1, 0, 3, 2, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 15, 14, 12, 14, 13, 16, 17, 18, 16, 18, 19, 20, 23, 22, 20, 22, 21 };
glGenVertexArrays(1, &vertexbuffer);
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);

glGenBuffers(1, &normalbuffer);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeNormals), cubeNormals, GL_STATIC_DRAW);

glGenBuffers(1, &uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeTexCoords), cubeTexCoords, GL_STATIC_DRAW);


}

glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);

glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glVertexAttribPointer(
1,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);

glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glVertexAttribPointer(
2,
2,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);

glDrawArrays(GL_TRIANGLES, 0, 32);

glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);

}

Heres my layouts for my shader:

layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 texCoords;

The code I had before worked but the texture chords were all wrong so I'm trying this.
I got the data from: https://raw.githubusercontent.com/McNopper/GLUS/master/GLUS/src/glus_shape.c

GClements
01-20-2017, 12:08 PM
I've pinched some code for a cube but it's not rendering anything. Can you spot what's wrong?

1. cubeVertices contains 4 vec4's (including W) per quad. But the glVertexAttribPointer() states that it's 3 components, packed (i.e. no padding, stride=0).
2. You have an index array, but you're not using it (glDrawArrays() rather than glDrawElements()).
3. The vertices form quads but you're drawing triangles (and not using an index array).
4. A cube made of triangles has 6 faces = 12 triangles = 36 vertices. The glDrawArrays() call says 32.

paul_g_griffiths
01-20-2017, 01:08 PM
1. cubeVertices contains 4 vec4's (including W) per quad. But the glVertexAttribPointer() states that it's 3 components, packed (i.e. no padding, stride=0).
2. You have an index array, but you're not using it (glDrawArrays() rather than glDrawElements()).
3. The vertices form quads but you're drawing triangles (and not using an index array).
4. A cube made of triangles has 6 faces = 12 triangles = 36 vertices. The glDrawArrays() call says 32.

Thanks man did not know it's that wrong, ill look for code elsewhere because don't want to rewrite my shaders.
Thanks for your time though.

There must be a simple library that created cubes, spheres, cones & torus etc. Ill keep looking at google.

john_connor
01-20-2017, 02:07 PM
https://sites.google.com/site/john87connor/texture-object/tutorial-09-5-cube-map
if you use colors, you dont need texcoords or normals
normals are only needed for lighting calculations, texcoords only for texturing

you dont need a lib for those basic steps, if you've understood the 3D math behind your app
to draw a sphere for example, consider "spherical coordinates"

you can convert each pair ( x | y | z ) into ( r | phi | theta ) and backwards
a sphere is mathematically described by r = constant, so to generate all the points for it, just iterate over both angles, phi and theta
assuming that ...
-- phi is within [-PI/2 ; +PI/2], that means [-90 ; +90] and ...
-- theta is within [0 ; +2PI], that means a full circle (at constant elevation) ...
your code would look like this:


float r = 1.0f // constant radius
for (float phi = -PI / 2; phi < +PI / 2; phi += phi_step) // phi_step ~ 0.01f for example
{
for (float theta = 0; theta < +2*PI; theta += theta _step) // theta _step ~ 0.01f for example
{
float x = r * cos(phi) * cos(theta);
float y = r * sin(phi);
float z = r * cos(phi) * sin(theta);

// generate vertex out of these coordinates

}
}

https://en.wikipedia.org/wiki/Spherical_coordinate_system
https://en.wikipedia.org/wiki/Cylindrical_coordinate_system#Cartesian_coordinate s

beside that, if you want to generate a cube and you are using OpenGL core profile, you cant use GL_QUADS to draw quads, instead you have to use triangles

paul_g_griffiths
01-20-2017, 02:29 PM
I require shapes with Vertices, texchoords Normals, Tangent & Bitangent .
It's for parallax rendering so need them all.

You would think creating shapes would be popular and there would be loads of code available, but no, if there is it's very hard to find.

john_connor
01-20-2017, 04:58 PM
usually you do that kind of stuff in a modelling program, like blender
https://www.blender.org/

you can then export such a model into a certain file format, .obj for example
your application can then easily load that model

regarding tangent and bitangent, as i said, is easy to calculate with basic 3D math:
you already have the position/normal of a face, so you have the equation for a plane
with that equation, you can calculate 2 further points in that plane, subtract them
that gives you a 2nd vector perpendicular to the normal
the 3rd vector can be calculated by the cross product of the normal and and the 2nd vector

paul_g_griffiths
01-20-2017, 05:48 PM
Thanks but I want to do it with code not models, found a function that generates tangent & bitangent though.
I can find code for cone, sphere etc but there from different authors so the code is different.

Looking for a good library.

paul_g_griffiths
01-21-2017, 07:19 AM
Ive came up with the following code but I require normal calculations.

Can you help me out?


TShape::TShape()
{}


TShape::~TShape()
{
}


void TShape::createBox(glm::vec3 origin, glm::f32 xside, glm::f32 yside, glm::f32 zside)
{
glm::f32 x = xside / 2.0f;
glm::f32 y = yside / 2.0f;
glm::f32 z = zside / 2.0f;

glm::vec3 a0 = glm::vec3(+x, +y, +z) + origin;
glm::vec3 a1 = glm::vec3(-x, +y, +z) + origin;
glm::vec3 a2 = glm::vec3(-x, -y, +z) + origin;
glm::vec3 a3 = glm::vec3(+x, -y, +z) + origin;
glm::vec3 a4 = glm::vec3(+x, +y, -z) + origin;
glm::vec3 a5 = glm::vec3(-x, +y, -z) + origin;
glm::vec3 a6 = glm::vec3(-x, -y, -z) + origin;
glm::vec3 a7 = glm::vec3(+x, -y, -z) + origin;

glm::vec3 verts[] = {
a1, a2, a3, a3, a0, a1,
a2, a6, a7, a7, a3, a2,
a6, a5, a4, a4, a7, a6,
a5, a1, a0, a0, a4, a5,
a0, a3, a7, a7, a4, a0,
a5, a6, a2, a2, a1, a5
};

glm::vec2 texc[] = {
glm::vec2(0,1), glm::vec2(0,0), glm::vec2(1,0), glm::vec2(1,0), glm::vec2(1,1), glm::vec2(0,1),
glm::vec2(0,1), glm::vec2(0,0), glm::vec2(1,0), glm::vec2(1,0), glm::vec2(1,1), glm::vec2(0,1),
glm::vec2(1,0), glm::vec2(1,1), glm::vec2(0,1), glm::vec2(0,1), glm::vec2(0,0), glm::vec2(1,0),
glm::vec2(0,1), glm::vec2(0,0), glm::vec2(1,0), glm::vec2(1,0), glm::vec2(1,1), glm::vec2(0,1),
glm::vec2(0,0), glm::vec2(1,0), glm::vec2(1,1), glm::vec2(1,1), glm::vec2(0,1), glm::vec2(0,0),
glm::vec2(1,1), glm::vec2(0,1), glm::vec2(0,0), glm::vec2(0,0), glm::vec2(1,0), glm::vec2(1,1),
};

glm::vec3 norm[36]; // help needed here

for (int i = 0; i < 36; i++)
{
vbo.addData(&verts[i], sizeof(glm::vec3));
vbo.addData(&texc[i], sizeof(glm::vec2));
vbo.addData(&norm[i], sizeof(glm::vec3));
}

numVertices = 36;

createVAO();
}

void TShape::createVAO()
{
// VAO & VBOs
vbo.createVBO();
vbo.bindVBO();
vbo.uploadDataToGPU(GL_STATIC_DRAW);

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

int iDataStride = 2 * sizeof(glm::vec3) + sizeof(glm::vec2); // vertex & texCoord & normal
int iDataOffset = 0;
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, iDataStride, (void*)iDataOffset);
iDataOffset += sizeof(glm::vec3);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, iDataStride, (void*)iDataOffset);
iDataOffset += sizeof(glm::vec2);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, iDataStride, (void*)iDataOffset);
}



void TShape::render()
{
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, numVertices);
}

paul_g_griffiths
01-21-2017, 08:22 AM
Done it!


#include "TShape.h"



TShape::TShape()
{}


TShape::~TShape()
{
}


void TShape::createBox(glm::vec3 size)
{
glm::f32 x = size.x / 2.0f;
glm::f32 y = size.y / 2.0f;
glm::f32 z = size.z / 2.0f;

glm::vec3 a0 = glm::vec3(+x, +y, +z);
glm::vec3 a1 = glm::vec3(-x, +y, +z);
glm::vec3 a2 = glm::vec3(-x, -y, +z);
glm::vec3 a3 = glm::vec3(+x, -y, +z);
glm::vec3 a4 = glm::vec3(+x, +y, -z);
glm::vec3 a5 = glm::vec3(-x, +y, -z);
glm::vec3 a6 = glm::vec3(-x, -y, -z);
glm::vec3 a7 = glm::vec3(+x, -y, -z);

glm::vec3 verts[] = {
a1, a2, a3, a3, a0, a1,
a2, a6, a7, a7, a3, a2,
a6, a5, a4, a4, a7, a6,
a5, a1, a0, a0, a4, a5,
a0, a3, a7, a7, a4, a0,
a5, a6, a2, a2, a1, a5
};

glm::vec2 texc[] = {
glm::vec2(0,1), glm::vec2(0,0), glm::vec2(1,0), glm::vec2(1,0), glm::vec2(1,1), glm::vec2(0,1),
glm::vec2(0,1), glm::vec2(0,0), glm::vec2(1,0), glm::vec2(1,0), glm::vec2(1,1), glm::vec2(0,1),
glm::vec2(1,0), glm::vec2(1,1), glm::vec2(0,1), glm::vec2(0,1), glm::vec2(0,0), glm::vec2(1,0),
glm::vec2(0,1), glm::vec2(0,0), glm::vec2(1,0), glm::vec2(1,0), glm::vec2(1,1), glm::vec2(0,1),
glm::vec2(0,0), glm::vec2(1,0), glm::vec2(1,1), glm::vec2(1,1), glm::vec2(0,1), glm::vec2(0,0),
glm::vec2(1,1), glm::vec2(0,1), glm::vec2(0,0), glm::vec2(0,0), glm::vec2(1,0), glm::vec2(1,1),
};

glm::vec3 norm[36]; // help needed here

for (int i = 0; i < 36; i += 3)
{
glm::vec3 normal = glm::normalize(
glm::cross(
glm::vec3(verts[i + 1]) - glm::vec3(verts[i]),
glm::vec3(verts[i + 2]) - glm::vec3(verts[i])));

norm[i] = normal;
norm[i + 1] = normal;
norm[i + 2] = normal;
}

for (int i = 0; i < 36; i++)
{
vbo.addData(&verts[i], sizeof(glm::vec3));
vbo.addData(&texc[i], sizeof(glm::vec3));
vbo.addData(&texc[i], sizeof(glm::vec2));
}

numVertices = 36;

createVAO();
}


void TShape::createVAO()
{
// VAO & VBOs
vbo.createVBO();
vbo.bindVBO();
vbo.uploadDataToGPU(GL_STATIC_DRAW);

glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

int iDataStride = 2 * sizeof(glm::vec3) + sizeof(glm::vec2); // vertex & texCoord & normal
int iDataOffset = 0;
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, iDataStride, (void*)iDataOffset);
iDataOffset += sizeof(glm::vec3);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, iDataStride, (void*)iDataOffset);
iDataOffset += sizeof(glm::vec2);
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, iDataStride, (void*)iDataOffset);
}



void TShape::render(Shader &shader, bool renderDepth, glm::vec3 cameraPosition)
{
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, numVertices);
}