Copying Data to Textures [SOLVED]

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
slavik262
Posts: 753
Joined: Sun Nov 22, 2009 9:25 pm
Location: Wisconsin, USA

Copying Data to Textures [SOLVED]

Post by slavik262 »

I'm making a program that streams 640 x 480 video from a robot (with a webcam). How I'm doing this is:
  1. Make a rectangle mesh with a texture.
  2. Point a camera at the rectangle mesh so it takes up the entire screen/window.
  3. Render. As images from the robot come in, convert them to IImages and copy their data to the texture.
To run a quick test of this, I created the following program. It loads two images, each 640 x 480, creates a 640 x 480, and copies one of the images to the texture every 30th of a second. I ran this on my machine which has a GF GTX 260, and it works absoltuely perfectly. I ran it on several other machines with integrated graphics, and this happens.

Image

Ignore the FPS - that's just because I had just brought the window back up after minimizing it. This is what I should be seeing (stretched to the 800 x 600 window of course):

Image

It looks like the texture isn't the expected size (maybe getting bumped up to 1024 x 512) and the rows aren't lining up because of this. Do most integrated graphics systems not support textures that aren't powers of two? I'll have to check with IVideoDriver::queryFeature(EVDF_TEXTURE_NPOT), but I was wondering if anyone had an idea about what the problem might be in the meantime.

Here's the code (Screen is just the object that sets up the camera and creates the rectangle with a texture. I'm sure this isn't the problem).

Code: Select all

#include <irrlicht.h>
#include <ctime>
#include "Screen.h"

#ifdef _IRR_WINDOWS_
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#endif

using namespace irr;
using namespace video;
using namespace scene;

const SColor kBgColor(255, 0xe4, 0xe7, 0xec);

 int main(void)
{
	SIrrlichtCreationParameters cp;
	cp.Bits = 32;
	cp.DriverType = EDT_DIRECT3D9;
	cp.Vsync = true;

	IrrlichtDevice* device = createDeviceEx(cp);

	device->setResizable(true);

	IVideoDriver* vd = device->getVideoDriver();
	ISceneManager* sm = device->getSceneManager();

	ICameraSceneNode* cam = sm->addCameraSceneNode();

	vd->setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false);

	ITexture* texture = vd->addTexture(dimension2d<u32>(640, 480), "Video Image");
	IImage* awesomeImg = vd->createImageFromFile("Awesome.png");
	IImage* doNotWantImg = vd->createImageFromFile("DoNotWant.png");

	bool awesomeTurn = true;

	Screen scrn(cam, sm, texture);

	u8 sinceLastFPS = 0;

	clock_t lastTime = clock();

	while(device->run())
	{
		if(device->isWindowActive())
		{
			if(clock() >= lastTime + CLOCKS_PER_SEC / 30)
			{
				if(awesomeTurn)
				{
					u32 imgBytes = awesomeImg->getImageDataSizeInBytes();
					void* txtPtr = texture->lock();
					void* imgPtr = awesomeImg->lock();
					memcpy(txtPtr, imgPtr, imgBytes);
					awesomeImg->unlock();
					texture->unlock();
				}

				else
				{
					u32 imgBytes = doNotWantImg->getImageDataSizeInBytes();
					void* txtPtr = texture->lock();
					void* imgPtr = doNotWantImg->lock();
					memcpy(txtPtr, imgPtr, imgBytes);
					doNotWantImg->unlock();
					texture->unlock();
				}

				awesomeTurn = !awesomeTurn;

				lastTime = clock();
			}

			if(++sinceLastFPS == 20)
			{
				sinceLastFPS = 0;
				stringw title(L"Rendering at ");
				title += vd->getFPS();
				title += L" FPS";
				device->setWindowCaption(title.c_str());
			}

			vd->beginScene(true, true, kBgColor);
			sm->drawAll();
			vd->endScene();
		}
		else
			device->yield();
	}

	awesomeImg->drop();
	doNotWantImg->drop();

	return 0;
}
Last edited by slavik262 on Tue Mar 09, 2010 12:28 pm, edited 1 time in total.
CuteAlien
Admin
Posts: 9929
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Textures often have an unused border on the right of each line. So you have to differ between the width of the image and the pitch (the real size of one line in bytes). Which also means you must usually copy line-by-line.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
slavik262
Posts: 753
Joined: Sun Nov 22, 2009 9:25 pm
Location: Wisconsin, USA

Post by slavik262 »

It was the pitch, and copying line by line fixed everything. Many thanks.
Post Reply