draw2DImage BUG in OpenGL! (fixed)

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
chromdragon
Posts: 101
Joined: Wed Feb 15, 2006 4:22 pm
Location: RO

draw2DImage BUG in OpenGL! (fixed)

Post by chromdragon »

Code: Select all

ITexture *tex = driver->getTexture("../data/texture_test.tga");

while(device->run())
{
	driver->beginScene(true, true, SColor(255,100,101,140));

	driver->draw2DImage(tex, position2d<s32>(100, 10));

	driver->endScene();

   // ...
}
TEST TEXTURE: http://redcloud.no-ip.info/Download/texture_test.tga
(this is a simple texture 128x128 with 1-pixel black border)

Image

The result of this test will show that first line of the texture will
be the last when it's draw.

problem: void COpenGLDriver::draw2DImage(...) in copengldriver.cpp

Code: Select all

	glBegin(GL_QUADS);

	// 0
	glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
	glVertex2f(npos.UpperLeftCorner.X, npos.UpperLeftCorner.Y);

	// 1
	glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
	glVertex2f(npos.LowerRightCorner.X, npos.UpperLeftCorner.Y);

	// 2
	glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
	glVertex2f(npos.LowerRightCorner.X, npos.LowerRightCorner.Y); 

	// 3
	glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
	glVertex2f(npos.UpperLeftCorner.X, npos.LowerRightCorner.Y); 
	
	glEnd();
Maybe somebody can help me? Or give me a idea how to fix this?
Last edited by chromdragon on Wed Apr 19, 2006 9:53 pm, edited 1 time in total.
chromdragon
Posts: 101
Joined: Wed Feb 15, 2006 4:22 pm
Location: RO

Post by chromdragon »

Partial Solution:

Code: Select all


	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	glOrtho(0, win_width, 0, win_height, -1, 1);

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	glBegin(GL_QUADS);
		glTexCoord2f( ... );
		glVertex2i(( ... );

		glTexCoord2f( ... );
		glVertex2i( ... );

		glTexCoord2f( ... );
		glVertex2i(( ... );

		glTexCoord2f( ... );
		glVertex2i( ... );
	glEnd();

	glMatrixMode(GL_PROJECTION);
	glPopMatrix();

	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();

I will try to make a fix soon!
jrm
Posts: 111
Joined: Tue Dec 13, 2005 8:57 pm

Post by jrm »

I have had a similar issue. In OpenGL and DX the draw2DImage doesn't draw very well, pixels are missplaced.

If your fix fixes my issue too that would be great!

Thank you,

JRM

Thread that I started.
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=11403
chromdragon
Posts: 101
Joined: Wed Feb 15, 2006 4:22 pm
Location: RO

Post by chromdragon »

patch: COpenGLDriver::draw2DImage() in COpenGLDriver.cpp

const core::rect<s32>* clipRect it is not implemented !!

Code: Select all


void COpenGLDriver::draw2DImage(video::ITexture* texture, const core::position2d<s32>& pos, 
								 const core::rect<s32>& sourceRect, 
								 const core::rect<s32>* clipRect, SColor color, 
								 bool useAlphaChannelOfTexture)

{

	if (!texture)
		return;

	core::dimension2d<s32> currentRendertargetSize = getCurrentRenderTargetSize();
	core::dimension2d<s32> sourceSurfaceSize = texture->getOriginalSize();

	setTexture(0, texture);	
	glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());

	if (useAlphaChannelOfTexture)
		setRenderStates2DMode(false, true, true);
	else
		setRenderStates2DMode(false, true, false);

	glDisable(GL_CULL_FACE);

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	glOrtho(0, currentRendertargetSize.Width, 0, currentRendertargetSize.Height, -1, 1);

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	f32 t_Xmin, t_Xmax, t_Ymin, t_Ymax;
	s32 s_Xmin, s_Xmax, s_Ymin, s_Ymax;

	s_Xmin = pos.X;
	s_Ymin = pos.Y;
	s_Xmax = s_Xmin + sourceRect.getWidth();
	s_Ymax = s_Ymin + sourceRect.getHeight();

	s_Ymin = currentRendertargetSize.Height - s_Ymin; 
	s_Ymax = currentRendertargetSize.Height - s_Ymax;

	t_Xmin = (f32) sourceRect.UpperLeftCorner.X / (f32) sourceSurfaceSize.Width;
	t_Ymax = (f32) sourceRect.LowerRightCorner.Y / (f32) sourceSurfaceSize.Height;
	t_Xmax = (f32) sourceRect.LowerRightCorner.X / (f32) sourceSurfaceSize.Width;
	t_Ymin = (f32) sourceRect.UpperLeftCorner.Y/ (f32) sourceSurfaceSize.Height;

	glBegin(GL_QUADS);
		glTexCoord2f(t_Xmin, t_Ymin);
		glVertex2i(s_Xmin, s_Ymin);

		glTexCoord2f(t_Xmin, t_Ymax);
		glVertex2i(s_Xmin, s_Ymax);

		glTexCoord2f(t_Xmax, t_Ymax);
		glVertex2i(s_Xmax, s_Ymax);

		glTexCoord2f(t_Xmax, t_Ymin);
		glVertex2i(s_Xmax, s_Ymin);
	glEnd();

	glMatrixMode(GL_PROJECTION);
	glPopMatrix();

	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();

}

void COpenGLDriver::draw2DImage(video::ITexture* texture, const core::rect<s32>& destRect, 
                   const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect, 
                   video::SColor* colors, bool useAlphaChannelOfTexture) 
{ 
	if (!texture) 
      return; 
	
	core::dimension2d<s32> currentRendertargetSize = getCurrentRenderTargetSize();
	core::dimension2d<s32> sourceSurfaceSize = texture->getOriginalSize();

	setTexture(0, texture);	

	bool bTempColors=false; 

	if(colors==NULL) 
	{ 
		colors=new SColor[4];
		for(int i=0;i<4;i++)colors[i]=SColor(0,255,255,255); 
		bTempColors=true; 
	} 

		if (useAlphaChannelOfTexture)
			setRenderStates2DMode(false, true, true);
		else
			setRenderStates2DMode(false, true, false);

		glDisable(GL_CULL_FACE);

		glMatrixMode(GL_PROJECTION);
		glPushMatrix();
		glLoadIdentity();
		glOrtho(0, currentRendertargetSize.Width, 0, currentRendertargetSize.Height, -1, 1);

		glMatrixMode(GL_MODELVIEW);
		glPushMatrix();
		glLoadIdentity();

		f32 t_Xmin, t_Xmax, t_Ymin, t_Ymax;
		s32 s_Xmin, s_Xmax, s_Ymin, s_Ymax;

		s_Xmin = destRect.UpperLeftCorner.X;
		s_Ymin = destRect.UpperLeftCorner.Y;
		s_Xmax = s_Xmin + destRect.getWidth();
		s_Ymax = s_Ymin + destRect.getHeight();

		s_Ymin = currentRendertargetSize.Height - s_Ymin; 
		s_Ymax = currentRendertargetSize.Height - s_Ymax;

		t_Xmin = (f32) sourceRect.UpperLeftCorner.X / (f32) sourceSurfaceSize.Width;
		t_Ymax = (f32) sourceRect.LowerRightCorner.Y / (f32) sourceSurfaceSize.Height;
		t_Xmax = (f32) sourceRect.LowerRightCorner.X / (f32) sourceSurfaceSize.Width;
		t_Ymin = (f32) sourceRect.UpperLeftCorner.Y/ (f32) sourceSurfaceSize.Height;

		glBegin(GL_QUADS);
			glColor4ub(colors[0].getRed(), colors[0].getGreen(), colors[0].getBlue(), colors[0].getAlpha()); 
			glTexCoord2f(t_Xmin, t_Ymin);
			glVertex2i(s_Xmin, s_Ymin);

			glColor4ub(colors[3].getRed(), colors[3].getGreen(), colors[3].getBlue(), colors[3].getAlpha()); 
			glTexCoord2f(t_Xmin, t_Ymax);
			glVertex2i(s_Xmin, s_Ymax);

			glColor4ub(colors[2].getRed(), colors[2].getGreen(), colors[2].getBlue(), colors[2].getAlpha()); 
			glTexCoord2f(t_Xmax, t_Ymax);
			glVertex2i(s_Xmax, s_Ymax);

			glColor4ub(colors[1].getRed(), colors[1].getGreen(), colors[1].getBlue(), colors[1].getAlpha());
			glTexCoord2f(t_Xmax, t_Ymin);
			glVertex2i(s_Xmax, s_Ymin);
		glEnd();

		glMatrixMode(GL_PROJECTION);
		glPopMatrix();

		glMatrixMode(GL_MODELVIEW);
		glPopMatrix();

	   if(bTempColors) 
		   delete [] colors; 
}

Post Reply