Jump to content

  • Log In with Google      Sign In   
  • Create Account

Jossos

Member Since 19 Dec 2012
Offline Last Active Dec 10 2014 08:08 AM

Posts I've Made

In Topic: 2 strange opengl problems - small window and reverse

25 November 2014 - 09:55 PM

Fixed problem I had posted, but this new one had taken me hours and I found no results on google.

 

I have 2 shaders

tileShader = new SHADER("Shaders/StandardShader.vs", "Shaders/TileShader.fs");
skinShader = new SHADER("Shaders/SkinningShader.vs", "Shaders/ShadingShader.fs");

and they each have 2 textures like so:

uniform sampler2D texture0;
uniform sampler2D texture1;

and then I do this:

glUniform1i(glGetUniformLocation(tileShader->GetProgramID(), "texture0"), 0);
glUniform1i(glGetUniformLocation(tileShader->GetProgramID(), "texture1"), 1);

glUniform1i(glGetUniformLocation(skinShader->GetProgramID(), "texture0"), 0);
glUniform1i(glGetUniformLocation(skinShader->GetProgramID(), "texture1"), 1);

In the shaders they do some stuff with the two textures mixing them together, however one of these shaders will only render ONE texture in place of both, depending on whichever I do the "new SHADER" on first(last works properly, first just has 1 texture, or is just sometimes completely black)

 

And I have no idea what the hell is causing this. I know my binding is fine, as swapping their "new SHADER" lines after each other makes them swap, one working and one not.

 

Any help is greatly appreciated.


In Topic: 2 strange opengl problems - small window and reverse

23 November 2014 - 03:23 AM

 

What does this call look like "pipeline.Ortho(-1, 1, -1, 1, -1, 1);"?

What does "quad.Render();" look like? Im thinking its a problem with the quads vertices or texture coordinates assigned to them.

For the blending if you textures alpha channel is black (0) or doesnt have an alpha channel and defaults to black it might not show.

 

Oh man thanks, I had my quad be 0,0 to 1,1, but it should have been -1,-1 to 1,1. That problem is now fixed. By I still have the issue of the model being back to front and rotating the wrong way.


In Topic: Opengl Spazzing out for no reason

02 November 2014 - 02:50 AM

Sorry everyone I'm retarded.

 

My shader:

void main()
{
	mat4 BoneTransform;
	BoneTransform += gBones[BoneIDs[0]] * Weights[0];
	BoneTransform += gBones[BoneIDs[1]] * Weights[1];
	BoneTransform += gBones[BoneIDs[2]] * Weights[2];
	BoneTransform += gBones[BoneIDs[3]] * Weights[3];

bonetransform is just full of nothing. Changed to:

void main()
{
	mat4 BoneTransform = gBones[BoneIDs[0]] * Weights[0];
	BoneTransform += gBones[BoneIDs[1]] * Weights[1];
	BoneTransform += gBones[BoneIDs[2]] * Weights[2];
	BoneTransform += gBones[BoneIDs[3]] * Weights[3];

All better


In Topic: Opengl Spazzing out for no reason

20 October 2014 - 06:18 PM

Get ready for code overload:

 

 

LOADING

bool MESH::Load(const char* filename)
{
	Clear();

	m_hasTexture = false;
	m_numBones = 0;

	std::vector<VECTOR3f> positions;
	std::vector<VECTOR3f> normals;
	std::vector<VECTOR2f> texCoords;
	std::vector<VertexBoneData> bones;
	std::vector<uint> indices;

	uint numVertices = 0;
	uint numIndices = 0;

	// Use assimp to get data from the file
	Assimp::Importer Importer;
	m_pScene = m_Importer.ReadFile(filename, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs);

	if (!m_pScene)
	{
		printf("Error parsing '%s': '%s'\n", filename, Importer.GetErrorString());
		return false;
	}

	m_globalInverseTransform = m_pScene->mRootNode->mTransformation;
	m_globalInverseTransform.Inverse();

	// Make all vectors the appropriate size for the data
	m_objects.resize(m_pScene->mNumMeshes);

	for (uint i = 0; i < m_objects.size(); i++)
	{
		m_objects[i].numVertices	= m_pScene->mMeshes[i]->mNumVertices;
		m_objects[i].numIndices		= m_pScene->mMeshes[i]->mNumFaces * 3;
		m_objects[i].startVertex	= numVertices;
		m_objects[i].startIndex		= numIndices;

		numVertices += m_objects[i].numVertices;
		numIndices	+= m_objects[i].numIndices;
	}

	positions.reserve(numVertices);
	normals.reserve(numVertices);
	texCoords.reserve(numVertices);
	bones.resize(numVertices);
	indices.reserve(numIndices);

	// Initialize the meshes
	int fuck = m_objects.size();

	for (uint i = 0; i < m_objects.size(); i++)
	{
		const aiMesh* paiMesh = m_pScene->mMeshes[i];
		const aiVector3D Zero3D(0.0f, 0.0f, 0.0f);

		// Populate Vertex Attributes
		for (uint j = 0; j < paiMesh->mNumVertices; j++)
		{
			const aiVector3D* aiTexCoord	= paiMesh->HasTextureCoords(0) ? &(paiMesh->mTextureCoords[0][j]) : &Zero3D;

			positions.push_back(VECTOR3f(paiMesh->mVertices[j].x, paiMesh->mVertices[j].y, paiMesh->mVertices[j].z));
			normals.push_back(VECTOR3f(paiMesh->mNormals[j].x, paiMesh->mNormals[j].y, paiMesh->mNormals[j].z));
			texCoords.push_back(VECTOR2f(aiTexCoord->x, aiTexCoord->y));
		}

		// Populate Indices
		for (uint j = 0; j < paiMesh->mNumFaces; j++)
		{
			const aiFace& face = paiMesh->mFaces[j];
			assert(face.mNumIndices == 3);

			indices.push_back(face.mIndices[0]);
			indices.push_back(face.mIndices[1]);
			indices.push_back(face.mIndices[2]);
		}

		// Load Bones for current Mesh
		for (uint j = 0; j < paiMesh->mNumBones; j++)
		{
			uint boneIndex = 0;
			std::string boneName(paiMesh->mBones[j]->mName.data);

			if (m_boneMapping.find(boneName) == m_boneMapping.end())
			{
				boneIndex = m_numBones;
				m_numBones++;
				m_boneInfo.push_back(BoneInfo());
				m_boneInfo[boneIndex].BoneOffset = paiMesh->mBones[j]->mOffsetMatrix;
				m_boneMapping[boneName] = boneIndex;
			}
			else
				boneIndex = m_boneMapping[boneName];

			m_boneMapping[boneName] = boneIndex;
			m_boneInfo[boneIndex].BoneOffset = paiMesh->mBones[j]->mOffsetMatrix;

			for (uint k = 0; k < paiMesh->mBones[j]->mNumWeights; k++)
			{
				uint VertexID = m_objects[i].startVertex + paiMesh->mBones[j]->mWeights[k].mVertexId;
				float weight = paiMesh->mBones[j]->mWeights[k].mWeight;
				bones[VertexID].AddBoneData(boneIndex, weight);
			}
		}
	}

	// Load the material (only using one for now)
	// We assume the texture file is in the same directory as the model file
	const aiMaterial* pMaterial = m_pScene->mMaterials[0];
	aiString path;
	if (pMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS)
	{
		std::string::size_type startIndex = std::string(path.C_Str()).find_last_of("\\");
		if (startIndex == std::string::npos)
			startIndex = std::string(path.C_Str()).find_last_of("/");

		std::string texFilename;

		if (startIndex != std::string::npos)
		{
			texFilename = std::string(path.C_Str()).substr(startIndex + 1);
		}
		else
			texFilename = path.C_Str();

		// get texture path, and make it lower case		
		std::string texPath = std::string(filename).substr(0, std::string(filename).find_last_of("/")) + "/";
		
		for (uint i = 0; i < texFilename.length(); i++)
			texPath += texFilename[i];

		// Load Texture
		if (!m_texture.Load(texPath.c_str()))
		{
			printf("Failed to load texture: \"%s\"", texPath.c_str());
		}
		else
			m_hasTexture = true;
	}

	const aiNodeAnim* pNodeAnim = NULL;
	uint i = 0;

	while (!pNodeAnim)
	{
		pNodeAnim = FindNodeAnim(m_pScene->mAnimations[0], m_pScene->mRootNode->mChildren[i]->mName.data);
		i++;

		if (i > 500)	// Too many loops
			continue;
	}
		//FindNodeAnim(pAnimation, nodeName);
		//m_pScene->mAnimations[0]->mChannels->

	if (pNodeAnim)
	{
		m_animInfo.numKeyframes = pNodeAnim->mNumPositionKeys;
		m_animInfo.frameDuration = m_pScene->mAnimations[0]->mDuration / (pNodeAnim->mNumPositionKeys);
	}

	// Negate the last frame, as it is the same as the first
	m_animInfo.MaxAnimTime = m_animInfo.frameDuration * (m_animInfo.numKeyframes - 1);

	// Initialize buffers with the data
	InitBuffers(positions, normals, texCoords, indices, bones);

	return true;
}
bool MESH::InitBuffers(const std::vector<VECTOR3f>& positions,
					   const std::vector<VECTOR3f>& normals,
					   const std::vector<VECTOR2f>& texCoords,
					   const std::vector<uint>& indices,
					   const std::vector<VertexBoneData>& bones)
{
	// Create the VAO
	glGenVertexArrays(1, &m_VAO);
	glBindVertexArray(m_VAO);

	// Create the buffers for the vertices attributes
	glGenBuffers(ArraySizeInElements(m_buffers), m_buffers);



	// Generate and populate the buffers with vertex attributes and the indices
	glBindBuffer(GL_ARRAY_BUFFER, m_buffers[POS_VB]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(positions[0]) * positions.size(), &positions[0], GL_STATIC_DRAW);
	glEnableVertexAttribArray(POSITION_LOCATION);
	glVertexAttribPointer(POSITION_LOCATION, 3, GL_FLOAT, GL_FALSE, 0, 0);

	glBindBuffer(GL_ARRAY_BUFFER, m_buffers[TEXCOORD_VB]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(texCoords[0]) * texCoords.size(), &texCoords[0], GL_STATIC_DRAW);
	glEnableVertexAttribArray(TEX_COORD_LOCATION);
	glVertexAttribPointer(TEX_COORD_LOCATION, 2, GL_FLOAT, GL_FALSE, 0, 0);

	glBindBuffer(GL_ARRAY_BUFFER, m_buffers[NORMAL_VB]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(normals[0]) * normals.size(), &normals[0], GL_STATIC_DRAW);
	glEnableVertexAttribArray(NORMAL_LOCATION);
	glVertexAttribPointer(NORMAL_LOCATION, 3, GL_FLOAT, GL_FALSE, 0, 0);

	if (m_numBones > 0)
	{
		glBindBuffer(GL_ARRAY_BUFFER, m_buffers[BONE_VB]);
		glBufferData(GL_ARRAY_BUFFER, sizeof(bones[0]) * bones.size(), &bones[0], GL_STATIC_DRAW);
		glEnableVertexAttribArray(BONE_ID_LOCATION);
		glVertexAttribIPointer(BONE_ID_LOCATION, 4, GL_INT, sizeof(VertexBoneData), (const GLvoid*)0);
		glEnableVertexAttribArray(BONE_WEIGHT_LOCATION);
		glVertexAttribPointer(BONE_WEIGHT_LOCATION, 4, GL_FLOAT, GL_FALSE, sizeof(VertexBoneData), (const GLvoid*)16);
	}

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffers[INDEX_BUFFER]);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), &indices[0], GL_STATIC_DRAW);
	


	glBindVertexArray(0);

	return true;
}
void MESH::Clear()
{
	if (m_buffers[0] != 0)
		glDeleteBuffers(ArraySizeInElements(m_buffers), m_buffers);

	if (m_VAO != 0)
	{
		glDeleteVertexArrays(1, &m_VAO);
		m_VAO = 0;
	}

	if (m_objects.size() > 0)
		m_objects.empty();
}

DRAWING

void GAME::RenderModels()
{
	// Draw Geometry / Scene Objects
	m_pipeline.MatrixMode(MODEL_MATRIX);
	m_pipeline.PushMatrix();

	stdShader->Bind();

		m_pipeline.CalcMatrices(stdShader->GetProgramID());
		plane.Render();
		
	stdShader->Unbind();
	skinShader->Bind();

		m_pipeline.RotateY(angle);
		m_pipeline.Scale(0.10f);
		//m_pipeline.Translate(0.0f, 0.0f, -6.0f);
		//m_pipeline.Translate(0.0f, 1.0f, 0.0f);

		std::vector<MATRIX4f> transforms;

		float time = m_timer.m_secsPassedSinceStart / ninja.GetAnimTime() * 0.5f;

		ninja.BoneTransform(time, transforms);

		for (uint i = 0; i < transforms.size(); i++)
			glUniformMatrix4fv(m_boneLocations[i], 1, GL_TRUE, (const GLfloat*)transforms[i].m_matrix);

		m_pipeline.Translate(0.0f, 0.0f, 1.0f);
		m_pipeline.CalcMatrices(skinShader->GetProgramID());
		ninja.Render();

	skinShader->Unbind();

	m_pipeline.PopMatrix();
}
void MESH::Render()
{
	glBindVertexArray(m_VAO);

	if (m_hasTexture)
		m_texture.Bind(GL_TEXTURE0);

	for (uint i = 0; i < m_objects.size(); i++)
	{
		glDrawElementsBaseVertex(GL_TRIANGLES,
								 m_objects[i].numIndices,
								 GL_UNSIGNED_INT,
								 (void*)(sizeof(uint) * m_objects[i].startIndex),
								 m_objects[i].startVertex);
	}

	if (m_hasTexture)
		m_texture.Unbind(GL_TEXTURE0);

	glBindVertexArray(0);
}
// This function simply has the bones be where they're supposed to be depending on the time in seconds passed in. At the moment its used as a loop
void MESH::BoneTransform(float& TimeInSeconds, std::vector<MATRIX4f>& transforms)
{
	MATRIX4f identity;
	identity.LoadIdentity();

	float ticksPerSecond = (float)(m_pScene->mAnimations[0]->mTicksPerSecond != 0 ? m_pScene->mAnimations[0]->mTicksPerSecond : 25.0f);
	float TimeInTicks = TimeInSeconds * ticksPerSecond;
    //float AnimationTime = fmod(TimeInTicks, (float)m_pScene->mAnimations[0]->mDuration);
	float AnimationTime = fmod(TimeInTicks, m_animInfo.MaxAnimTime);
	

	ReadNodeHeirarchy(AnimationTime, m_pScene->mRootNode, identity);

	transforms.resize(m_numBones);

	for (uint i = 0; i < m_numBones; i++)
		transforms[i] = m_boneInfo[i].FinalTransformation;
}
void MESH::ReadNodeHeirarchy(float AnimationTime, const aiNode* pNode, const MATRIX4f& ParentTransform)
{
	std::string nodeName(pNode->mName.data);

	const aiAnimation* pAnimation = m_pScene->mAnimations[0];

	MATRIX4f NodeTransformation(pNode->mTransformation);

	const aiNodeAnim* pNodeAnim = FindNodeAnim(pAnimation, nodeName);

	if (pNodeAnim)
	{
		// Interpolate scaling and generate scaling transformation matrix
        aiVector3D Scaling;
        CalcInterpolatedScaling(Scaling, AnimationTime, pNodeAnim);
        MATRIX4f ScalingM;
        ScalingM.InitScale(Scaling.x, Scaling.y, Scaling.z);
        
        // Interpolate rotation and generate rotation transformation matrix
        aiQuaternion RotationQ;
        CalcInterpolatedRotation(RotationQ, AnimationTime, pNodeAnim);        
        MATRIX4f RotationM = MATRIX4f(RotationQ.GetMatrix());

        // Interpolate translation and generate translation transformation matrix
        aiVector3D Translation;
        CalcInterpolatedPosition(Translation, AnimationTime, pNodeAnim);
        MATRIX4f TranslationM;
        TranslationM.InitTranslate(Translation.x, Translation.y, Translation.z);
        
        // Combine the above transformations
        NodeTransformation = TranslationM * RotationM * ScalingM;
	}

	MATRIX4f GlobalTransformation = ParentTransform * NodeTransformation;

	if (m_boneMapping.find(nodeName) != m_boneMapping.end())
	{
		uint boneIndex = m_boneMapping[nodeName];
		m_boneInfo[boneIndex].FinalTransformation = m_globalInverseTransform * GlobalTransformation * m_boneInfo[boneIndex].BoneOffset;;
	}

	for (uint i = 0; i < pNode->mNumChildren; i++)
		ReadNodeHeirarchy(AnimationTime, pNode->mChildren[i], GlobalTransformation);
}

Now this is where I suspect the problem may lie, however I don't really understand it:

void MESH::CalcInterpolatedPosition(aiVector3D& Out, float AnimationTime, const aiNodeAnim* pNodeAnim)
{
    if (pNodeAnim->mNumPositionKeys == 1) {
        Out = pNodeAnim->mPositionKeys[0].mValue;
        return;
    }
            
    uint PositionIndex = FindPosition(AnimationTime, pNodeAnim);
    uint NextPositionIndex = (PositionIndex + 1);
    assert(NextPositionIndex < pNodeAnim->mNumPositionKeys);
    float DeltaTime = (float)(pNodeAnim->mPositionKeys[NextPositionIndex].mTime - pNodeAnim->mPositionKeys[PositionIndex].mTime);
    float Factor = (AnimationTime - (float)pNodeAnim->mPositionKeys[PositionIndex].mTime) / DeltaTime;
	
	//assert(Factor >= 0.0f && Factor <= 1.0f);
    const aiVector3D& Start = pNodeAnim->mPositionKeys[PositionIndex].mValue;
    const aiVector3D& End = pNodeAnim->mPositionKeys[NextPositionIndex].mValue;
    aiVector3D Delta = End - Start;
    Out = Start + Factor * Delta;
}
void MESH::CalcInterpolatedRotation(aiQuaternion& Out, float AnimationTime, const aiNodeAnim* pNodeAnim)
{
	// we need at least two values to interpolate...
    if (pNodeAnim->mNumRotationKeys == 1) {
        Out = pNodeAnim->mRotationKeys[0].mValue;
        return;
    }
    
    uint RotationIndex = FindRotation(AnimationTime, pNodeAnim);
    uint NextRotationIndex = (RotationIndex + 1);
    assert(NextRotationIndex < pNodeAnim->mNumRotationKeys);
    float DeltaTime = (float)(pNodeAnim->mRotationKeys[NextRotationIndex].mTime - pNodeAnim->mRotationKeys[RotationIndex].mTime);
    float Factor = (AnimationTime - (float)pNodeAnim->mRotationKeys[RotationIndex].mTime) / DeltaTime;
    
	//assert(Factor >= 0.0f && Factor <= 1.0f);
    const aiQuaternion& StartRotationQ = pNodeAnim->mRotationKeys[RotationIndex].mValue;
    const aiQuaternion& EndRotationQ   = pNodeAnim->mRotationKeys[NextRotationIndex].mValue;    
    aiQuaternion::Interpolate(Out, StartRotationQ, EndRotationQ, Factor);
    Out = Out.Normalize();
}
void MESH::CalcInterpolatedScaling(aiVector3D& Out, float AnimationTime, const aiNodeAnim* pNodeAnim)
{
    if (pNodeAnim->mNumScalingKeys == 1) {
        Out = pNodeAnim->mScalingKeys[0].mValue;
        return;
    }

    uint ScalingIndex = FindScaling(AnimationTime, pNodeAnim);
    uint NextScalingIndex = (ScalingIndex + 1);
    assert(NextScalingIndex < pNodeAnim->mNumScalingKeys);
    float DeltaTime = (float)(pNodeAnim->mScalingKeys[NextScalingIndex].mTime - pNodeAnim->mScalingKeys[ScalingIndex].mTime);
    float Factor = (AnimationTime - (float)pNodeAnim->mScalingKeys[ScalingIndex].mTime) / DeltaTime;

	//assert(Factor >= 0.0f && Factor <= 1.0f);
    const aiVector3D& Start = pNodeAnim->mScalingKeys[ScalingIndex].mValue;
    const aiVector3D& End   = pNodeAnim->mScalingKeys[NextScalingIndex].mValue;
    aiVector3D Delta = End - Start;
    Out = Start + Factor * Delta;
}

You will notice i commented out the assertion because i do actually get values outside 0 and 1. I must confess I don't really understand this function.

 

Any help is greatly appreciated!


In Topic: Opengl Spazzing out for no reason

20 October 2014 - 07:26 AM

30nag68.jpg

 

I'll also add, as I said above, this is occuring in projects that worked perfectly fine before, but are now all spazzing out in the same way without any new changes.


PARTNERS