Drawing a cone lazarus / 70-OpenGL ---------------------------------------------------------------------- ehj666 · 2017-02-28 01:15 I have the following code ported from Delphi. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TBackplot.ShowTool(const X, Y, Z: Extended);   var    Cone: gluQuadricObj;   begin    Cone := gluNewQuadric;    gluQuadricNormals(Cone, GLU_SMOOTH);    glPushMatrix;    glColor3f(0.0, 0.75, 0.75);    glTranslatef(X - Cx, Y - Cy, Z - Cz);  gluCylinder(Cone, 0.0, 0.25, 1.0, 26, 13);    glPopMatrix;  end;   On the line "Cone := gluNewQuadric;" I get the error "Incompatible types: got expected GLUquadric". I see that gluNewQuadric is defined in glu.pp as  gluNewQuadric : function:PGLUquadric;extdecl; But I do not know how to resolve the incompatible types; I am using it with TOpenGlControl. Thanks ---------------------------------------------------------------------- User137 · 2017-02-28 03:35 PGLUquadric is a pointer type, gluQuadricObj you are using for Cone is not. ---------------------------------------------------------------------- ehj666 · 2017-02-28 13:56 I realize that, my question is what construct do I use? This worked in D7 so it seems to me that gluQuadricObj or gluNewQuadric is defined differently in fp. I am trying to port an old application and haven't touched opengl in at least 10 years, so just asking how I draw a cone under fp. ---------------------------------------------------------------------- balazsszekely · 2017-02-28 14:57 @ehj666 What @User137 is saying, you need a @ before Cone. ---------------------------------------------------------------------- User137 · 2017-02-28 21:54 If you want this Cone := gluNewQuadric; to work, you need Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var    Cone: PGLUQuadric; // or Cone: ^gluQuadricObj; But then check definition of gluCylinder. Is it a pointer or not? It depends on that if you can use Cone directly or Cone^. ---------------------------------------------------------------------- ehj666 · 2017-02-28 23:39 That is not correct either, gluNewQuadric is defines as: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i gluNewQuadric : function:PGLUquadric;extdecl;  So, as I understand it, it does not return a PGLUquadric, it returns a pointer to a function which then returns a PGLUquadric. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   var    Cone: pgluQuadric;   begin    Cone := gluNewQuadric;    gluQuadricNormals(Cone, GLU_SMOOTH);  This does not work, nor does: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i     Cone := gluNewQuadric^; ---------------------------------------------------------------------- ehj666 · 2017-03-01 00:00 From a C example: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  GLUquadric* qobj; void init() // only call once on startup{  qobj = gluNewQuadric();  gluQuadricNormals(qobj, GLU_SMOOTH);} void wheel() // use object in your drawing{  gluCylinder(qobj, 1.0, 1.0, 0.4, 1, 16);} void cleanup() // call once when you exit program{  gluDeleteQuadric(qobj);} ---------------------------------------------------------------------- ehj666 · 2017-03-01 00:16 This at least compiles, if I cast gluNewQuadric as a pointer. Not far enough along to test at run time. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   var    Cone: pgluQuadric;   begin    Cone := pointer(gluNewQuadric);    gluQuadricNormals(Cone, GLU_SMOOTH); ---------------------------------------------------------------------- ehj666 · 2017-03-01 00:54 That compiles, but does not run. Blows out at: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i gluQuadricNormals(Cone, GLU_SMOOTH);  with "raised exception class 'External: SIGSEGV'". ---------------------------------------------------------------------- User137 · 2017-03-01 01:27 I figured you are using Lazarus' headers (not dglOpengl), so these from glu.pas: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i gluNewQuadric : function:PGLUquadric;extdecl;gluDeleteQuadric : procedure(quad:PGLUquadric);extdecl;gluCylinder : procedure(quad:PGLUquadric; base:GLdouble; top:GLdouble; height:GLdouble; slices:GLint;     stacks:GLint);extdecl;From that it's clear that you should have "var Cone: PGLUquadric;". But you also have to use gluDeleteQuadric(), otherwise you have a memory leak sort of thing. It's fine to dismiss in a simple demo that only calls gluNewQuadric once per program runtime. You can also keep reusing the same quadric index instead of always making a new one, if you only work with 1 model type at the time. Like if you want to render 1000 cones you still only need to call the gluNewQuadric just once. Other than that, all glu* based commands have been deprecated for many years and new drivers have no obligation to support them. I would guess they already don't work on android at all. And i don't know why you get sigsegv. What if you just draw a triangle with glbegin..glend? ---------------------------------------------------------------------- ehj666 · 2017-03-01 02:23 That was a simplified version for testing. Here is the full code: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i constructor TBackplot.Create(AGLControl: TopenGLControl);   begin    BackplotControl := AGLControl;    InitOpengl;  end; destructor TBackplot.Destroy;   begin    inherited Destroy;    gluDeleteQuadric(Cone);  end; procedure TBackplot.InitOpengl;   begin    Cone := pointer(gluNewQuadric);    gluQuadricNormals(Cone, GLU_SMOOTH);  end; procedure TBackplot.ShowTool(const X, Y, Z: Extended);   begin    glPushMatrix;    glColor3f(0.0, 0.75, 0.75);    glTranslatef(X - Cx, Y - Cy, Z - Cz);    gluCylinder(Cone, 0.0, 0.25, 1.0, 26, 13);    glPopMatrix;  end;   A simple triangle does work, implemented as follows: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TBackplot.Paint;   begin    glClearColor(0.0, 0.0, 0.0, 1.0); //Set black background    glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);    glLoadIdentity;    glBegin(GL_TRIANGLES);    glColor3f(1, 0, 0);      glVertex3f( 0.0, 1.0, 0.0);      glColor3f(0, 1, 0);      glVertex3f(-1.0,-1.0, 0.0);      glColor3f(0, 0, 1);      glVertex3f( 1.0,-1.0, 0.0);    glEnd;    BackplotControl.SwapBuffers;  end;  What should I be using instead of glu to render a cone? The code I am porting is 10-15 years old. ---------------------------------------------------------------------- User137 · 2017-03-01 03:57 Is there any difference if you do Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Cone := gluNewQuadric();instead of Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Cone := pointer(gluNewQuadric); Both sides should already be of identical types, so you don't need type conversion. ---------------------------------------------------------------------- ehj666 · 2017-03-01 04:22 Yes, the first gives an incompatible types compiler error. See first post. ---------------------------------------------------------------------- molly · 2017-03-01 04:56 User137 is correct. At least mode objfpc assumes the cone variable to match the function, while it is of course just a PGLUquadric. I was able to solve that by doing: Code: [Select]var   Cone: PGLUquadric; begin   Cone := gluNewQuadric(); end. To explicitly tell to _call_ the function. So, something seems off in ehj666's code. In addition to that, always check the return value in order to make sure that function is supported by your hardware/software to begin with. ---------------------------------------------------------------------- ehj666 · 2017-03-01 12:09 Sorry, I misunderstood. I thought the '()' at the end of gluNewQuadric was a typo, using C syntax. I did not realize that was valid syntax in fpc. That does compile, and so far is not generating a run time error. Thanks. ---------------------------------------------------------------------- molly · 2017-03-01 18:50 Quote from: ehj666 on March 01, 2017, 01:09:44 pmSorry, I misunderstood. I thought the '()' at the end of gluNewQuadric was a typo, using C syntax. I did not realize that was valid syntax in fpc. No need to apologize. If you are not familiar with these kind of thing then i can understand the mistake. The () brackets after the function name are very important here because the function itself that is part of opengl is stored inside a variable. When a would be your conedata, and b the variable that contains the pointer to the function then: Code: [Select]a := b; will try to assign the function that is stored in b to a. That is why you got the message from the compiler telling that type a and type b did not match. That is also why it is very dangerous to overrule that with casting b to a pointer in order to get it stored in a, because then you are in fact storing/copying the pointer to the opengl function into a. Hence the crash, as a pointer to a opengl function is not valid cone data. Now adding the () behind b so that it looks like: Code: [Select]a := b(); Will tell the compiler that your intention is to call the function that is assigned to variable b, and use its return value to be assigned to variable a. If not mistaken then mode delphi does this automatically for you, but mode objfpc is more or less forcing you to be explicit. Because in delphi, you would have to guess what the compiler is actually doing. QuoteThat does compile, and so far is not generating a run time error. I really hope so, otherwise i would have a hard time explaining why the nehe code 'just' works :-)