I am using this tutorial to learn a little XNA, and i keep running into problems. I've had to convert alot of the code, since it seems the tutorial do not use XNA 4.0.
But lets cut to the chase!
float aXPosition = (float)(-mCarWidth / 2 + mCarPosition.X + aMove * Math.Cos(mCarRotation));
float aYPosition = (float)(-mCarHeight / 2 + mCarPosition.Y + aMove * Math.Sin(mCarRotation));
Texture2D aCollisionCheck = CreateCollisionTexture(aXPosition, aYPosition);
//Bruke GetData til å fylle en array med fargen på pixlene ved collisons texturen
int aPixels = mCarWidth * mCarHeight;
Color[] myColors = new Color[aPixels];
aCollisionCheck.GetData<Color>(0, new Rectangle((int)(aCollisionCheck.Width / 2 - mCarWidth / 2),
(int)(aCollisionCheck.Height / 2 - mCarHeight / 2), mCarWidth, mCarHeight), myColors, 0, aPixels);
The error i get when i try to debug the code says: InvalidOperationException was unhandeled, The render Target must not be set on the device when it is used as a texture.
I have no clue what to do.
This basically means exactly what it says.
You have to unset the render target from the device by calling GraphicsDevice.SetRenderTarget(null) (or setting it to a different render target). Because you can't use it as both a source texture and a destination buffer at the same time.
Keep in mind that, in this version of XNA, there is no ResolveRenderTarget. Render targets simply are textures.
Note that the tutorial that you are using is pretty terrible. Reading back from a render target like this is extremely slow. Especially seeing as the operations that it is using the render target for (selecting pixels in a transformed region) could easily be done efficiently on the CPU. Consider using this better, official example.
Related
I am new to Lua programming and I am having problems while trying to move an image from a set of coordinates to another.
What I am trying to create is to be used with the X-Plane flight simulator. There is a library called SASL (www.1-sim.com), that was created to make plugins (for X-Plane) creation easir, since the default language is C++ and many people find it difficult.
In general, SASL works as a bridge between Lua and X-Plane, in general lines, the scripts you write reads some data straight from X-Plane (DataRefs) while it is running and depending on the code you wrote its execute commands or many other things that it is possible.
So, when using SASL to create cockpit/panel gauges it uses a base file, named 'avionics.lua' that works as a class and loads all gauges you create for the specific aircraft you are working on. For example my avionics.lua file looks like this:
size = { 2048, 2048 }
components = {
flaps {};
};
where, 'size' is the size that will be used for things to be drawn and components is an array of gauges, in this case the flaps gauge.
The rest of the work is to create the gauge functionality and this is done in a separate file, in my case, called 'flaps.lua'.
Within flaps.lua, is where I need to code the flaps indicator functionality which is to load 2 images: one for the back ground and the second one for the flaps indicator.
The first image is a fixed image. The second one will move throught the 'y' axis based on the flaps indicator DataRef (flapsDegree property below).
The code below when X-Plane is running displays the background image and the flaps indicator on its first stage which is 0 as you can see on the image.
size = {78,100}
local flapsDegree = globalPropertyf("sim/cockpit2/controls/flap_ratio")
local background = loadImage("gfx/Flaps.png")
local indicator = loadImage("gfx/Flaps_Indicator.png")
local flaps = get(flapsPosition)
components = {
texture { position = {945, 1011, 60, 100}, image = background},
texture { position = {959, 1097, 30, 9}, image = indicator},
}
Image
Now, the problem comes when I need to implement the logic for moving the 'indicator' image through the 'y' axis.
I have tried this code without success:
if flaps == 0.333 then
indicator.position = {959, 1075, 30, 9}
end
So how could I accomplish that?
I am not familiar with the SALS library. I just had a quick look into it.
Everything you need to know is in the manuals on the website you linked.
In particular http://www.1-sim.com/files/SASL300.pdf
Everytime your screen is updated each components draw() function will be called.
So if you want to change something dynamically you have to put that into the component's draw function.
If you open the SALS sources you'll find basic components which show you how to use that stuff. One of them is needle.lua:
-- default angle
defineProperty("angle", 0)
-- no image
defineProperty("image")
function draw(self)
local w, h = getTextureSize(get(image))
local max = w
if h > max then
max = h
end
local rw = (w / max) * 100
local rh = (h / max) * 100
drawRotatedTexture(get(image), get(angle),
(100 - rw) / 2, (100 - rh) / 2, rw, rh)
end
If you check the manual you'll find that there is not only a drawRotatedTexture function but many other functions for drawing stuff. Just play around. Try drawTexture for your purpose.
If you don't know what you have to program, open every single lua file in the library and read it together with the Lua reference manual and the SALS documentation until you understand what is going on. Once you understand the existing code you can extend it with ease.
I'm trying to build Qt5.6 project in MSVS2013 express (i wrote all code under QtCreator in Linux). First of all in Visual studio it i could build it only in Release mode, and it works fine. Then i used windeployqt.exe utility for creating deployment pack. I also put assimp32.dll (i use it for model loading).
And everything works fine, except PIXEL_BUFFER functionality (I draw some stuff to texture in additional Framebuffer, make some analysis of drawing result, prepare another one texture and push it for drawing).
I've got some errors in Dependency Walker (msvcr90.dll, Dcomp.dll, API-MS-WIN-CORE-*.dll) even though i've installed every MS Redistributable crap that exist in this world.
Here the code that i try to use:
void AUVGBO::PrepareGBO(QOpenGLShaderProgram *shader) {
if (mEnabled) {
this->PrepareRender(shader, AUVCamera::PR_PROJECTION | AUVCamera::PR_VIEW | AUVCamera::PR_VIEW_POS | AUVCamera::PR_LIGHT | AUVCamera::PR_LIGHT_POS );
// Attach framebuffer for intermediate rendering
m_GL->glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
m_GL->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
m_GL->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_GL->glViewport(0, 0, mGBO_Width, mGBO_Height);
}
}
void AUVGBO::FinishGBO(QOpenGLShaderProgram *shader) {
// Read pixels from FBO texture
GLuint indexAsync = mPBO_inIndex;
GLuint indexSync = (mPBO_inIndex + 1) % PBO_NUM;
// Bind pixel buffer for asynchronous reading from framebuffer
m_GL->glReadBuffer(GL_COLOR_ATTACHMENT0);
m_GL->glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO_in[indexAsync]);
m_GL->glReadPixels(0, 0, mGBO_Width, mGBO_Height, GL_RGB, GL_FLOAT, 0); // This call will be async
if (firstAsyncCalls && ( indexSync != 0 )) {
mPBO_inIndex = indexSync;
return;
} else {
firstAsyncCalls = false;
}
// Bind pixel buffer which already has data fetched one step ago
m_GL->glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO_in[indexSync]);
memcpy(mGBO_Pixels,
m_GL->glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_WRITE),
mGBO_Size * 3 * sizeof(GLfloat));
m_GL->glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
m_GL->glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
// Swap buffer for sync/async readback
mPBO_inIndex = indexSync;
m_GL->glBindFramebuffer(GL_FRAMEBUFFER, 0);
so now every pixel in memory area [mGBO_Pixels : mGBO_Size * 3 * sizeof(GLfloat)] is black, but they should'not be black. I put (for test) 0.12345f value in third byte of every pixel
color = vec4(cos, length(r), 0.12345f, 1.0f);
but (mGBO_Pixels + 2) is 0.0 if i run exe file. But in VS everything is ok as i've already said ((mGBO_Pixels + 2) = 0.12345f).
I found some SO answers, where people said that it could be Qt openGL bugs (their application crashes on initializeGLContext() stuff), but in my situation pushing created texture to openGL is ok. So guess that i've made a mistake somewhere. It drives me crazy. huh. Wish Sara and John Conor with T800 go to Microsoft instead of Cyberdyne.
P.S. I create release build using Cmake in my Arch Linux, and everything work as Avtomat Kalashnikova, so at least in Linux Qt OpenGL stuff works. If i find enough time i will try to use Cmake with MinGW in Windows.
I'm altering someone else's code. They used PNG's which are loaded via BufferedImage. I need to load a TGA instead, which is just simply a 18 byte header and BGR codes. I have the textures loaded and running, but I get a gray box instead of the texture. I don't even know how to DEBUG this.
Textures are loaded in a ByteBuffer:
final static int datasize = (WIDTH*HEIGHT*3) *2; // Double buffer size for OpenGL // not +18 no header
static ByteBuffer buffer = ByteBuffer.allocateDirect(datasize);
FileInputStream fin = new FileInputStream("/Volumes/RAMDisk/shot00021.tga");
FileChannel inc = fin.getChannel();
inc.position(18); // skip header
buffer.clear(); // prepare for read
int ret = inc.read(buffer);
fin.close();
I've followed this: [how-to-manage-memory-with-texture-in-opengl][1] ... because I am updating the texture once per frame, like video.
Called once:
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, width, height, 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
assert(GL11.GL_NO_ERROR == GL11.glGetError());
Called repeatedly:
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
GL11.glTexSubImage2D(GL11.GL_TEXTURE_2D, 0, 0, 0, width, height, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, byteBuffer);
assert(GL11.GL_NO_ERROR == GL11.glGetError());
return textureID;
The render code hasn't changed and is based on:
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, this.vertexCount);
Make sure you set the texture sampling mode. Especially min filter: glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR). The default setting is mip mapped (GL_NEAREST_MIPMAP_LINEAR) so unless you upload mip maps you will get a white read result.
So either set the texture to no mip or generate them. One way to do that is to call glGenerateMipmap after the tex img call.
(see https://www.khronos.org/opengles/sdk/docs/man/xhtml/glTexParameter.xml).
It's a very common gl pitfall and something people just tend to know after getting bitten by it a few times.
There is no easy way to debug stuff like this. There are good gl debugging tools in for example xcode but they will not tell you about this case.
Debugging GPU code is always a hassle. I would bet my money on a big industry progress in this area as more companies discover the power of GPU. Until then; I'll share my two best GPU debugging friends:
1) Define a function to print OGL errors:
int printOglError(const char *file, int line)
{
/* Returns 1 if an OpenGL error occurred, 0 otherwise. */
GLenum glErr;
int retCode = 0;
glErr = glGetError();
while (glErr != GL_NO_ERROR) {
printf("glError in file %s # line %d: %s\n", file, line, gluErrorString(glErr));
retCode = 1;
glErr = glGetError();
}
return retCode;
}
#define printOpenGLError() printOglError(__FILE__, __LINE__)
And call it after your render draw calls (possible earlier errors will also show up):
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, this.vertexCount);
printOpenGLError();
This alerts if you make some invalid operations (which might just be your case) but you usually have to find where the error occurs by trial and error.
2) Check out gDEBugger, free software with tons of GPU memory information.
[Edit]:
I would also recommend using the opensource lib DevIL - its quite competent in loading various image formats.
Thanks to Felix, by not calling glTexSubImage2D (leaving the memory valid, but uninitialized) I noticed a remnant pattern left by the default memory. This indicated that the texture is being displayed, but the load is most likely the problem.
**UPDATE:
The, problem with the code above is essentially the buffer. The buffer is 1024*1024, but it is only partially filled in by the read, leaving the limit marker of the ByteBuffer at 2359296(1024*768*3) instead of 3145728(1024*1024*3). This gives the error:
Number of remaining buffer elements is must be ... at least ...
I thought that OpenGL needed space to return data, so I doubled the size of the buffer.
The buffer size is doubled to compensate for the error.
final static int datasize = (WIDTH*HEIGHT*3) *2; // Double buffer size for OpenGL // not +18 no header
This is wrong, what is needed is the flip() function (Big THANKS to Reto Koradi for the small hint to the buffer rewind) to put the ByteBuffer in read mode. Since the buffer is only semi-full, the OpenGL buffer check gives an error. The correct thing to do is not double the buffer size; use buffer.position(buffer.capacity()) to fill the buffer before doing a flip().
final static int datasize = (WIDTH*HEIGHT*3); // not +18 no header
buffer.clear(); // prepare for read
int ret = inc.read(buffer);
fin.close();
buffer.position(buffer.capacity()); // make sure buffer is completely FILLED!
buffer.flip(); // flip buffer to read mode
To figure this out, it is helpful to hardcode the memory of the buffer to make sure the OpenGL calls are working, isolating the load problem. Then when the OpenGL calls are correct, concentrate on the loading of the buffer. As suggested by Felix K, it is good to make sure one texture has been drawn correctly before calling glTexSubImage2D repeatedly.
Some ideas which might cause the issue:
Your texture is disposed somewhere. I don't know the whole code but I guess somewhere there is a glDeleteTextures and this could cause some issues if called at the wrong time.
Are the texture width and height powers of two? If not this might be an issue depending on your hardware. Old hardware sometimes won't support non-power of two images.
The texture parameters changed between the draw calls at some other point ( Make a debug check of the parameters with glGetTexParameter ).
There could be a loading issue when loading the next image ( edit: or even the first image ). Check if the first image is displayed without loading the next images. If so it must be one of the cases above.
I’m trying to animate a Mayavi pipeline volume:
src = mlab.pipeline.volume(mlab.pipeline.scalar_field(data),vmin=.1*np.max(data),vmax=.2*np.max(data))
that is combined in the pipeline by another dataset represented as a cut plane.
However, I can’t get the volume visualization to update - only the first frame shows up. The animation is stepping through the data correctly (I get different values of the np.max(data[t]) below) but nothing in the visualization changes.
My understanding is that mlab_source_set should re-render correctly, and there’s nothing on the web anywhere that describes this (as far as I can tell).
The animation looks like:
#mlab.show
#mlab.animate(delay=250,ui=True)
def anim(src,data,tax,fig):
"""Animate."""
t = 0
nt = len(tax)
while 1:
vmin = .1*np.max(data[t])
vmax = .2*np.max(data[t])
print 'animation t = ',tax[t],', max = ',np.max(data[t])
src.mlab_source.set(scalar = mlab.pipeline.scalar_field(data[t]), vmin=vmin,vmax=vmax)
t = mod(t+1,nt)
yield
Any thoughts?
this is the code
CvMemStorage *mem123 = cvCreateMemStorage(0);
CvSeq* ptr123;CvRect face_rect123;
CvHaarClassifierCascade* cascade123 = (CvHaarClassifierCascade*)cvLoad("haarcascade_frontalface_alt2.xml" ); //detects the face if it's frontal
void HeadDetection(IplImage* frame,CvRect* face){
ptr123=cvHaarDetectObjects(frame,cascade123,mem123,1.2,2,CV_HAAR_DO_CANNY_PRUNING);
if(!ptr123){return ;}
if(!(ptr123->total)){return ;}
face_rect123=*(CvRect*)cvGetSeqElem( ptr123, 0 ); //CvRect face_rect holds the position of Rectangle
face->height=face_rect123.height;
face->width=face_rect123.width;
face->x=face_rect123.x;
face->y=face_rect123.y;
return ;
}//detects the position of head and it is fed in CvRect*face as rectangle
int main(){
IplImage* oldframe=cvCreateImage(cvSize(640,480),8,3);
CvCapture* capture=cvCaptureFromCAM(CV_CAP_ANY);
CvRect a;a.height=0;a.width=0;a.x=0;a.y=0;
while(1){
oldframe=cvQueryFrame(capture); //real frame captured of size 640x480
cvFlip(oldframe,oldframe,1);
cvResize(oldframe,frame); //frame scaled down 4 times
HeadDetection(frame,&a);
cvShowImage("frame",frame);
cvWaitKey(1);
}
}
Here if "HeadDetection(frame,&a);" is commented, then using task manager i see that angledetection.exe (name of my project) consumes 20188 Kb memory (No memory leak happening then).
However if I don't comment that the taskmanager shows that some memory leak is happening (around 300Kb/s )
I'm using VS 2010 on 64 bit windows 7 bit OS (core 2 duo).
This code is trying to detect face and get the four corners of square by haar detection in OpenCV 2.1
In case anything is unclear please ask. :-)
Thanks in advance.
You are getting a pointer to an object when you call cvHaarDetectObjects.
But you never free it ( the object that ptr123 points to).
Also face_rect123 isnt freed.
Btw you should consider refactoring the code and give better names to the variables.