Ok I drew a simple maze and what I am doing for collision to determine if you can move is use glReadPixels which I offset by the width of the square starting at the coordinates of the player which is passed to the function.

Here is the function should someone wish to help me out here.

GLfloat pixel[3];
bool CheckCollision(string Dir, float posX, float posY, float offset)
{
	
	if (Dir == "Left")
	{
		glReadPixels((int)(posX - (offset * 2)), (int)(posY + offset), 2, 2, GL_RGB, GL_BYTE, &pixel);
		if (pixel[0] == 255)
		{
			if (pixel[1] == 255)
			{
				if (pixel[2] == 255)
				{
					return false;
				} else {
					return true;
				}
			} else {
				return true;
			}
		} else {
			return true;
		}
	} else if (Dir == "Right")
	{
		glReadPixels((int)(posX + (offset * 2)), (int)(posY + offset), 2, 2, GL_RGB, GL_BYTE, &pixel);
		if (pixel[0] == 255)
		{
			if (pixel[1] == 255)
			{
				if (pixel[2] == 255)
				{
					return false;
				} else {
					return true;
				}
			} else {
				return true;
			}
		} else {
			return true;
		}
	} else if (Dir == "Up")
	{
		glReadPixels((int)(posX + offset), (int)(posY + (offset * 2)), 2, 2, GL_RGB, GL_BYTE, &pixel);
		if (pixel[0] == 255)
		{
			if (pixel[1] == 255)
			{
				if (pixel[2] == 255)
				{
					return false;
				} else {
					return true;
				}
			} else {
				return true;
			}
		} else {
			return true;
		}
	} else if (Dir == "Down")
	{
		glReadPixels((int)(posX + offset), (int)(posY - (offset * 2)), 2, 2, GL_RGB, GL_BYTE, &pixel);
		if (pixel[0] == 255)
		{
			if (pixel[1] == 255)
			{
				if (pixel[2] == 255)
				{
					return false;
				} else {
					return true;
				}
			} else {
				return true;
			}
		} else {
			return true;
		}
	}
}

As you can tell I want the glReadPixels result to store to the variable pixels and be whatever format it requires to test the value for color. Walls are white so im testing for a white pixel as to that means they cant move that direction.

Recommended Answers

All 8 Replies

If you read this doc, you will see that the width and height should be 1 if you want to read a single pixel. Second, the type parameter (which you have set to GL_BYTE) has to match the type of the pixel pointer which is GLfloat. So, that parameter should most probably be GL_FLOAT. Third, your variable pixel is an array, that means that "pixel" (without & or [0]) is a pointer to a GLfloat. So, you should omit the & sign in your code. Finally, if pixel is of type GLfloat, then the value of "white" is not 255 but 1.0. You could also just make your array "pixel" of type GLbyte (with the type parameter as GL_BYTE), which would give you 255 for full color (i.e. white).

As far as I'm concerned, your code has a much more serious issue... the following:

if (pixel[0] == 255)
		{
			if (pixel[1] == 255)
			{
				if (pixel[2] == 255)
				{
					return false;
				} else {
					return true;
				}
			} else {
				return true;
			}
		} else {
			return true;
		}

can be written as:

return pixel[0]!=255 || pixel[1]!=255 || pixel[2]!=255;

or if you prefer:

return !(pixel[0]==255 && pixel[1]==255 && pixel[2]==255);

If you read this doc, you will see that the width and height should be 1 if you want to read a single pixel. Second, the type parameter (which you have set to GL_BYTE) has to match the type of the pixel pointer which is GLfloat. So, that parameter should most probably be GL_FLOAT. Third, your variable pixel is an array, that means that "pixel" (without & or [0]) is a pointer to a GLfloat. So, you should omit the & sign in your code. Finally, if pixel is of type GLfloat, then the value of "white" is not 255 but 1.0. You could also just make your array "pixel" of type GLbyte (with the type parameter as GL_BYTE), which would give you 255 for full color (i.e. white).

The problem is no matter the format I use the only thing pixel has is 0.00000

What do I have to do to get it to hold a value?

Make sure that your glPixelTransfer parameters are properly set.

The glReadPixels reads the pixels from the frame buffer. If you are using double-buffering, make sure that there is something rendered on the frame buffer before reading from it.. and make sure it is the right one. For instance, if you render everything to the scene, and then you call glSwapBuffers, it is likely that after that point, trying to read pixels from the frame buffer will be useless because the frame buffer with all the rendered objects will have been swapped already.

I'm not sure how it works, I have never used this function. But I remember that I tried but never succeeded. Good luck.

Lemme take a wild guess I hope is wrong....

glReadPixels uses the pixels of the form. For example if its a form of window size 800x640 that is the limit? If so thats the reason it returns nothing because im not using pixels for opengl so I will likely have to rewrite my drawing to better suit glReadPixels.

If I am wrong please say so >.<

>>glReadPixels uses the pixels of the form.

Wait a minute... You cannot use glReadPixels to read from anything other than an OpenGL frame buffer. You must have created a Rendering Context (GL_RC) and be rendering all your stuff with OpenGL commands. If you are trying to read off a "form" as in a form from a GUI tool like Qt, MFC, or WinForm, then that will never work. You have to have a OpenGL window (an OpenGL rendering context (GL_RC) linked to a form's device context (H_DC), with everything rendered on an OpenGL viewport).

If you are using a GUI tool of some sort to display your image, then that GUI tool must have a function to read the pixels. That will probably be much easier to use.

I did here is my graphics code.

Be Ready for a large chunk of code:

// Draw frame
void DrawAppGraphics(float x, float y, float z, float offset, int color,  float cx, float cy, string Row1, string Row2, string Row3, string Row4, string Row5, string Row6, string Row7, string Row8)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Set location in front of camera
    glLoadIdentity();
    glTranslated(cx, cy, -20); // Camera Position

	glBegin(GL_QUADS);
	glColor3d(1, color, 0);
	glVertex3d(x - offset, y + offset, z);
	glVertex3d(x + offset, y + offset, z);
	glVertex3d(x + offset, y - offset, z);
	glVertex3d(x - offset, y - offset, z);
	glEnd();

	int _column = 0;

	//Row1
	for (int cc = -7; cc < 9; cc += 2)
	{
		if(Row1[_column] == 'W')
		{
			glBegin(GL_QUADS);
			glColor3d(1, 1, 1);
			glVertex3d(cc - offset, 6 + offset, 0);
			glVertex3d(cc + offset, 6 + offset, 0);
			glVertex3d(cc + offset, 6 - offset, 0);
			glVertex3d(cc - offset, 6 - offset, 0);
			glEnd();
		}
		_column++;
	}
	_column = 0;

	//Row2
	for (int cc = -7; cc < 9; cc += 2)
	{
		if(Row2[_column] == 'W')
		{
			glBegin(GL_QUADS);
			glColor3d(1, 1, 1);
			glVertex3d(cc - offset, 4 + offset, 0);
			glVertex3d(cc + offset, 4 + offset, 0);
			glVertex3d(cc + offset, 4 - offset, 0);
			glVertex3d(cc - offset, 4 - offset, 0);
			glEnd();
		}
		_column++;
	}
	_column = 0;

	//Row3
	for (int cc = -7; cc < 9; cc += 2)
	{
		if(Row3[_column] == 'W')
		{
			glBegin(GL_QUADS);
			glColor3d(1, 1, 1);
			glVertex3d(cc - offset, 2 + offset, 0);
			glVertex3d(cc + offset, 2 + offset, 0);
			glVertex3d(cc + offset, 2 - offset, 0);
			glVertex3d(cc - offset, 2 - offset, 0);
			glEnd();
		}
		_column++;
	}
	_column = 0;

	//Row4
	for (int cc = -7; cc < 9; cc += 2)
	{
		if(Row4[_column] == 'W')
		{
			glBegin(GL_QUADS);
			glColor3d(1, 1, 1);
			glVertex3d(cc - offset, 0 + offset, 0);
			glVertex3d(cc + offset, 0 + offset, 0);
			glVertex3d(cc + offset, 0 - offset, 0);
			glVertex3d(cc - offset, 0 - offset, 0);
			glEnd();
		}
		_column++;
	}
	_column = 0;

	//Row5
	for (int cc = -7; cc < 9; cc += 2)
	{
		if(Row5[_column] == 'W')
		{
			glBegin(GL_QUADS);
			glColor3d(1, 1, 1);
			glVertex3d(cc - offset, -2 + offset, 0);
			glVertex3d(cc + offset, -2 + offset, 0);
			glVertex3d(cc + offset, -2 - offset, 0);
			glVertex3d(cc - offset, -2 - offset, 0);
			glEnd();
		}
		_column++;
	}
	_column = 0;

	//Row6
	for (int cc = -7; cc < 9; cc += 2)
	{
		if(Row6[_column] == 'W')
		{
			glBegin(GL_QUADS);
			glColor3d(1, 1, 1);
			glVertex3d(cc - offset, -4 + offset, 0);
			glVertex3d(cc + offset, -4 + offset, 0);
			glVertex3d(cc + offset, -4 - offset, 0);
			glVertex3d(cc - offset, -4 - offset, 0);
			glEnd();
		}
		_column++;
	}
	_column = 0;

	//Row7
	for (int cc = -7; cc < 9; cc += 2)
	{
		if(Row7[_column] == 'W')
		{
			glBegin(GL_QUADS);
			glColor3d(1, 1, 1);
			glVertex3d(cc - offset, -6 + offset, 0);
			glVertex3d(cc + offset, -6 + offset, 0);
			glVertex3d(cc + offset, -6 - offset, 0);
			glVertex3d(cc - offset, -6 - offset, 0);
			glEnd();
		}
		_column++;
	}
	_column = 0;

	//Row8
	for (int cc = -7; cc < 9; cc += 2)
	{
		if(Row8[_column] == 'W')
		{
			glBegin(GL_QUADS);
			glColor3d(1, 1, 1);
			glVertex3d(cc - offset, -8 + offset, 0);
			glVertex3d(cc + offset, -8 + offset, 0);
			glVertex3d(cc + offset, -8 - offset, 0);
			glVertex3d(cc - offset, -8 - offset, 0);
			glEnd();
		}
		_column++;
	}
	_column = 0;

	// Show the new scene
    SwapBuffers(hDC);
}

Ok. So, in my opinion, your best bet is to put the CheckCollision function right at the line 155 of the code you posted. In other words, after you have drawn to the screen and before you do the SwapBuffers call.

If it is not a convenient place to put it, and it probably isn't, you should use glReadPixels to capture (almost) the entire screen (i.e. the whole region of interest) and use that image for the collision detection.

BTW, glBegin/glEnd are deprecated, you should use VBOs in this day-and-age.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.