C++ OpenGL: How to make a second circle over the cylinder?











up vote
2
down vote

favorite












So basically I have a cylinder with a base (there is a circle under the cylinder), but there is not circle above. I want to make it a closed cylinder.



Here is the important part from my bool CMyApp::Init() function:



Vertex vert[(N+1)*(M+1) + N+2];   //NxM rectangle for our parametric equation
for (int i=0; i<=N; ++i)
for (int j=0; j<=M; ++j)
{
float u = i/(float)N;
float v = j/(float)M;

vert[i + j*(N+1)].p = GetUV(u, v);
vert[i + j*(N+1)].c = glm::normalize( vert[i + j*(N+1)].p );
}

vert[(N + 1)*(M + 1)].p = glm::vec3(0, 0, 0); //center point for cone base
vert[(N + 1)*(M + 1)].c = glm::vec3(0, 0, 0);
for (int i = 0; i <= N; i++) {
vert[(N + 1)*(M + 1) + 1 + i].p = vert[(N)-i].p; //cone base
vert[(N + 1)*(M + 1) + 1 + i].c = vert[(N)-i].c;
}


Render function:



glDrawElements( GL_TRIANGLES,       
3*2*(N)*(M),
GL_UNSIGNED_SHORT,
0);

glDrawArrays(GL_TRIANGLE_FAN, (N + 1)*(M + 1) + 1, (N + 2)); //draw cone base


The "cone base" is there because I started this project from a "Draw a cone" project.



How can I make a second circle but above the cylinder?



Edit:
M,N: Const numbers (20 and 10)



My parametric equation (which is a FUNCTION called GetUV() ):



u *= 2*3.1415f;
float cu = cosf(u), su = sinf(u), cv = cosf(v), sv = sinf(v);
float M = 2.f;
float r = 0.5;
float m = v*M;

return glm::vec3(r*sinf(u), m, r*cosf(u));


How I create Indices (inside Init() function):



 GLushort indices[3*2*(N)*(M)];
for (int i=0; i<N; ++i)
for (int j=0; j<M; ++j)
{
indices[6*i + j*3*2*(N) + 0] = (i) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 1] = (i+1) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 2] = (i) + (j+1)*(N+1);
indices[6*i + j*3*2*(N) + 3] = (i+1) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 4] = (i+1) + (j+1)*(N+1);
indices[6*i + j*3*2*(N) + 5] = (i) + (j+1)*(N+1);
}









share|improve this question









New contributor




József Huszkó is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1




    what is M,N ? you need just 2 circles ... but I am not seeing even the one where are any sin,cos ? The usual is compute X,Y as parametric circle and Z is constant (different for each base, their distance is the cylinder height)
    – Spektre
    Nov 17 at 19:11










  • ... and what does GetUV do? Why glDrawElements and glDrawArrays? Where is the element list?
    – Rabbid76
    Nov 17 at 19:14












  • Sorry, I edited the post.
    – József Huszkó
    Nov 17 at 19:28















up vote
2
down vote

favorite












So basically I have a cylinder with a base (there is a circle under the cylinder), but there is not circle above. I want to make it a closed cylinder.



Here is the important part from my bool CMyApp::Init() function:



Vertex vert[(N+1)*(M+1) + N+2];   //NxM rectangle for our parametric equation
for (int i=0; i<=N; ++i)
for (int j=0; j<=M; ++j)
{
float u = i/(float)N;
float v = j/(float)M;

vert[i + j*(N+1)].p = GetUV(u, v);
vert[i + j*(N+1)].c = glm::normalize( vert[i + j*(N+1)].p );
}

vert[(N + 1)*(M + 1)].p = glm::vec3(0, 0, 0); //center point for cone base
vert[(N + 1)*(M + 1)].c = glm::vec3(0, 0, 0);
for (int i = 0; i <= N; i++) {
vert[(N + 1)*(M + 1) + 1 + i].p = vert[(N)-i].p; //cone base
vert[(N + 1)*(M + 1) + 1 + i].c = vert[(N)-i].c;
}


Render function:



glDrawElements( GL_TRIANGLES,       
3*2*(N)*(M),
GL_UNSIGNED_SHORT,
0);

glDrawArrays(GL_TRIANGLE_FAN, (N + 1)*(M + 1) + 1, (N + 2)); //draw cone base


The "cone base" is there because I started this project from a "Draw a cone" project.



How can I make a second circle but above the cylinder?



Edit:
M,N: Const numbers (20 and 10)



My parametric equation (which is a FUNCTION called GetUV() ):



u *= 2*3.1415f;
float cu = cosf(u), su = sinf(u), cv = cosf(v), sv = sinf(v);
float M = 2.f;
float r = 0.5;
float m = v*M;

return glm::vec3(r*sinf(u), m, r*cosf(u));


How I create Indices (inside Init() function):



 GLushort indices[3*2*(N)*(M)];
for (int i=0; i<N; ++i)
for (int j=0; j<M; ++j)
{
indices[6*i + j*3*2*(N) + 0] = (i) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 1] = (i+1) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 2] = (i) + (j+1)*(N+1);
indices[6*i + j*3*2*(N) + 3] = (i+1) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 4] = (i+1) + (j+1)*(N+1);
indices[6*i + j*3*2*(N) + 5] = (i) + (j+1)*(N+1);
}









share|improve this question









New contributor




József Huszkó is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1




    what is M,N ? you need just 2 circles ... but I am not seeing even the one where are any sin,cos ? The usual is compute X,Y as parametric circle and Z is constant (different for each base, their distance is the cylinder height)
    – Spektre
    Nov 17 at 19:11










  • ... and what does GetUV do? Why glDrawElements and glDrawArrays? Where is the element list?
    – Rabbid76
    Nov 17 at 19:14












  • Sorry, I edited the post.
    – József Huszkó
    Nov 17 at 19:28













up vote
2
down vote

favorite









up vote
2
down vote

favorite











So basically I have a cylinder with a base (there is a circle under the cylinder), but there is not circle above. I want to make it a closed cylinder.



Here is the important part from my bool CMyApp::Init() function:



Vertex vert[(N+1)*(M+1) + N+2];   //NxM rectangle for our parametric equation
for (int i=0; i<=N; ++i)
for (int j=0; j<=M; ++j)
{
float u = i/(float)N;
float v = j/(float)M;

vert[i + j*(N+1)].p = GetUV(u, v);
vert[i + j*(N+1)].c = glm::normalize( vert[i + j*(N+1)].p );
}

vert[(N + 1)*(M + 1)].p = glm::vec3(0, 0, 0); //center point for cone base
vert[(N + 1)*(M + 1)].c = glm::vec3(0, 0, 0);
for (int i = 0; i <= N; i++) {
vert[(N + 1)*(M + 1) + 1 + i].p = vert[(N)-i].p; //cone base
vert[(N + 1)*(M + 1) + 1 + i].c = vert[(N)-i].c;
}


Render function:



glDrawElements( GL_TRIANGLES,       
3*2*(N)*(M),
GL_UNSIGNED_SHORT,
0);

glDrawArrays(GL_TRIANGLE_FAN, (N + 1)*(M + 1) + 1, (N + 2)); //draw cone base


The "cone base" is there because I started this project from a "Draw a cone" project.



How can I make a second circle but above the cylinder?



Edit:
M,N: Const numbers (20 and 10)



My parametric equation (which is a FUNCTION called GetUV() ):



u *= 2*3.1415f;
float cu = cosf(u), su = sinf(u), cv = cosf(v), sv = sinf(v);
float M = 2.f;
float r = 0.5;
float m = v*M;

return glm::vec3(r*sinf(u), m, r*cosf(u));


How I create Indices (inside Init() function):



 GLushort indices[3*2*(N)*(M)];
for (int i=0; i<N; ++i)
for (int j=0; j<M; ++j)
{
indices[6*i + j*3*2*(N) + 0] = (i) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 1] = (i+1) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 2] = (i) + (j+1)*(N+1);
indices[6*i + j*3*2*(N) + 3] = (i+1) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 4] = (i+1) + (j+1)*(N+1);
indices[6*i + j*3*2*(N) + 5] = (i) + (j+1)*(N+1);
}









share|improve this question









New contributor




József Huszkó is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











So basically I have a cylinder with a base (there is a circle under the cylinder), but there is not circle above. I want to make it a closed cylinder.



Here is the important part from my bool CMyApp::Init() function:



Vertex vert[(N+1)*(M+1) + N+2];   //NxM rectangle for our parametric equation
for (int i=0; i<=N; ++i)
for (int j=0; j<=M; ++j)
{
float u = i/(float)N;
float v = j/(float)M;

vert[i + j*(N+1)].p = GetUV(u, v);
vert[i + j*(N+1)].c = glm::normalize( vert[i + j*(N+1)].p );
}

vert[(N + 1)*(M + 1)].p = glm::vec3(0, 0, 0); //center point for cone base
vert[(N + 1)*(M + 1)].c = glm::vec3(0, 0, 0);
for (int i = 0; i <= N; i++) {
vert[(N + 1)*(M + 1) + 1 + i].p = vert[(N)-i].p; //cone base
vert[(N + 1)*(M + 1) + 1 + i].c = vert[(N)-i].c;
}


Render function:



glDrawElements( GL_TRIANGLES,       
3*2*(N)*(M),
GL_UNSIGNED_SHORT,
0);

glDrawArrays(GL_TRIANGLE_FAN, (N + 1)*(M + 1) + 1, (N + 2)); //draw cone base


The "cone base" is there because I started this project from a "Draw a cone" project.



How can I make a second circle but above the cylinder?



Edit:
M,N: Const numbers (20 and 10)



My parametric equation (which is a FUNCTION called GetUV() ):



u *= 2*3.1415f;
float cu = cosf(u), su = sinf(u), cv = cosf(v), sv = sinf(v);
float M = 2.f;
float r = 0.5;
float m = v*M;

return glm::vec3(r*sinf(u), m, r*cosf(u));


How I create Indices (inside Init() function):



 GLushort indices[3*2*(N)*(M)];
for (int i=0; i<N; ++i)
for (int j=0; j<M; ++j)
{
indices[6*i + j*3*2*(N) + 0] = (i) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 1] = (i+1) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 2] = (i) + (j+1)*(N+1);
indices[6*i + j*3*2*(N) + 3] = (i+1) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 4] = (i+1) + (j+1)*(N+1);
indices[6*i + j*3*2*(N) + 5] = (i) + (j+1)*(N+1);
}






c++ opengl graphics 3d glm-math






share|improve this question









New contributor




József Huszkó is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




József Huszkó is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited Nov 18 at 17:31





















New contributor




József Huszkó is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked Nov 17 at 18:37









József Huszkó

112




112




New contributor




József Huszkó is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





József Huszkó is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






József Huszkó is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








  • 1




    what is M,N ? you need just 2 circles ... but I am not seeing even the one where are any sin,cos ? The usual is compute X,Y as parametric circle and Z is constant (different for each base, their distance is the cylinder height)
    – Spektre
    Nov 17 at 19:11










  • ... and what does GetUV do? Why glDrawElements and glDrawArrays? Where is the element list?
    – Rabbid76
    Nov 17 at 19:14












  • Sorry, I edited the post.
    – József Huszkó
    Nov 17 at 19:28














  • 1




    what is M,N ? you need just 2 circles ... but I am not seeing even the one where are any sin,cos ? The usual is compute X,Y as parametric circle and Z is constant (different for each base, their distance is the cylinder height)
    – Spektre
    Nov 17 at 19:11










  • ... and what does GetUV do? Why glDrawElements and glDrawArrays? Where is the element list?
    – Rabbid76
    Nov 17 at 19:14












  • Sorry, I edited the post.
    – József Huszkó
    Nov 17 at 19:28








1




1




what is M,N ? you need just 2 circles ... but I am not seeing even the one where are any sin,cos ? The usual is compute X,Y as parametric circle and Z is constant (different for each base, their distance is the cylinder height)
– Spektre
Nov 17 at 19:11




what is M,N ? you need just 2 circles ... but I am not seeing even the one where are any sin,cos ? The usual is compute X,Y as parametric circle and Z is constant (different for each base, their distance is the cylinder height)
– Spektre
Nov 17 at 19:11












... and what does GetUV do? Why glDrawElements and glDrawArrays? Where is the element list?
– Rabbid76
Nov 17 at 19:14






... and what does GetUV do? Why glDrawElements and glDrawArrays? Where is the element list?
– Rabbid76
Nov 17 at 19:14














Sorry, I edited the post.
– József Huszkó
Nov 17 at 19:28




Sorry, I edited the post.
– József Huszkó
Nov 17 at 19:28












2 Answers
2






active

oldest

votes

















up vote
0
down vote













The easiest way to draw the other circular cap is to just change the model matrix of the circle and make the draw call again. So if you're doing something like this before calling glDrawArrays():



glm::mat4 modelViewMatrix = calculateModelViewMatrix();
glUniformMatrix4fv(modelViewLocation, 1, FALSE, modelViewMatrix);


Do the same thing but translate the modelViewMatrix so that it's at the other end of the cylinder.






share|improve this answer





















  • My goal is to make the other circle in the same way the first circle draws, with Vertex vectors.
    – József Huszkó
    Nov 17 at 19:57










  • You can do the same thing by hand by copying the geometry and doing the translation on the CPU then uploading it to the GPU again, but it's going to be far less efficient. That may not be a big deal in this context, but you should get out of the habit of uploading the same geometry multiple times because it's an antipattern when writing performant 3D code.
    – user1118321
    Nov 17 at 20:00


















up vote
0
down vote













So N is number of points on the circle circumference and M is the number of points per height...



LOL in your GetUV you are computing cu,su,cv,sv but not using them, instead you use the same sin and cos call again. if I see it right u=<0,1> maps circumference of the circle/cylinder (XZ plane circle) and v=<0,1> maps the height (Y). But it looks like that the function itself works as should (just slowly than possible) appart of that inaccurate M_PI usage which might cause artifacts.



First problem I see is



vert[i + j*(N+1)].c = glm::normalize( vert[i + j*(N+1)].p );


I would get rid of that line as it will create the cone ... which you do not want anymore (btw. very weird and slow method of cone creation)



Also the i + j*(N+1) is ugly instead I would do:



for (int ix=0,j=0; j<=M; j++)
for (int i=0; i<=N; i++,ix++)
{
float u = i/(float)N;
float v = j/(float)M;
vert[ix].p = GetUV(u, v);
}


Next problem you got is wrong usage of the Draw methods ... as you want a grid of points instead of just 2 circles you divided the stuff into GL_TRIANGLE_FAN and GL_TRIANGLES. That was almost correct but you should have:



2x GL_TRIANGLE_FAN one for each base
1x GL_TRIANGLES or GL_QUADS for the rest



as you want to use indices it is basically simpler/faster to use all as triangles and feed the indices buffer correctly so you got just single draw call. Sadly we do not see the part of code where you are computing the indices ...



Why N+1 and M+1 points? You do not need to duplicate first point in vert you can do it in indices instead...



Hope the VBO related part of the code is correct ...



Also beware that faces of the other circle should have points in reverse order so GL_CULL_FACE will cull of faces correctly ...



[Edit1] C++ example



Anyway if you want to use normals latter on you should also duplicate the caps due to different normal on the edge... If I put all together in my style of coding I got this:



//---------------------------------------------------------------------------
const int M=20; // points per circle circumference
const int N=10; // point per cylinder height
const int pnts=3*((M*(N+2))+2); // 3* number of points
const int facs=3*M*(N+N+2); // 3* number of indices
float pnt[pnts]; // (x,y,z) position per each point
float nor[pnts]; // (x,y,z) normal per each point
int fac[facs]; // (i0,i1,i2) indices per each TRIANGLE
//---------------------------------------------------------------------------
void cylinder_init(float r,float h)
{
int i,j,ix,i0,i1,i2,i3;
float x,y,z,a,da,dz;
// compute position and normals
ix=0;
dz=h/double(N-1);
da=2.0*M_PI/double(M);
for (z=-0.5*h,j=0;j<N;j++,z+=dz) // circles
for (a=0.0,i=0;i<M;i++,a+=da)
{
x=cos(a);
y=sin(a);
pnt[ix]=r*x; nor[ix]=x; ix++;
pnt[ix]=r*y; nor[ix]=y; ix++;
pnt[ix]=z; nor[ix]=0.0; ix++;
}
pnt[ix]= 0.0; nor[ix]= 0.0; ix++; // top cap
pnt[ix]= 0.0; nor[ix]= 0.0; ix++;
pnt[ix]=+0.5*h; nor[ix]=+1.0; ix++;
for (j=ix-3*(M+1),i=0;i<M;i++)
{
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]=+1.0; ix++; j++;
}
pnt[ix]= 0.0; nor[ix]= 0.0; ix++; // bottom cap
pnt[ix]= 0.0; nor[ix]= 0.0; ix++;
pnt[ix]=-0.5*h; nor[ix]=-1.0; ix++;
for (j=0,i=0;i<M;i++)
{
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]=-1.0; ix++; j++;
}
// compute triangle indices
ix=0; i0=M-1; i1=0; i2=i0+M; i3=i1+M; // circles
for (j=0;j<N-1;j++,i0+=M,i2+=M)
for (i=0;i<M;i++,i0=i1,i1++,i2=i3,i3++)
{
fac[ix]=i0; ix++;
fac[ix]=i1; ix++;
fac[ix]=i2; ix++;
fac[ix]=i2; ix++;
fac[ix]=i1; ix++;
fac[ix]=i3; ix++;
}
i2=M*N; i0=i2+M; i1=i2+1; // top cap
for (i=0;i<M;i++,i0=i1,i1++)
{
fac[ix]=i0; ix++;
fac[ix]=i1; ix++;
fac[ix]=i2; ix++;
}
i2+=M+1; i0=i2+M; i1=i2+1; // bottom cap
for (i=0;i<M;i++,i0=i1,i1++)
{
fac[ix]=i2; ix++;
fac[ix]=i1; ix++;
fac[ix]=i0; ix++;
}
}
//---------------------------------------------------------------------------


And preview:



preview



You just use single draw with GL_TRIANGLES on the whole fac[facs] indices buffer.






share|improve this answer























  • Thank you for your answer, I edited the post and added the Indices part.
    – József Huszkó
    Nov 18 at 17:32










  • @JózsefHuszkó I updated my answer also ...
    – Spektre
    Nov 18 at 19:39










  • @JózsefHuszkó how is it going did you solve your issue or not?
    – Spektre
    7 hours ago











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});






József Huszkó is a new contributor. Be nice, and check out our Code of Conduct.










 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53354308%2fc-opengl-how-to-make-a-second-circle-over-the-cylinder%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
0
down vote













The easiest way to draw the other circular cap is to just change the model matrix of the circle and make the draw call again. So if you're doing something like this before calling glDrawArrays():



glm::mat4 modelViewMatrix = calculateModelViewMatrix();
glUniformMatrix4fv(modelViewLocation, 1, FALSE, modelViewMatrix);


Do the same thing but translate the modelViewMatrix so that it's at the other end of the cylinder.






share|improve this answer





















  • My goal is to make the other circle in the same way the first circle draws, with Vertex vectors.
    – József Huszkó
    Nov 17 at 19:57










  • You can do the same thing by hand by copying the geometry and doing the translation on the CPU then uploading it to the GPU again, but it's going to be far less efficient. That may not be a big deal in this context, but you should get out of the habit of uploading the same geometry multiple times because it's an antipattern when writing performant 3D code.
    – user1118321
    Nov 17 at 20:00















up vote
0
down vote













The easiest way to draw the other circular cap is to just change the model matrix of the circle and make the draw call again. So if you're doing something like this before calling glDrawArrays():



glm::mat4 modelViewMatrix = calculateModelViewMatrix();
glUniformMatrix4fv(modelViewLocation, 1, FALSE, modelViewMatrix);


Do the same thing but translate the modelViewMatrix so that it's at the other end of the cylinder.






share|improve this answer





















  • My goal is to make the other circle in the same way the first circle draws, with Vertex vectors.
    – József Huszkó
    Nov 17 at 19:57










  • You can do the same thing by hand by copying the geometry and doing the translation on the CPU then uploading it to the GPU again, but it's going to be far less efficient. That may not be a big deal in this context, but you should get out of the habit of uploading the same geometry multiple times because it's an antipattern when writing performant 3D code.
    – user1118321
    Nov 17 at 20:00













up vote
0
down vote










up vote
0
down vote









The easiest way to draw the other circular cap is to just change the model matrix of the circle and make the draw call again. So if you're doing something like this before calling glDrawArrays():



glm::mat4 modelViewMatrix = calculateModelViewMatrix();
glUniformMatrix4fv(modelViewLocation, 1, FALSE, modelViewMatrix);


Do the same thing but translate the modelViewMatrix so that it's at the other end of the cylinder.






share|improve this answer












The easiest way to draw the other circular cap is to just change the model matrix of the circle and make the draw call again. So if you're doing something like this before calling glDrawArrays():



glm::mat4 modelViewMatrix = calculateModelViewMatrix();
glUniformMatrix4fv(modelViewLocation, 1, FALSE, modelViewMatrix);


Do the same thing but translate the modelViewMatrix so that it's at the other end of the cylinder.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 17 at 19:43









user1118321

19.2k43963




19.2k43963












  • My goal is to make the other circle in the same way the first circle draws, with Vertex vectors.
    – József Huszkó
    Nov 17 at 19:57










  • You can do the same thing by hand by copying the geometry and doing the translation on the CPU then uploading it to the GPU again, but it's going to be far less efficient. That may not be a big deal in this context, but you should get out of the habit of uploading the same geometry multiple times because it's an antipattern when writing performant 3D code.
    – user1118321
    Nov 17 at 20:00


















  • My goal is to make the other circle in the same way the first circle draws, with Vertex vectors.
    – József Huszkó
    Nov 17 at 19:57










  • You can do the same thing by hand by copying the geometry and doing the translation on the CPU then uploading it to the GPU again, but it's going to be far less efficient. That may not be a big deal in this context, but you should get out of the habit of uploading the same geometry multiple times because it's an antipattern when writing performant 3D code.
    – user1118321
    Nov 17 at 20:00
















My goal is to make the other circle in the same way the first circle draws, with Vertex vectors.
– József Huszkó
Nov 17 at 19:57




My goal is to make the other circle in the same way the first circle draws, with Vertex vectors.
– József Huszkó
Nov 17 at 19:57












You can do the same thing by hand by copying the geometry and doing the translation on the CPU then uploading it to the GPU again, but it's going to be far less efficient. That may not be a big deal in this context, but you should get out of the habit of uploading the same geometry multiple times because it's an antipattern when writing performant 3D code.
– user1118321
Nov 17 at 20:00




You can do the same thing by hand by copying the geometry and doing the translation on the CPU then uploading it to the GPU again, but it's going to be far less efficient. That may not be a big deal in this context, but you should get out of the habit of uploading the same geometry multiple times because it's an antipattern when writing performant 3D code.
– user1118321
Nov 17 at 20:00












up vote
0
down vote













So N is number of points on the circle circumference and M is the number of points per height...



LOL in your GetUV you are computing cu,su,cv,sv but not using them, instead you use the same sin and cos call again. if I see it right u=<0,1> maps circumference of the circle/cylinder (XZ plane circle) and v=<0,1> maps the height (Y). But it looks like that the function itself works as should (just slowly than possible) appart of that inaccurate M_PI usage which might cause artifacts.



First problem I see is



vert[i + j*(N+1)].c = glm::normalize( vert[i + j*(N+1)].p );


I would get rid of that line as it will create the cone ... which you do not want anymore (btw. very weird and slow method of cone creation)



Also the i + j*(N+1) is ugly instead I would do:



for (int ix=0,j=0; j<=M; j++)
for (int i=0; i<=N; i++,ix++)
{
float u = i/(float)N;
float v = j/(float)M;
vert[ix].p = GetUV(u, v);
}


Next problem you got is wrong usage of the Draw methods ... as you want a grid of points instead of just 2 circles you divided the stuff into GL_TRIANGLE_FAN and GL_TRIANGLES. That was almost correct but you should have:



2x GL_TRIANGLE_FAN one for each base
1x GL_TRIANGLES or GL_QUADS for the rest



as you want to use indices it is basically simpler/faster to use all as triangles and feed the indices buffer correctly so you got just single draw call. Sadly we do not see the part of code where you are computing the indices ...



Why N+1 and M+1 points? You do not need to duplicate first point in vert you can do it in indices instead...



Hope the VBO related part of the code is correct ...



Also beware that faces of the other circle should have points in reverse order so GL_CULL_FACE will cull of faces correctly ...



[Edit1] C++ example



Anyway if you want to use normals latter on you should also duplicate the caps due to different normal on the edge... If I put all together in my style of coding I got this:



//---------------------------------------------------------------------------
const int M=20; // points per circle circumference
const int N=10; // point per cylinder height
const int pnts=3*((M*(N+2))+2); // 3* number of points
const int facs=3*M*(N+N+2); // 3* number of indices
float pnt[pnts]; // (x,y,z) position per each point
float nor[pnts]; // (x,y,z) normal per each point
int fac[facs]; // (i0,i1,i2) indices per each TRIANGLE
//---------------------------------------------------------------------------
void cylinder_init(float r,float h)
{
int i,j,ix,i0,i1,i2,i3;
float x,y,z,a,da,dz;
// compute position and normals
ix=0;
dz=h/double(N-1);
da=2.0*M_PI/double(M);
for (z=-0.5*h,j=0;j<N;j++,z+=dz) // circles
for (a=0.0,i=0;i<M;i++,a+=da)
{
x=cos(a);
y=sin(a);
pnt[ix]=r*x; nor[ix]=x; ix++;
pnt[ix]=r*y; nor[ix]=y; ix++;
pnt[ix]=z; nor[ix]=0.0; ix++;
}
pnt[ix]= 0.0; nor[ix]= 0.0; ix++; // top cap
pnt[ix]= 0.0; nor[ix]= 0.0; ix++;
pnt[ix]=+0.5*h; nor[ix]=+1.0; ix++;
for (j=ix-3*(M+1),i=0;i<M;i++)
{
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]=+1.0; ix++; j++;
}
pnt[ix]= 0.0; nor[ix]= 0.0; ix++; // bottom cap
pnt[ix]= 0.0; nor[ix]= 0.0; ix++;
pnt[ix]=-0.5*h; nor[ix]=-1.0; ix++;
for (j=0,i=0;i<M;i++)
{
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]=-1.0; ix++; j++;
}
// compute triangle indices
ix=0; i0=M-1; i1=0; i2=i0+M; i3=i1+M; // circles
for (j=0;j<N-1;j++,i0+=M,i2+=M)
for (i=0;i<M;i++,i0=i1,i1++,i2=i3,i3++)
{
fac[ix]=i0; ix++;
fac[ix]=i1; ix++;
fac[ix]=i2; ix++;
fac[ix]=i2; ix++;
fac[ix]=i1; ix++;
fac[ix]=i3; ix++;
}
i2=M*N; i0=i2+M; i1=i2+1; // top cap
for (i=0;i<M;i++,i0=i1,i1++)
{
fac[ix]=i0; ix++;
fac[ix]=i1; ix++;
fac[ix]=i2; ix++;
}
i2+=M+1; i0=i2+M; i1=i2+1; // bottom cap
for (i=0;i<M;i++,i0=i1,i1++)
{
fac[ix]=i2; ix++;
fac[ix]=i1; ix++;
fac[ix]=i0; ix++;
}
}
//---------------------------------------------------------------------------


And preview:



preview



You just use single draw with GL_TRIANGLES on the whole fac[facs] indices buffer.






share|improve this answer























  • Thank you for your answer, I edited the post and added the Indices part.
    – József Huszkó
    Nov 18 at 17:32










  • @JózsefHuszkó I updated my answer also ...
    – Spektre
    Nov 18 at 19:39










  • @JózsefHuszkó how is it going did you solve your issue or not?
    – Spektre
    7 hours ago















up vote
0
down vote













So N is number of points on the circle circumference and M is the number of points per height...



LOL in your GetUV you are computing cu,su,cv,sv but not using them, instead you use the same sin and cos call again. if I see it right u=<0,1> maps circumference of the circle/cylinder (XZ plane circle) and v=<0,1> maps the height (Y). But it looks like that the function itself works as should (just slowly than possible) appart of that inaccurate M_PI usage which might cause artifacts.



First problem I see is



vert[i + j*(N+1)].c = glm::normalize( vert[i + j*(N+1)].p );


I would get rid of that line as it will create the cone ... which you do not want anymore (btw. very weird and slow method of cone creation)



Also the i + j*(N+1) is ugly instead I would do:



for (int ix=0,j=0; j<=M; j++)
for (int i=0; i<=N; i++,ix++)
{
float u = i/(float)N;
float v = j/(float)M;
vert[ix].p = GetUV(u, v);
}


Next problem you got is wrong usage of the Draw methods ... as you want a grid of points instead of just 2 circles you divided the stuff into GL_TRIANGLE_FAN and GL_TRIANGLES. That was almost correct but you should have:



2x GL_TRIANGLE_FAN one for each base
1x GL_TRIANGLES or GL_QUADS for the rest



as you want to use indices it is basically simpler/faster to use all as triangles and feed the indices buffer correctly so you got just single draw call. Sadly we do not see the part of code where you are computing the indices ...



Why N+1 and M+1 points? You do not need to duplicate first point in vert you can do it in indices instead...



Hope the VBO related part of the code is correct ...



Also beware that faces of the other circle should have points in reverse order so GL_CULL_FACE will cull of faces correctly ...



[Edit1] C++ example



Anyway if you want to use normals latter on you should also duplicate the caps due to different normal on the edge... If I put all together in my style of coding I got this:



//---------------------------------------------------------------------------
const int M=20; // points per circle circumference
const int N=10; // point per cylinder height
const int pnts=3*((M*(N+2))+2); // 3* number of points
const int facs=3*M*(N+N+2); // 3* number of indices
float pnt[pnts]; // (x,y,z) position per each point
float nor[pnts]; // (x,y,z) normal per each point
int fac[facs]; // (i0,i1,i2) indices per each TRIANGLE
//---------------------------------------------------------------------------
void cylinder_init(float r,float h)
{
int i,j,ix,i0,i1,i2,i3;
float x,y,z,a,da,dz;
// compute position and normals
ix=0;
dz=h/double(N-1);
da=2.0*M_PI/double(M);
for (z=-0.5*h,j=0;j<N;j++,z+=dz) // circles
for (a=0.0,i=0;i<M;i++,a+=da)
{
x=cos(a);
y=sin(a);
pnt[ix]=r*x; nor[ix]=x; ix++;
pnt[ix]=r*y; nor[ix]=y; ix++;
pnt[ix]=z; nor[ix]=0.0; ix++;
}
pnt[ix]= 0.0; nor[ix]= 0.0; ix++; // top cap
pnt[ix]= 0.0; nor[ix]= 0.0; ix++;
pnt[ix]=+0.5*h; nor[ix]=+1.0; ix++;
for (j=ix-3*(M+1),i=0;i<M;i++)
{
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]=+1.0; ix++; j++;
}
pnt[ix]= 0.0; nor[ix]= 0.0; ix++; // bottom cap
pnt[ix]= 0.0; nor[ix]= 0.0; ix++;
pnt[ix]=-0.5*h; nor[ix]=-1.0; ix++;
for (j=0,i=0;i<M;i++)
{
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]=-1.0; ix++; j++;
}
// compute triangle indices
ix=0; i0=M-1; i1=0; i2=i0+M; i3=i1+M; // circles
for (j=0;j<N-1;j++,i0+=M,i2+=M)
for (i=0;i<M;i++,i0=i1,i1++,i2=i3,i3++)
{
fac[ix]=i0; ix++;
fac[ix]=i1; ix++;
fac[ix]=i2; ix++;
fac[ix]=i2; ix++;
fac[ix]=i1; ix++;
fac[ix]=i3; ix++;
}
i2=M*N; i0=i2+M; i1=i2+1; // top cap
for (i=0;i<M;i++,i0=i1,i1++)
{
fac[ix]=i0; ix++;
fac[ix]=i1; ix++;
fac[ix]=i2; ix++;
}
i2+=M+1; i0=i2+M; i1=i2+1; // bottom cap
for (i=0;i<M;i++,i0=i1,i1++)
{
fac[ix]=i2; ix++;
fac[ix]=i1; ix++;
fac[ix]=i0; ix++;
}
}
//---------------------------------------------------------------------------


And preview:



preview



You just use single draw with GL_TRIANGLES on the whole fac[facs] indices buffer.






share|improve this answer























  • Thank you for your answer, I edited the post and added the Indices part.
    – József Huszkó
    Nov 18 at 17:32










  • @JózsefHuszkó I updated my answer also ...
    – Spektre
    Nov 18 at 19:39










  • @JózsefHuszkó how is it going did you solve your issue or not?
    – Spektre
    7 hours ago













up vote
0
down vote










up vote
0
down vote









So N is number of points on the circle circumference and M is the number of points per height...



LOL in your GetUV you are computing cu,su,cv,sv but not using them, instead you use the same sin and cos call again. if I see it right u=<0,1> maps circumference of the circle/cylinder (XZ plane circle) and v=<0,1> maps the height (Y). But it looks like that the function itself works as should (just slowly than possible) appart of that inaccurate M_PI usage which might cause artifacts.



First problem I see is



vert[i + j*(N+1)].c = glm::normalize( vert[i + j*(N+1)].p );


I would get rid of that line as it will create the cone ... which you do not want anymore (btw. very weird and slow method of cone creation)



Also the i + j*(N+1) is ugly instead I would do:



for (int ix=0,j=0; j<=M; j++)
for (int i=0; i<=N; i++,ix++)
{
float u = i/(float)N;
float v = j/(float)M;
vert[ix].p = GetUV(u, v);
}


Next problem you got is wrong usage of the Draw methods ... as you want a grid of points instead of just 2 circles you divided the stuff into GL_TRIANGLE_FAN and GL_TRIANGLES. That was almost correct but you should have:



2x GL_TRIANGLE_FAN one for each base
1x GL_TRIANGLES or GL_QUADS for the rest



as you want to use indices it is basically simpler/faster to use all as triangles and feed the indices buffer correctly so you got just single draw call. Sadly we do not see the part of code where you are computing the indices ...



Why N+1 and M+1 points? You do not need to duplicate first point in vert you can do it in indices instead...



Hope the VBO related part of the code is correct ...



Also beware that faces of the other circle should have points in reverse order so GL_CULL_FACE will cull of faces correctly ...



[Edit1] C++ example



Anyway if you want to use normals latter on you should also duplicate the caps due to different normal on the edge... If I put all together in my style of coding I got this:



//---------------------------------------------------------------------------
const int M=20; // points per circle circumference
const int N=10; // point per cylinder height
const int pnts=3*((M*(N+2))+2); // 3* number of points
const int facs=3*M*(N+N+2); // 3* number of indices
float pnt[pnts]; // (x,y,z) position per each point
float nor[pnts]; // (x,y,z) normal per each point
int fac[facs]; // (i0,i1,i2) indices per each TRIANGLE
//---------------------------------------------------------------------------
void cylinder_init(float r,float h)
{
int i,j,ix,i0,i1,i2,i3;
float x,y,z,a,da,dz;
// compute position and normals
ix=0;
dz=h/double(N-1);
da=2.0*M_PI/double(M);
for (z=-0.5*h,j=0;j<N;j++,z+=dz) // circles
for (a=0.0,i=0;i<M;i++,a+=da)
{
x=cos(a);
y=sin(a);
pnt[ix]=r*x; nor[ix]=x; ix++;
pnt[ix]=r*y; nor[ix]=y; ix++;
pnt[ix]=z; nor[ix]=0.0; ix++;
}
pnt[ix]= 0.0; nor[ix]= 0.0; ix++; // top cap
pnt[ix]= 0.0; nor[ix]= 0.0; ix++;
pnt[ix]=+0.5*h; nor[ix]=+1.0; ix++;
for (j=ix-3*(M+1),i=0;i<M;i++)
{
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]=+1.0; ix++; j++;
}
pnt[ix]= 0.0; nor[ix]= 0.0; ix++; // bottom cap
pnt[ix]= 0.0; nor[ix]= 0.0; ix++;
pnt[ix]=-0.5*h; nor[ix]=-1.0; ix++;
for (j=0,i=0;i<M;i++)
{
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]=-1.0; ix++; j++;
}
// compute triangle indices
ix=0; i0=M-1; i1=0; i2=i0+M; i3=i1+M; // circles
for (j=0;j<N-1;j++,i0+=M,i2+=M)
for (i=0;i<M;i++,i0=i1,i1++,i2=i3,i3++)
{
fac[ix]=i0; ix++;
fac[ix]=i1; ix++;
fac[ix]=i2; ix++;
fac[ix]=i2; ix++;
fac[ix]=i1; ix++;
fac[ix]=i3; ix++;
}
i2=M*N; i0=i2+M; i1=i2+1; // top cap
for (i=0;i<M;i++,i0=i1,i1++)
{
fac[ix]=i0; ix++;
fac[ix]=i1; ix++;
fac[ix]=i2; ix++;
}
i2+=M+1; i0=i2+M; i1=i2+1; // bottom cap
for (i=0;i<M;i++,i0=i1,i1++)
{
fac[ix]=i2; ix++;
fac[ix]=i1; ix++;
fac[ix]=i0; ix++;
}
}
//---------------------------------------------------------------------------


And preview:



preview



You just use single draw with GL_TRIANGLES on the whole fac[facs] indices buffer.






share|improve this answer














So N is number of points on the circle circumference and M is the number of points per height...



LOL in your GetUV you are computing cu,su,cv,sv but not using them, instead you use the same sin and cos call again. if I see it right u=<0,1> maps circumference of the circle/cylinder (XZ plane circle) and v=<0,1> maps the height (Y). But it looks like that the function itself works as should (just slowly than possible) appart of that inaccurate M_PI usage which might cause artifacts.



First problem I see is



vert[i + j*(N+1)].c = glm::normalize( vert[i + j*(N+1)].p );


I would get rid of that line as it will create the cone ... which you do not want anymore (btw. very weird and slow method of cone creation)



Also the i + j*(N+1) is ugly instead I would do:



for (int ix=0,j=0; j<=M; j++)
for (int i=0; i<=N; i++,ix++)
{
float u = i/(float)N;
float v = j/(float)M;
vert[ix].p = GetUV(u, v);
}


Next problem you got is wrong usage of the Draw methods ... as you want a grid of points instead of just 2 circles you divided the stuff into GL_TRIANGLE_FAN and GL_TRIANGLES. That was almost correct but you should have:



2x GL_TRIANGLE_FAN one for each base
1x GL_TRIANGLES or GL_QUADS for the rest



as you want to use indices it is basically simpler/faster to use all as triangles and feed the indices buffer correctly so you got just single draw call. Sadly we do not see the part of code where you are computing the indices ...



Why N+1 and M+1 points? You do not need to duplicate first point in vert you can do it in indices instead...



Hope the VBO related part of the code is correct ...



Also beware that faces of the other circle should have points in reverse order so GL_CULL_FACE will cull of faces correctly ...



[Edit1] C++ example



Anyway if you want to use normals latter on you should also duplicate the caps due to different normal on the edge... If I put all together in my style of coding I got this:



//---------------------------------------------------------------------------
const int M=20; // points per circle circumference
const int N=10; // point per cylinder height
const int pnts=3*((M*(N+2))+2); // 3* number of points
const int facs=3*M*(N+N+2); // 3* number of indices
float pnt[pnts]; // (x,y,z) position per each point
float nor[pnts]; // (x,y,z) normal per each point
int fac[facs]; // (i0,i1,i2) indices per each TRIANGLE
//---------------------------------------------------------------------------
void cylinder_init(float r,float h)
{
int i,j,ix,i0,i1,i2,i3;
float x,y,z,a,da,dz;
// compute position and normals
ix=0;
dz=h/double(N-1);
da=2.0*M_PI/double(M);
for (z=-0.5*h,j=0;j<N;j++,z+=dz) // circles
for (a=0.0,i=0;i<M;i++,a+=da)
{
x=cos(a);
y=sin(a);
pnt[ix]=r*x; nor[ix]=x; ix++;
pnt[ix]=r*y; nor[ix]=y; ix++;
pnt[ix]=z; nor[ix]=0.0; ix++;
}
pnt[ix]= 0.0; nor[ix]= 0.0; ix++; // top cap
pnt[ix]= 0.0; nor[ix]= 0.0; ix++;
pnt[ix]=+0.5*h; nor[ix]=+1.0; ix++;
for (j=ix-3*(M+1),i=0;i<M;i++)
{
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]=+1.0; ix++; j++;
}
pnt[ix]= 0.0; nor[ix]= 0.0; ix++; // bottom cap
pnt[ix]= 0.0; nor[ix]= 0.0; ix++;
pnt[ix]=-0.5*h; nor[ix]=-1.0; ix++;
for (j=0,i=0;i<M;i++)
{
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]=-1.0; ix++; j++;
}
// compute triangle indices
ix=0; i0=M-1; i1=0; i2=i0+M; i3=i1+M; // circles
for (j=0;j<N-1;j++,i0+=M,i2+=M)
for (i=0;i<M;i++,i0=i1,i1++,i2=i3,i3++)
{
fac[ix]=i0; ix++;
fac[ix]=i1; ix++;
fac[ix]=i2; ix++;
fac[ix]=i2; ix++;
fac[ix]=i1; ix++;
fac[ix]=i3; ix++;
}
i2=M*N; i0=i2+M; i1=i2+1; // top cap
for (i=0;i<M;i++,i0=i1,i1++)
{
fac[ix]=i0; ix++;
fac[ix]=i1; ix++;
fac[ix]=i2; ix++;
}
i2+=M+1; i0=i2+M; i1=i2+1; // bottom cap
for (i=0;i<M;i++,i0=i1,i1++)
{
fac[ix]=i2; ix++;
fac[ix]=i1; ix++;
fac[ix]=i0; ix++;
}
}
//---------------------------------------------------------------------------


And preview:



preview



You just use single draw with GL_TRIANGLES on the whole fac[facs] indices buffer.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 18 at 19:38

























answered Nov 18 at 6:53









Spektre

28.8k645201




28.8k645201












  • Thank you for your answer, I edited the post and added the Indices part.
    – József Huszkó
    Nov 18 at 17:32










  • @JózsefHuszkó I updated my answer also ...
    – Spektre
    Nov 18 at 19:39










  • @JózsefHuszkó how is it going did you solve your issue or not?
    – Spektre
    7 hours ago


















  • Thank you for your answer, I edited the post and added the Indices part.
    – József Huszkó
    Nov 18 at 17:32










  • @JózsefHuszkó I updated my answer also ...
    – Spektre
    Nov 18 at 19:39










  • @JózsefHuszkó how is it going did you solve your issue or not?
    – Spektre
    7 hours ago
















Thank you for your answer, I edited the post and added the Indices part.
– József Huszkó
Nov 18 at 17:32




Thank you for your answer, I edited the post and added the Indices part.
– József Huszkó
Nov 18 at 17:32












@JózsefHuszkó I updated my answer also ...
– Spektre
Nov 18 at 19:39




@JózsefHuszkó I updated my answer also ...
– Spektre
Nov 18 at 19:39












@JózsefHuszkó how is it going did you solve your issue or not?
– Spektre
7 hours ago




@JózsefHuszkó how is it going did you solve your issue or not?
– Spektre
7 hours ago










József Huszkó is a new contributor. Be nice, and check out our Code of Conduct.










 

draft saved


draft discarded


















József Huszkó is a new contributor. Be nice, and check out our Code of Conduct.













József Huszkó is a new contributor. Be nice, and check out our Code of Conduct.












József Huszkó is a new contributor. Be nice, and check out our Code of Conduct.















 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53354308%2fc-opengl-how-to-make-a-second-circle-over-the-cylinder%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Create new schema in PostgreSQL using DBeaver

Deepest pit of an array with Javascript: test on Codility

Costa Masnaga