CXX: problems creating geometry from scratch

It seems I found a bug in the CXX api. I’ve written a small program to generate geometry from scratch (two triangles) but it crashes on me:

#pragma warning (disable: 4267)
#include "pandaFramework.h"
#include "pandaSystem.h"
#include "geomVertexFormat.h"
#include "geomVertexArrayFormat.h"
#include "geomVertexData.h"
#include "geomVertexWriter.h"
#include "geomTriangles.h"
#include "geom.h"
#include "geomNode.h"
#include "renderState.h"
#include "TextureAttrib.h"
#include "TextureStage.h"

PandaFramework framework;

int main(int argc, char *argv[]) {
  //open a new window framework
  framework.open_framework(argc, argv);
  //set the window title to My Panda3D Window
  framework.set_window_title("My Panda3D Window");
  //open the window
  WindowFramework *window = framework.open_window();

  
  // create a quad from scratch
  const GeomVertexFormat* gf = GeomVertexFormat::get_v3t2();
  GeomVertexData* vdata = new GeomVertexData("test", gf, GeomEnums::UsageHint::UH_static);
  GeomVertexWriter* vwriter = new GeomVertexWriter(vdata, "vertex");
  GeomVertexWriter* twriter = new GeomVertexWriter(vdata, "texture");

  vwriter->add_data3f(-1,0,-1);
  twriter->add_data2f(0,0);
  vwriter->add_data3f(1,0,-1);
  twriter->add_data2f(1,0);
  vwriter->add_data3f(1,0,1);
  twriter->add_data2f(1,1);
  vwriter->add_data3f(-1,0,1);
  twriter->add_data2f(0,1);

  // add the two triangles
  GeomTriangles* prim = new GeomTriangles(GeomEnums::UsageHint::UH_static);
  prim->add_vertices(0,1,2);
  prim->close_primitive();
  prim->add_vertices(0,2,3);
  prim->close_primitive();
  
  //close the window framework
  framework.close_framework();
  return (0);
}

The crash (access violation) happens in this line:

prim->add_vertices(0,2,3)

I’ve stepped into it a little bit, and the trouble is caused because the prim decides that it needs to be indexed after seeing the vertex 0 a second time and this confuses something around _cdata.
I don’t understand the inner workings well enough to understand exactly whats going on.

I have a workaround for this problem, when I use a trianglefan instead of two seperate triangles, it works. but nevertheless I wanted to report this problem.

It occurs both in 1.3.2 and in the latest version from CVS.

Or am I doing something wrong?

I suspect your GeomVertexData is getting destructed, because you are not using Panda’s reference counting properly.

In general in Panda, some objects inherit from ReferenceCount and some objects don’t. For instance, GeomVertexData and GeomTriangles are examples of classes that inherit from ReferenceCount. Objects that inherit from ReferenceCount should always be stored in a PointerTo, not a regular pointer:

PT(GeomVertexData) vdata = new GeomVertexData("test", gf, GeomEnums::UsageHint::UH_static);
PT(GeomTriangles) prim = new GeomTriangles(GeomEnums::UsageHint::UH_static)

You must do this because initially the reference count is zero, and only the PointerTo object will increment it to one. If you call any method on an object whose reference count is zero, it may be deleted.

Incidentally, most objects that don’t inherit from ReferenceCount are intended to be used as concretes, not as pointers. GeomVertexWriter is an example of a class that does not inherit from ReferenceCount, and is intended to be used as a concrete object:

  GeomVertexWriter vwriter(vdata, "vertex");
  GeomVertexWriter twriter(vdata, "texture");
  vwriter.add_data3f(-1,0,-1);
  twriter.add_data2f(0,0);

Sorry, there’s not documentation about which class is which, other than the inheritance hierarchy. You just have to learn which classes are which. It may be helpful to follow existing example code in Panda.

David

Thanks, that did the trick!

Erik