Advertisement

Unreliable Object Handles

Started by October 02, 2020 06:52 AM
2 comments, last by WitchLord 4 years, 1 month ago

I'm experiencing quite a strange issue trying to register a simple rendering API… I have a texture and renderer2D class that work perfectly to render something on the screen when I do it through native C++… The problem arises when I try to use the API through AngelScript, it isn't very reliable.

Here is how I'm registering the two classes:

r = m_engine->RegisterObjectType("Texture", 0, asOBJ_REF); assert(r >= 0);
r = m_engine->RegisterObjectBehaviour("Texture", asBEHAVE_FACTORY, "Texture@ f(string)", asFUNCTION(Texture_Factory), asCALL_CDECL); assert( r >= 0 );
r = m_engine->RegisterObjectBehaviour("Texture", asBEHAVE_ADDREF, "void f()", asMETHOD(Texture,AddRef), asCALL_THISCALL); assert( r >= 0 );
r = m_engine->RegisterObjectBehaviour("Texture", asBEHAVE_RELEASE, "void f()", asMETHOD(Texture,Release), asCALL_THISCALL); assert( r >= 0 );
r = m_engine->RegisterObjectMethod("Texture", "void Bind(int)", asMETHOD(Texture,Bind), asCALL_THISCALL); assert( r >= 0 );

r = m_engine->RegisterObjectType("SpriteRenderer", 0, asOBJ_REF); assert(r >= 0);
r = m_engine->RegisterObjectBehaviour("SpriteRenderer", asBEHAVE_FACTORY, "SpriteRenderer@ f(mat4& in, string)", asFUNCTION(SpriteRenderer_Factory), asCALL_CDECL); assert( r >= 0 );
r = m_engine->RegisterObjectBehaviour("SpriteRenderer", asBEHAVE_ADDREF, "void f()", asMETHOD(SpriteRenderer,AddRef), asCALL_THISCALL); assert( r >= 0 );
r = m_engine->RegisterObjectBehaviour("SpriteRenderer", asBEHAVE_RELEASE, "void f()", asMETHOD(SpriteRenderer,Release), asCALL_THISCALL); assert( r >= 0 );
r = m_engine->RegisterObjectMethod("SpriteRenderer", "void DrawSprite(Texture@)", asFUNCTION(SpriteRenderer_DrawSprite), asCALL_CDECL_OBJLAST); assert( r >= 0 );

Here are the relevant wrappers:

static SpriteRenderer* SpriteRenderer_Factory(const glm::mat4& projection, std::string& shaderPath) {
  return new SpriteRenderer(projection, shaderPath.c_str());
}

static void SpriteRenderer_DrawSprite(Texture* texture, SpriteRenderer* renderer) {
  renderer->DrawSprite(*texture, glm::vec2(0,0));
}

static Texture* Texture_Factory(std::string& path) {
  return new Texture(path.c_str());
}

And here is how I'm using it in AngelScript (I can confirm that OnInit and OnRender are being called correctly):

Graphics::SpriteRenderer@ spriteRenderer;
Graphics::Texture@ testTexture;

void OnInit() {
  @spriteRenderer = @Graphics::SpriteRenderer(ortho(), "Data/Shaders/Sprite.glsl");

  @testTexture = @Graphics::Texture("Data/Textures/guy.bmp");
}

void OnRender() {
  spriteRenderer.DrawSprite(@testTexture);
}

The problem is: It only renders something on the screen 7 times out of 10. Sometimes it works flawlessly, sometimes it doesn't render anything at all… What am I doing wrong?

None

Nevermind, I fixed my problem. What was happening is the renderer that was being called by the script wasn't being cleared properly.

None

Advertisement

Hi Veridis,

I'm glad you figured out the problem.

Pay attention to the reference counters so you don't get a memory leak. Your DrawSprite method should release the reference on the Texture it received as a handle from AngelScript. Either that or register the method to receive a reference instead of a handle.

Regards,
Andreas

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement