我想用pbuffer表面实现egl offscreen渲染。但我能读回的只是背景颜色。我画的东西是看不到的。
例如,如果我用蓝色清除屏幕,通过glReadPixel读回图像只是一个蓝色图像,没有其他的东西。我的想法确实没用了
#include <QCoreApplication>
#include <QDebug>
#include <QImage>
#include <GLES2/gl2.h>
#include <EGL/egl.h>
#include <QElapsedTimer>
GLuint LoadShader(const char *shaderSrc, GLenum type)
{
GLuint shader;
GLint compiled;
// Create the shader object
shader = glCreateShader(type);
if(shader == 0)
return 0;
// Load the shader source
glShaderSource(shader, 1, &shaderSrc, NULL);
// Compile the shader
glCompileShader(shader);
// Check the compile status
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if(!compiled)
{
GLint infoLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if(infoLen > 1)
{
char* infoLog = (char*)malloc(sizeof(char) * infoLen);
glGetShaderInfoLog(shader, infoLen, NULL, infoLog);
qDebug() << "Error compiling shader:" << infoLog;
free(infoLog);
}
glDeleteShader(shader);
return 0;
}
return shader;
}
int main(int argc, char *argv[])
{
GLuint renderBufferWidth = 1920;
GLuint renderBufferHeight = 1080;
EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE };
// Step 1 - Get the default display.
EGLDisplay eglDisplay = eglGetDisplay((EGLNativeDisplayType)0);
// Step 2 - Initialize EGL.
eglInitialize(eglDisplay, 0, 0);
// Step 3 - Make OpenGL ES the current API.
eglBindAPI(EGL_OPENGL_ES_API);
// Step 4 - Specify the required configuration attributes.
EGLint pi32ConfigAttribs[23];
pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
pi32ConfigAttribs[1] = EGL_PBUFFER_BIT;
pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
pi32ConfigAttribs[4] = EGL_CONFORMANT;
pi32ConfigAttribs[5] = EGL_OPENGL_ES2_BIT;
pi32ConfigAttribs[6] = EGL_COLOR_BUFFER_TYPE;
pi32ConfigAttribs[7] = EGL_RGB_BUFFER;
pi32ConfigAttribs[8] = EGL_LUMINANCE_SIZE;
pi32ConfigAttribs[9] = 0;
pi32ConfigAttribs[10] = EGL_RED_SIZE;
pi32ConfigAttribs[11] = 5;
pi32ConfigAttribs[12] = EGL_GREEN_SIZE;
pi32ConfigAttribs[13] = 6;
pi32ConfigAttribs[14] = EGL_BLUE_SIZE;
pi32ConfigAttribs[15] = 5;
pi32ConfigAttribs[16] = EGL_ALPHA_SIZE;
pi32ConfigAttribs[17] = 0;
pi32ConfigAttribs[18] = EGL_DEPTH_SIZE;
pi32ConfigAttribs[19] = 16;
pi32ConfigAttribs[20] = EGL_LEVEL;
pi32ConfigAttribs[21] = 0;
pi32ConfigAttribs[22] = EGL_NONE;
// Step 5 - Find a config that matches all requirements.
int iConfigs;
EGLConfig eglConfig;
eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1,
&iConfigs);
if (iConfigs != 1)
{
printf("Error: eglChooseConfig(): config not found.\n");
exit(-1);
}
EGLint pbufferAttribs[5];
pbufferAttribs[0] = EGL_WIDTH;
pbufferAttribs[1] = renderBufferWidth;
pbufferAttribs[2] = EGL_HEIGHT;
pbufferAttribs[3] = renderBufferHeight;
pbufferAttribs[4] = EGL_NONE;
// Step 6 - Create a surface to draw to.
EGLSurface eglSurface;
eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, pbufferAttribs);
if (eglSurface == EGL_NO_SURFACE)
{
qDebug() << "surface error";
exit(1);
}
// Step 7 - Create a context.
EGLContext eglContext;
eglContext = eglCreateContext(eglDisplay, eglConfig, NULL,
ai32ContextAttribs);
if (eglContext == EGL_NO_CONTEXT)
{
qDebug() << "context error";
exit(1);
}
// Step 8 - Bind the context to the current thread
bool result = eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
if (!result)
{
qDebug() << "make current error" << eglGetError();
}
GLuint programObject;
{ //init
char* vShaderStr =
"attribute vec4 vPosition; \n"
"void main() \n"
"{ \n"
" gl_Position = vPosition; \n"
"} \n";
char* fShaderStr =
"precision mediump float; \n"
"void main() \n"
"{ \n"
" gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n"
"} \n";
GLuint vertexShader;
GLuint fragmentShader;
GLint linked;
// Load the vertex/fragment shaders
vertexShader = LoadShader(vShaderStr, GL_VERTEX_SHADER);
fragmentShader = LoadShader(fShaderStr, GL_FRAGMENT_SHADER);
// Create the program object
programObject = glCreateProgram();
if(programObject == 0)
return 0;
glAttachShader(programObject, vertexShader);
glAttachShader(programObject, fragmentShader);
// Bind vPosition to attribute 0
glBindAttribLocation(programObject, 0, "vPosition");
// Link the program
glLinkProgram(programObject);
// Check the link status
glGetProgramiv(programObject, GL_LINK_STATUS, &linked);
if(!linked)
{
GLint infoLen = 0;
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen);
if(infoLen > 1)
{
char* infoLog = (char*)malloc(sizeof(char) * infoLen);
glGetProgramInfoLog(programObject, infoLen, NULL, infoLog);
qDebug() <<"Error linking program:" << infoLog;
free(infoLog);
}
glDeleteProgram(programObject);
}
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
}
{//draw
GLfloat vVertices[] = {0.0f, 1.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f};
// Set the viewport
glViewport(0, 0, 1920, 1080);
// Clear the color buffer
glClear(GL_COLOR_BUFFER_BIT);
// Use the program object
glUseProgram(programObject);
// Load the vertex data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
int size = 4 * renderBufferHeight * renderBufferWidth;
unsigned char *data2 = new unsigned char[size];
eglSwapBuffers( eglDisplay, eglSurface);
glReadPixels(0,0,renderBufferWidth,renderBufferHeight,GL_RGBA, GL_UNSIGNED_BYTE, data2);
qDebug() << glGetError() << eglGetError();
QImage saveImage(data2, renderBufferWidth, renderBufferHeight, QImage::Format_RGBA8888_Premultiplied);
saveImage.save("haha.png");
QCoreApplication a(argc, argv);
qDebug() << "done";
return a.exec();
}
答案 0 :(得分:0)
今天,我在装有NVIDIA显卡和专有驱动程序的机器上运行了相同的程序。
事实证明代码运行良好。这可能是英特尔司机的错误。