- Home /
Render to RenderTexture in android/gles (plugin)
I am attempting to update a texture via a plugin in Unity. My first attempt was using a Texture2D, and while it works fine in android, on windows d3d11 there is no way to lock the buffer, and it crashes. So I found a solution, by using a RenderTexture, I get a dynamic type texture, and can map/unmap it to lock my buffer and it no longer crashes.... Except my rendering in gles no longer works. I don't get any error, it just doesn't write to my texture for some reason.
Here is a sample of my gles code (it was heavily inspired from an example I found online, as I am not super familiar with gles. Note that this all works fine if I use a Texture2D, but fails silently if I use a RenderTexture. I removed most of the error handling code to simplify readability, but I do normally check for glErrors everywhere, and no errors occur):
int texW =m_frameW;
int texH = m_frameH;
int dataSize = texW * texH;
bool singlePBO = false;
if(!testCreated)
{
glGenBuffers(2, pboIds);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[0]);
glBufferData(GL_PIXEL_UNPACK_BUFFER, dataSize, 0, GL_STREAM_DRAW);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[1]);
glBufferData(GL_PIXEL_UNPACK_BUFFER, dataSize, 0, GL_STREAM_DRAW);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
testCreated = true;
}
static int index = 0;
int nextIndex = 0; // pbo index used for next frame
// "index" is used to copy pixels from a PBO to a texture object
// "nextIndex" is used to update pixels in a PBO
if(singlePBO)
{
// In single PBO mode, the index and nextIndex are set to 0
index = nextIndex = 0;
}
else
{
// In dual PBO mode, increment current index first then get the next index
index = (index + 1) % 2;
nextIndex = (index + 1) % 2;
}
// bind the texture and PBO
glBindTexture(GL_TEXTURE_2D, (GLuint)txId);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[index]);
// copy pixels from PBO to texture object
// Use offset instead of pointer.
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texW, texH, (useAlphaChannel?GL_ALPHA:GL_RED), GL_UNSIGNED_BYTE, 0);
if((err = glGetError()) != GL_NO_ERROR)
{
SAL_FUNC_DEBUG("Error trying to copy texture, switching channel");
useAlphaChannel = !useAlphaChannel;
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, texW, texH, (useAlphaChannel?GL_ALPHA:GL_RED), GL_UNSIGNED_BYTE, 0);
if((err = glGetError()) != GL_NO_ERROR)
{
SAL_FUNC_DEBUG("Switching channel didn't help... you're screwed");
}
}
// bind PBO to update pixel values
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pboIds[nextIndex]);
// map the buffer object into client's memory
// Note that glMapBufferARB() causes sync issue.
// If GPU is working with this buffer, glMapBufferARB() will wait(stall)
// for GPU to finish its job. To avoid waiting (stall), you can call
// first glBufferDataARB() with NULL pointer before glMapBufferARB().
// If you do that, the previous data in PBO will be discarded and
// glMapBufferARB() returns a new allocated pointer immediately
// even if GPU is still working with the previous data.
glBufferData(GL_PIXEL_UNPACK_BUFFER, dataSize, 0, GL_STREAM_DRAW);
GLubyte* ptr = (GLubyte*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER,0, dataSize, GL_MAP_WRITE_BIT);
if(ptr)
{
// update data directly on the mapped buffer
memcpy(ptr, m_frame.data(), dataSize);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); // release pointer to mapping buffer
}
// it is good idea to release PBOs with ID 0 after use.
// Once bound with 0, all pixel operations behave normal ways.
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
Does anyone know if a RenderTexture is considered as a gl Texture2D? or maybe it is a FrameBuffer or something? Unity were nice enough to provide a plugin example using a texture2D, but nothing with RenderTexture.
Any help would be greatly appreciated at this point.
Your answer
Follow this Question
Related Questions
Rendering Unity output on OpenTK Windows? 0 Answers
OpenGL Context from Plugin 1 Answer
External terrain renderer 0 Answers
Native rendering plugin OpenGL device type not being set. 2 Answers
Native Rendering Plugin with Oculus Rift 0 Answers