Hi
From my short observation RenderTexture.GetNativeTextureID() return texture_2d id attached to FBO.
What I need is to get Frame Buffer Object ID but no idea how to obtain it.
Why FBO id is better:[PBO for async glGetTexImage, random slowdowns…][1]
[1]: PBO for async glGetTexImage, random slowdowns.. - OpenGL: Advanced Coding - Khronos Forums
I try to implement DMA transfer from FBO and display it on desktop - (WinXP).
I have tested both: glReadPixels,glGetTexImage and was not able to achieve good performance with DMA and glGetTexImage.
I am able to transfer data by glReadPixels (~10% CPU usage) but for that I need FBO id.
This is my short test program - maybe it helps a little (warning! I am FBO,PBO,VBO noob)
int texture_id=0;
//public Texture2D tex;
public RenderTexture tex;
IEnumerator Start () {
texture_id=tex.GetNativeTextureID();
yield return StartCoroutine("CallPluginAtEndOfFrames");
}
private IEnumerator CallPluginAtEndOfFrames ()
{
while (true) {
// Wait until all frame rendering is done
yield return new WaitForEndOfFrame();
// Set time for the plugin
SetTimeFromUnity (Time.timeSinceLevelLoad);
// Issue a plugin event with arbitrary integer identifier.
// The plugin can distinguish between different
// things it needs to do based on this ID.
// For our simple plugin, it does not matter which ID we pass here.
GL.IssuePluginEvent (texture_id);
}
}
Plugin code
-----------
extern "C" void EXPORT_API BlitTexture(int textureID)
{
//this is called from issue plubin event
static int index = 0;
int nextIndex = 0; // pbo index used for next frame
static bool b=0;
int textureWidth,textureHeight=512;
if (b==0)
{
// get pointers to GL functions
glGenBuffersARB = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffersARB");
glBindBufferARB = (PFNGLBINDBUFFERARBPROC)wglGetProcAddress("glBindBufferARB");
glBufferDataARB = (PFNGLBUFFERDATAARBPROC)wglGetProcAddress("glBufferDataARB");
glBufferSubDataARB = (PFNGLBUFFERSUBDATAARBPROC)wglGetProcAddress("glBufferSubDataARB");
glDeleteBuffersARB = (PFNGLDELETEBUFFERSARBPROC)wglGetProcAddress("glDeleteBuffersARB");
glGetBufferParameterivARB = (PFNGLGETBUFFERPARAMETERIVARBPROC)wglGetProcAddress("glGetBufferParameterivARB");
glMapBufferARB = (PFNGLMAPBUFFERARBPROC)wglGetProcAddress("glMapBufferARB");
glUnmapBufferARB = (PFNGLUNMAPBUFFERARBPROC)wglGetProcAddress("glUnmapBufferARB");
glBindFramebufferEXT = (PFNGLBINDFRAMEBUFFEREXTPROC)wglGetProcAddress("glBindFramebufferEXT");
// create 2 pixel buffer objects, you need to delete them when program exits.
// glBufferDataARB with NULL pointer reserves only memory space.
glGenBuffersARB(PBO_COUNT, pboIds);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[0]);
glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, DATA_SIZE, 0, GL_STREAM_READ_ARB);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[1]);
glBufferDataARB(GL_PIXEL_PACK_BUFFER_ARB, DATA_SIZE, 0, GL_STREAM_READ_ARB);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
b=1;
freopen("debug.txt", "a", stdout);
printf("SetTexture id:%d
" ,textureID);
printf("PBO ID:%d %d
" ,pboIds[0],pboIds[1]);
}
BITMAPINFOHEADER bhi;
bhi.biSize=sizeof(BITMAPINFOHEADER);
bhi.biWidth=512;
bhi.biHeight=512;
bhi.biPlanes=1;
bhi.biBitCount=32;
bhi.biCompression = BI_RGB;
bhi.biSizeImage=bhi.biWidth*bhi.biHeight*4;
bhi.biClrUsed=0;
bhi.biClrImportant=0;
bhi.biXPelsPerMeter=1000;
bhi.biXPelsPerMeter=1000;
// increment current index first then get the next index
// "index" is used to read pixels from a framebuffer to a PBO
// "nextIndex" is used to process pixels in the other PBO
index = (index + 1) % 2;
nextIndex = (index + 1) % 2;
//glReadBuffer(textureID);
//glBindTexture(GL_TEXTURE_2D, textureID);
// Use offset instead of pointer.
// OpenGL should perform asynch DMA transfer, so glReadPixels() will return immediately.
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 1); //<-how to get this id from unity???
glReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[index]);
glReadPixels(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, PIXEL_FORMAT, GL_UNSIGNED_BYTE, 0);
//glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);
// map the PBO that contain framebuffer pixels before processing it
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pboIds[nextIndex]);
GLubyte* src = (GLubyte*)glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB);
if(src )
{
HDC dc=GetDC(0);
SetDIBitsToDevice(dc,0,0,512,512,0,0,0,512,src,(BITMAPINFO*)&bhi,DIB_RGB_COLORS);
ReleaseDC(0,dc);
glUnmapBufferARB(GL_PIXEL_PACK_BUFFER_ARB); // release pointer to the mapped buffer
}
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, 0);
}