C'è un modo per rendere il contenuto di un UIView come una trama con OpenGL in iOS? O il contenuto di un CGLayer?Rendering del contenuto di UIView come trama OpenGL
risposta
È possibile utilizzare la proprietà layer della vista per ottenere il CALayer e utilizzare renderInContext: su quello per disegnare in un contesto CoreGraphics. È possibile impostare un contesto CoreGraphics con memoria allocata dall'utente per ricevere un buffer di pixel. È quindi possibile caricarlo in OpenGL con il metodo normale.
Quindi: c'è un mezzo per ottenere il contenuto dei pixel di un UIView e OpenGL accetterà i buffer dei pixel. Non esiste un collegamento specifico tra i due.
Coding estemporaneamente, il processo sarebbe qualcosa di simile:
UIView *view = ... something ...;
// make space for an RGBA image of the view
GLubyte *pixelBuffer = (GLubyte *)malloc(
4 *
view.bounds.size.width *
view.bounds.size.height);
// create a suitable CoreGraphics context
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context =
CGBitmapContextCreate(pixelBuffer,
view.bounds.size.width, view.bounds.size.height,
8, 4*view.bounds.size.width,
colourSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colourSpace);
// draw the view to the buffer
[view.layer renderInContext:context];
// upload to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0,
GL_RGBA,
view.bounds.size.width, view.bounds.size.height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, pixelBuffer);
// clean up
CGContextRelease(context);
free(pixelBuffer);
che non si occupa di questioni che circondano non-potere-su-due viste dimensioni su hardware senza il non-potere-di-due tessitura estensione e presuppone che un nome di struttura GL appropriato sia già stato generato e vincolato. Controllate voi stessi, ma penso che il non-potere-di-due sia supportato sull'hardware SGX (cioè, iPhone 3GS in poi, l'iPad e tutti tranne l'iPod Touch di terza generazione da 8 gb in poi) ma non su MBX.
Il modo più semplice per gestire le trame non di potenza di due è probabilmente quello di creare una grande potenza di due texture e di usare glTexSubImage2D per caricare solo la porzione dalla tua UIView di origine.
Ecco un altro metodo per afferrare un livello OpenGL, che è quello di utilizzare glReadPixels. Questo catturerà i livelli visibili DIETRO il tuo livello openGL, (in sostanza, lo schermo visibile). Dai un'occhiata a questa domanda: How do I grab an image form my EAGLLayer ?
Una volta che hai la tua immagine, deve essere ridimensionata alla potenza di due. Puoi provare e allungare l'immagine, ma ciò causerà problemi di qualità quando lo riduci di nuovo o se lo fai più volte. Il modo migliore è disegnare la dimensione normale dell'immagine in una trama di base-2 con extra pixel per creare un buffer. Ecco il codice (ho modificato questo dal codice di qualcun altro, ma non riesco a trovare il codice originale, quindi se qualcuno vede il codice originale, per favore fatemelo sapere da dove è venuto a dare credito):
-(UIImage*)base2Image:(UIImage *) srcImg {
int frame2Base = 512;
CGSize srcSize = [srcImg size];
CGRect rec = CGRectMake(0, 0, frame2Base, frame2Base);
[srcImg drawInRect:rec blendMode:kCGBlendModeNormal alpha:1.0];
//create a context to do our clipping in
UIGraphicsBeginImageContext(CGSizeMake(frame2Base, frame2Base));
CGContextRef currentContext = UIGraphicsGetCurrentContext();
//create a rect with the size we want to crop the image to
CGRect clippedRect = CGRectMake(0, 0, frame2Base, frame2Base);
CGContextClipToRect(currentContext, clippedRect);
//create a rect equivalent to the full size of the image
CGRect drawRect = CGRectMake(0, 0, srcSize.width, srcSize.height);
//draw the image to our clipped context using our offset rect
CGContextDrawImage(currentContext, drawRect, srcImg.CGImage);
UIImage *dstImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return dstImg;
}
Ora, una volta fatto, si utilizza una matrice di coordinate di trama per SOLO estrarre la sezione di dimensioni corrette dall'immagine. Ad esempio:
GLfloat texCoords[] = {
0.0, (float)frameHeight/2BaseHeight,
0.0, 0.0,
(float)frameWidth/2BaseWidth, (float)frameHeight/2BaseHeight,
(float)frameWidth/2BaseWidth, 0.0
};
E ce l'hai. Uno screenshot dal tuo schermo visibile che ora è una texture.
Questa è una grande tecnica! In realtà ho bisogno di ottenere solo il contenuto di una porzione della mia gerarchia di visualizzazione, ma ancora, +1. –
- 1. OpenGL - Rendering in una trama
- 2. OpenGL ES Android Framebuffer - Rendering profondità del buffer di trama
- 3. Combinazione di blocchi di animazione UIView e rendering OpenGL ES
- 4. opengl - come implementare "rendering portale"
- 5. Aggiornamento di una trama in OpenGL con glTexImage2D
- 6. Sincronizza layout UIView su frame OpenGL
- 7. Qual è l'intervallo di ID trama OpenGL?
- 8. Alpha blending problema con più iterazioni di rendering nella stessa trama (OpenGL)
- 9. Come ritagliare il rendering in OpenGL (C++)
- 10. Contenuto AirPrint di un UIView
- 11. Webkit di rendering nella trama GL
- 12. come implementare il rendering in scala di grigi in OpenGL?
- 13. Come ottenere il contenuto del rendering a livello di programmazione?
- 14. Rendering OpenGL ES su richiesta con GLKit
- 15. Impostazione di destinazioni di rendering multiple OpenGL
- 16. OpenGL ES 2d rendering nell'immagine
- 17. Come creare una trama OpenGL dall'array di byte in Android
- 18. Caricamento trama texture JuicyPixels in Haskell OpenGL?
- 19. Caricamento trama per OpenGL con OpenCV
- 20. Rendering grafica vettoriale in OpenGL?
- 21. trama capovolta? | OpenGL-ES 2.0 (android)
- 22. Schermata del contenuto OpenGL ES per l'app Paint
- 23. Caricamento trama OpenGL: UNSIGNED_BYTE vs UNSIGNED_INT_8_8_8_8
- 24. Converti trama OpenGL in OpenCV Mat
- 25. Come modificare il contenuto prima del rendering in Android WebView?
- 26. Impossibile inizializzare la libreria di rendering OpenGL
- 27. OpenGL esegue il rendering di caselle all'interno
- 28. Come modificare il singolo texel nella trama OpenGL
- 29. Rendering UIView con i relativi figli
- 30. Tipo di formato trama OpenGL errato per CL/GL-Interop?
Utilizzo di CVOpenGLESTextureCacheCreateTextureForImage deve essere più efficiente dell'utilizzo di glTexImage2D direttamente. Il buffer dei pixel dovrebbe avere le chiavi 'IOSurfaceProperties' e' OpenGLESCompatibility' definite. – OrangeDog