Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


DavidColson

Member Since 18 Nov 2013
Offline Last Active Jul 13 2015 04:33 AM

Topics I've Started

Returning an existing userdata in __index metamethod (Lua)

08 July 2015 - 03:49 AM

So I've been binding some C++ functions to Lua and all has been going well until I came across this problem.

local transform
transform = gfx3D.Transform(); -- Works fine (transform is a userdata)
transform.Position = Vector3(0, 0, 0) -- This seems to work fine (Position is a userdata)
transform.Position.z = -80 -- This doesn't work (z accessed with a __newindex call, position with an __index call)

LOG(tostring(transform.Position)) -- Prints X:0 Y:0 Z:0

Both transform and position are userdata but setting z does not work. I wondered why this was until I realised exactly the reason. This is the __index method for the transform userdata:

static int TransformGet(lua_State* L)
{
	if (luaL_checkudata(L, 1, "Transform") == NULL)
	{
		luaL_typerror(L, 1, "Transform");
	}
	Transform* trans = (Transform*)lua_touserdata(L, 1);

	const char* key = luaL_checkstring(L, 2);

	if (strcmp(key, "Position") == 0)
	{
		Maths::Vec3f* returnValue;
		returnValue = (Maths::Vec3f*)lua_newuserdata(L, sizeof(Maths::Vec3f)); // Creates a new vector for the return value, and so breaking the reference
		luaL_getmetatable(L, "Vector3");
		lua_setmetatable(L, -2);
		*returnValue = trans->Position;
	}
	else if (strcmp(key, "Rotation") == 0)
	{
		Maths::Vec3f* returnValue;
		returnValue = (Maths::Vec3f*)lua_newuserdata(L, sizeof(Maths::Vec3f));
		luaL_getmetatable(L, "Vector3");
		lua_setmetatable(L, -2);
		*returnValue = trans->Rotation;
	}
	else if (strcmp(key, "Scale") == 0)
	{
		Maths::Vec3f* returnValue;
		returnValue = (Maths::Vec3f*)lua_newuserdata(L, sizeof(Maths::Vec3f));
		luaL_getmetatable(L, "Vector3");
		lua_setmetatable(L, -2);
		*returnValue = trans->Scale;
	}
	return 1;
}

As you can see when I access the Position element in the transform I create a new userdata and push it on the stack as the return value. But this breaks the reference to the original userdata, and so setting it's Z element has no effect on the original, and so it appears the assignment didn't work.

 

The logical answer is to return a reference to the existing data of the position vector. But it doesn't have it's own userdata as it's simply an element of the transform userdata. You can see the transform userdata being created here:

Transform* transform;
transform = (Transform*)lua_newuserdata(L, sizeof(Transform));
luaL_getmetatable(L, "Transform");
lua_setmetatable(L, -2);
*transform = Transform();

I am completely at a loss at what to do here. I somehow need to create a userdata that points to the same block of memory that the position element was kept in. I tried experimenting with lightuserdata as it's only a pointer, but that threw errors when I tried to access members of the lightuserdata, which seem to not exist in Lua's mind.

 

This seems like an issue other Lua devs must have come across so I'd like some help on dealing with it.

 

Thanks.


Edge artifact with basic diffuse shading

02 July 2015 - 08:04 AM

Hello all,

 

I implemented basic diffuse and ambient lighting in a glsl shader which I'm using to draw some cubes. However at a distance there are some strange artifacts on the edge's of the object. It's not aliasing. At least I'm reasonably sure. It's almost like a whole chunk of the edge isn't being lit correctly or something.

 

Here's a picture:

 

sbjxRnO.png

 

It doesn't occur when the lighting is turned off. So it's definitely the lighting that's causing it.

 

Obviously I want this to go away. I'm not quite sure what code needs to be shown so here's the fragment shader for starters:

#version 330

in vec2 UV;
in vec3 Normal0;

out vec4 FragColor;

uniform sampler2D myTextureSampler;

void main() {
	vec3 DirectionalLightColor = vec3(1.0f, 1.0f, 1.0f);
	float AmbientLightIntensity = 0.4f;
	float DirectionalLightIntensity = 1.2f;
	vec3 DirectionalLightDirection = normalize(vec3(1.0f, 1.0f, 1.0f));

	vec4 AmbientColor = vec4(DirectionalLightColor * AmbientLightIntensity, 1.0f);

	float DiffuseFactor = dot(normalize(Normal0), -DirectionalLightDirection);

	vec4 DiffuseColor;

	if (DiffuseFactor > 0) {
		DiffuseColor = vec4(DirectionalLightColor * DirectionalLightIntensity * DiffuseFactor, 1.0f);
	}
	else {
		DiffuseColor = vec4(0, 0, 0, 0);
	}

	//FragColor = (texture(myTextureSampler, UV)) * (AmbientColor + DiffuseColor);
	//FragColor = (texture(myTextureSampler, UV));
	FragColor = vec4(0.5,0.5,0.5,1) * (AmbientColor + DiffuseColor);
}

And here's the vertex shader as well incase it might be the cause of the problem

#version 330

uniform mat4 gMVP;
uniform mat4 gWorld;

layout (location = 0) in vec3 Position;
layout (location = 1) in vec2 TexCoords;
layout (location = 2) in vec3 Normal;

out vec2 UV;
out vec3 Normal0;

void main() {
    gl_Position = gMVP * vec4(Position, 2.0);
    UV = TexCoords;
	Normal0 = (gWorld * vec4(Normal, 0.0)).xyz;
}

I'm not that experienced with OpenGL so I'm not even sure how to go about debugging this. I observed the effect lessens when you get closer to the objects. Don't know if that's relevant. 

Oh here's the code that submits the draw call as well

void DrawCube(State* state, Maths::Vec3f Position, Maths::Vec3f Rotation, Maths::Vec3f Scale)
{
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, cube.VertexPositionsBuffer);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, cube.TexCoordsBuffer);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);

    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, cube.VertexNormalsBuffer);
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cube.ElementBuffer);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, cube.Texture);
    glUniform1i(state->TextureUniformHandle, 0);

    Maths::Mat4f scale = Maths::MakeScale(Scale);
    Maths::Mat4f translate = Maths::MakeTranslate(Position);
    Maths::Mat4f rotate = Maths::MakeRotate(Rotation);

    Maths::Mat4f cameraTranslate = Maths::MakeTranslate(Maths::Vec3f(-state->Camera.Position.X, -state->Camera.Position.Y, -state->Camera.Position.Z));
    Maths::Mat4f cameraRotate = Maths::MakeLookAt(state->Camera.Forward, state->Camera.Up);

    Maths::Mat4f projection = Maths::MakePerspective(800, 450, 0.01, 100, 30);

    Maths::Mat4f Model = translate * rotate * scale;
    Maths::Mat4f MVP = projection * cameraRotate * cameraTranslate * Model;

    glUniformMatrix4fv(state->gMVPHandle, 1, GL_TRUE, &MVP.m[0][0]);
    glUniformMatrix4fv(state->gWorldHandle, 1, GL_TRUE, &Model.m[0][0]);

    glDrawElements(GL_TRIANGLES, cube.NumIndices, GL_UNSIGNED_INT,0);

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

OpenGL View Matrix that rotates the camera

19 April 2015 - 02:28 PM

I've spent the day trying to implement a system in an SDL2 OpenGL app that rotates the actual camera by pitch, yaw and roll.

 

I'm fed up of reading tutorials that use glm::lookat and set the up vector to (0, 1, 0), and forgo the ability to roll the camera, trying to emulate a first person camera.

 

Let me first define what I'm trying to do. I noticed naively that using a glm::rotate matrix as the view matrix just rotates the objects in the scene, and not the camera. I actually want the camera to rotate, so if pitch is 90 degrees, the camera looks down. Or if yaw is set to 90 degrees, the camera looks right, and therefore cannot see the objects. If roll is set to 90 degrees the scene is viewed as rotated sideways.

 

Considering that I'm not afraid of quaternions and I know they remove gimbal lock if used correctly, what is the best way to create a view matrix that rotates the camera itself by specifying pitch, yaw and roll?

 

Thank you for any help!


Object interactions in a multithreaded game

27 November 2013 - 03:16 PM

So I have been doing research into multithreading for no reason other than curiosity and I have noticed something which I'd like to bring up. 

 

The best way to multithread any software, apparently, is data-decomposition. As in instead of putting subsystems on different threads, you break up the processing of one subsystem into multiple jobs to do concurrently, scaling to n number of threads. 

 

This is all fine and dandy, but say if you were to do this to the physics system, my logic would be to break it up so for n threads divide the number of objects by n and give each thread a group of objects to update. Then you would have a situation were conflicts would occur. Say object A collides with object B, but A and B are being updated at the same time on separate threads. Problem.

 

Another example is for updating game logic on gameObjects. What if object A is dependant on the health of object B. But again, they are being updated on different threads.

 

Now I know the simple answer is, minimize interaction and communication between objects, however this is not always going to be good enough, especially in physics, since object interaction is critical to the function of the system.

 

I have not worked on a game were objects never have to talk to each other, so how do you get around this problem when designing a multithreaded game?


Singletons in a component based architecture.

25 November 2013 - 02:10 PM

Hello, 

 

So I wanted to write a game using a component based architecture for the obvious reasons of wanting quick iteration and such, thats not my point tough.

 

What I have thought up is a system were components are implemented in Lua instead of c++, and then Lua can call functions that are implemented in c++. All fine and dandy, however I see a problem.

 

From the c++ point of view most of my code is just going to be a list Lua functions implemented in c++, with no need for inheritance or things such as that.

 

Furthermore, if I just put all these Lua functions in classes, as merely namespaces, I will have code, from the c++ point of view thats just a bunch of singletons, with Lua functions in them.

 

This goes against what I know to be good practice in c++ OOP programming. So my question is, everyone talks about the components and data, but what about the rest of the code, is there a way that all this functionality is normally implemented, as in the functionality for components to use?


PARTNERS