Jump to content

  • Log In with Google      Sign In   
  • Create Account

mynameisnafe

Member Since 04 Sep 2012
Offline Last Active Aug 17 2014 09:15 AM

Topics I've Started

glm/opengl orbital camera C++

02 August 2014 - 11:46 AM

Hi there,

 

I have a gl project with a first person camera that uses glm to do it's math.

My question is thus and I'm sorry for it's quite poor construction: 

Do I need to use/do glm::quat things or do I need rotX, rotY, rotZ, for some code where the camera spins around on a sphere centred on the model?

So, the end goal is that moving the mouse makes it look like the model is spinning, when actually the camera is spinning?

And how would I do that?

For example, how different would this class declaration be?

I'd like to throw a 'orbit-cam' in there, then extract a base class, etc.

class GLCamera
{
protected:


float   _mx, _my;
float   m_frameTime, // how much time has passed
m_moveSpeed, // how many units to move per second
m_mouseSpeed; // how many degrees to rotate per second of


glm::vec3 m_real_up;
glm::vec3 m_origin;


float m_horizontalAngle, m_verticalAngle, m_initFoV;


glm::vec3 position;


glm::vec3 m_direction;
glm::vec3 m_right;
glm::vec3 m_up;


glm::mat4 m_viewMatrix;

C++ Multi-Byte - prepare string of extensions for OpenFileDialog

01 July 2014 - 01:04 PM

HI all,

 

I'm having some trouble figuring out how to do this one.

Assimp gives me a string, containing all the file extensions it can handle.

I found some code to tokenize strings on SO and wrapped it in a function.

The format of the string that is used to initialise the accepted extensions list for the OPENFILENAME structure is as follows:
 

L"All\0*.*\0Text\*.txt\0"

And so I'm trying to recreate that programatically. Which is a nightmare, as I'm trying to stick '\0' in the middle of a string.

// Get a vector of extensions supported by Assimp ( assimp exts string, tokenise by ';' )
std::vector<std::string> exts = Scatterbrain::Split(extsAccepted.c_str(), ';');
	
//create a string with a bunch of '\0' s in it, if possible
std::string extsList="";
for(size_t i = 0; i < exts.size(); i++)
	extsList.append(exts[i] + '\0');
	
// contains the first extension.
CString pwszExts(extsList.c_str());

// Initialize OPENFILENAME
ZeroMemory(&ofn, sizeof(ofn));

ofn.lpstrFilter = (LPCWSTR)pwszExts; // This one
...

// Display the Open dialog box. 
if( GetOpenFileName(&ofn) == TRUE ) 
{
...

Okay - I see one bug already: the dialog is going to say 'extension_a extension_b', instead of 'ext_name_a ext_a', but I'm happy to add blank spaces for names.

how is the generation of a string 

L"Hello\0World\0How\0Are\0You\0'

 done?

Thanks in advance

 


Assimp and Common Dialog Box - Strings - C++

28 June 2014 - 07:55 PM

Hi all,

 

I've been playing with Assimp: I've used it before, hardcoding file paths. However now I'm getting a complete file path from one of these Common Dialog Box things with

 GetOpenFileName()

http://msdn.microsoft.com/en-gb/library/windows/desktop/ms646829(v=vs.85).aspx#open_file

 

I'm then jumping through some (CString-shaped) hoops to format the string for the call below:


Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(filename, aiProcessPreset_TargetRealtime_Fast);
//aiProcessPreset_TargetRealtime_Fast has the configs we'll need// nickthecoder.com

 

The problem is that scene is NULL. I'm guessing this is because of the flilepath and my incorrect formatting.

- what steps do I need to go through to ensure the filepath is good for assimp?

Hope to hear from you soon :)


Simple Question BYTE->float C++

27 February 2014 - 04:18 PM

I have

unsigned char RGBA =[] { 255, 255, 255, 255 };

struct vector4 { float r, float g, float b, float a; } colour;

That's probably not valid C++, still

 

How do I set colour?

.

 


I feel like a Noob C++ GL 4.1 and GLSL 3.3 help please!

24 February 2014 - 04:08 PM

Please help! I am trying to render a textured quad.
For the life of me, it retains black with a textured phong shader. In fact, when I use a phong shader, it stays black, even though its the same phong shader that renders all the models around said dastardly quad.

I'm hoping the code is quite explanatory so I'm just gonna walk through it and someone with a sharper eye than I can hunt for glory. Beware, there is a LOT of code - just looked and I feel bad.. however I do have to explain a couple of classes, FreeImage, and how it all works. I have quite a big project now.. it just doesn't yet do a lot because I don't have any textures. Just some 30-second -to-load .objs that are blue, and almost shiny.

 

I digress, the 'textured' quad gets made with the line below, which calls CreateQuad inline. It's gonna have some picture of some wood or something on it. It sits at 5,5,0 world space, and is 5x5 units in area.

m_HUD->Create( *ShapeFactory::CreateQuad( 5, 5, 5, 5, true),
	         "../Shaders/basic_phong.vs", "../Shaders/basic_phong.fs" );

Heres CreateQuad. (I post this so you can spot an error in it, but it ~should~ be pretty standard. It creates a quad. I hope.)

GeometryData* // Draw with GL_QUADS, centred on x, y
	ShapeFactory::CreateQuad(int x, int y, int width, int height, bool textured)
{
	GeometryData* shape = new GeometryData();
	shape->SetTopology(7); // ..->SetTopology(GL_QUADS);
	
	float x0, x1, y0, y1;
	
	x0 = x + (width/2);	x1 = x - (width/2);
	y0 = y + (height/2);	y1 = y - (height/2);

	shape->numVertices = 4;
	shape->m_Vertices = (Cream::Vertex3D*) calloc (4, sizeof(Cream::Vertex3D) );
	shape->m_Vertices[0] = Vertex3D( x0, y1 , 0.0f );
	shape->m_Vertices[1] = Vertex3D( x1, y1 , 0.0f );
	shape->m_Vertices[2] = Vertex3D( x1, y0 , 0.0f );
	shape->m_Vertices[3] = Vertex3D( x0, y0 , 0.0f );

	shape->numNormals = 4;	
	shape->m_Normals = (Cream::Vertex3D*) calloc (4, sizeof(Cream::Vertex3D) );
	shape->m_Normals[0] = Vertex3D( 0.0f, 0.0f , 1.0f );
	shape->m_Normals[1] = Vertex3D( 0.0f, 0.0f , 1.0f );
	shape->m_Normals[2] = Vertex3D( 0.0f, 0.0f , 1.0f );
	shape->m_Normals[3] = Vertex3D( 0.0f, 0.0f , 1.0f );

	if( textured )
	{
		shape->numUVs = 4;
		shape->m_TexCoords = (Cream::Vertex2D*) calloc (4, sizeof(Cream::Vertex2D) );
		shape->m_TexCoords[0] = Vertex2D(0.0f, 1.0f);
		shape->m_TexCoords[1] = Vertex2D(1.0f, 1.0f);
		shape->m_TexCoords[2] = Vertex2D(1.0f, 0.0f);
		shape->m_TexCoords[3] = Vertex2D(0.0f, 0.0f);
	}

	shape->numIndices = 0;

	return shape;	
}

m_HUD is of type GLMesh. GLMesh::Create in short creates a VAO from that GeometryData, a Shader from those filenames, and holds a material - which contains uniforms I may want to set for the model; colour, gl texture id, texture name, etc. It has the Render method.

So, GLMesh::PreRender sets uniforms by talking to its GLShader, and it works like this: If the material says I'm textured, if it contains a texture ID for a diffuse map -- then I have a KdID, I set it. It also sets camera matrices. bOk is bOk, whether I use a texture or no, so the "1" is getting sent to map_kd in the shader.

if(material->isTextured)
{
	if( material->KdID != 0 )
	{	// both barrels and still nothing!
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, material->KdID );

		bOk = bOk && m_Shader->SetUniformInt( 1, "map_kd" );
	}
	if( material->KaID != 0 )
	{
		//glActiveTexture(GL_TEXTURE2);
		glBindTexture(GL_TEXTURE_2D, material->KaID );
	
        	bOk = bOk && m_Shader->SetUniformInt( 2, "map_ka" );		
	}
        ......
        else
        {       // always fires for non-textured shader, always works*
                bOk = bOk && m_Shader->SetUniformVec4(glm::vec4(material->Kd.GLM(), 1.0), "m_Kd");
        }

So that explains how the quad gets made and how it gets rendered, using texture unit or colour, the other data that it requires etc to exist in GL land. I'm pretty sure everything's good except setting the texture / sampler (I've said little of textures, I know).

 

I got FreeImage. It gives me bits, and I copy them, and keep them locally, then I let GL copy them and GL gives me a texture unit.

 

It gets convoluted though - as I said, I keep the texture locally and don't free them bits after I give them to OpenGL, because I want to play later - so I have a class for a texture, that lets me access those bits from FreeImage with GetPixel, SetPixel, Fill, etc, as if it were a 2D array. This I feel would be a handy thing to make heightmaps with, among other things.

So FreeImage gives me bits, FreeImage is disguised as ImageFactory.

 

The bits go to a GLBitmap Constructor ( .. bmp->GetPixel(x, y) ), along with width, height, and whether the bits need shuffling or not when they get copied.

 

The GLBitmap goes to a GLTexture, which takes the width and height and the bits and does the OpenGL stuff in GLTexture::Load. 


Cream::GLTexture Cream::LoadTexture(std::string path)
{
ImageFactory* factory = ImageFactory::Create();
 
unsigned int width(0), height(0);
bool bShuffle(false);
 
BYTE* bits = factory->Load( path, width, height, bShuffle );
 
GLBitmap* bitmap = new GLBitmap( width, height, bShuffle, bits );
 
GLTexture texture(GL_TEXTURE_2D, GL_RGBA);
 
texture.SetParam(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
texture.SetParam(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
texture.SetParam(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
texture.SetParam(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 
texture.Load( bitmap );
 
return texture;
}

Okay, so here's the constructor for GLBitmap - a Pixel is 4 bytes, a BYTE is an unsigned char. You knew that. So we cast the bits to Pixels and we know we have w * h of them. This could be a place where things have gone wrong though.

GLBitmap(int w, int h, bool bShuffle, BYTE* bits)
{
	width = w;
	height = h;
	Pixel* src = (Pixel*)bits;

	pixels = new Pixel[w*h];

	for(int i = 0; i < w; ++i)
	{
		for(int j = 0 ; j < h; ++j)
		{			
			const Pixel& p = src[(i * h) + j];
			pixels[(i * h) + j] = (bShuffle) ? Pixel(p.B, p.G, p.R, p.A) : p ;
		}
	}
}

And finally our wrapper for an int, GLTexture, here's the Load method, that makes the actual OpenGL calls to generate a texture ID and set the bits to it.

bool GLTexture::Load( GLBitmap* bitmap )
{
	glGenTextures( 1, &m_GLID );
	glBindTexture( target, m_GLID );

	glTexImage2D( target, 0, GL_RGBA, bitmap->Width(), bitmap->Height(), 
                              0, GL_BGRA, GL_UNSIGNED_BYTE, bitmap->Data() );

	for( auto i = params.begin(); i != params.end(); ++i )
	        glTexParameteri( target, i->first, i->second );
 
	return (m_GLID!=0);
}

And so, that explains, in SetMaterial, the workings behind Cream::LoadTexture()

if(mat->isTextured)
{
	material->isTextured = true;

	if(mat->mapKd.size() != 0)	// if there is a filename
	{
		if(mat->KdID != 0)		//if there is a gl/sl tex unit id
			material->KdID = mat->KdID;	//grab it
		else
		{
			m_Textures[0] = Cream::LoadTexture( mat->mapKd ); // else load it
			material->KdID = m_Textures[0].ID();
		}
		material->mapKd = mat->mapKd;
	}
....

So where's my error.. Well I suspect a couple of things. I have a debug callback set, would it inform me of anything obvious?

- the glActiveTexture(GLTEXTURE0+n) calls - they're wrong - the wrong place, too often, wrong texture unit ?
- not sending the right value through to the sampler in the shader*, and no map is being sampled.. linked to above?
- the bits were mangled or the pointer lost by the time OpenGL gets to them in GLTexture::Load

As I say, the coloured phong shader and the textured phong shader are identical except for swapping a vec4 uniform for a sampler and a vec2 attribute, and getting the colour by sampling the texture.

Everything renders fine except the textured-not-coloured stuff.

Please find my error(s), I'll be around to let you know how much you helped! It was a long post.. apologies! A lot of code..

Thank you so, so much in advance! There's a lot I want to do with textures that I can't yet!

In fact, here's a screenshot of a mildly shiny blue cube, a white floor-grid, and a square black hole. I kid, it's that quad.

 

 


PARTNERS