gpt4 book ai didi

opengl-es-2.0 - 用于 FBO 渲染的 OpenGL ES2.0 离屏上下文

转载 作者:行者123 更新时间:2023-12-04 08:49:44 56 4
gpt4 key购买 nike

我想使用 FBO 进行离屏渲染(在没有任何 WS 的控制台环境中)。
我知道有必要为任何操作创建一个 OpenGL 上下文,并且至少有一个虚拟窗口,因此我做了以下初始化:

// Step 1 - Get the default display.
eglDisplay = eglGetDisplay((EGLNativeDisplayType)0);

// Step 2 - Initialize EGL.
EGLint iMajorVersion, iMinorVersion;
if (!eglInitialize(eglDisplay, &iMajorVersion, &iMinorVersion))
{
printf("Error: eglInitialize() failed.\n");
goto cleanup;
}

// Step 3 - Make OpenGL ES the current API.
eglBindAPI(EGL_OPENGL_ES_API);
if (!TestEGLError("eglBindAPI"))
{
goto cleanup;
}

// Step 4 - Specify the required configuration attributes.
EGLint pi32ConfigAttribs[5];
pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
pi32ConfigAttribs[4] = EGL_NONE;

// Step 5 - Find a config that matches all requirements.
int iConfigs;
if (!eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1))
{
printf("Error: eglChooseConfig() failed.\n");
goto cleanup;
}

// Step 6 - Create a surface to draw to.
EGLSurface eglSurface;
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (EGLNativeWindowType)NULL, NULL);
if (!TestEGLError("eglCreateWindowSurface")) goto cleanup;

// Step 7 - Create a context.
eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, ai32ContextAttribs);
if (!TestEGLError("eglCreateContext")) goto cleanup;

// Step 8 - Bind the context to the current thread
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
if (!TestEGLError("eglMakeCurrent")) goto cleanup;

这种类型的初始化适用于目标系统,但是如果我在 FBO 中绘制一些东西,并且在读取它之后 (getReadPixels) 总是只能得到一个黑色图像。
我在 X11 上面尝试了相同的代码,它(已经)在 eglCreateWindowSurface 调用失败并出现错误:EGL_BAD_NATIVE_WINDOW WORKS,但如果我传递给这个调用一个真正的 X11window native 窗口处理程序,它就可以工作(这种情况下我可以读回有效的渲染图像还)

请澄清我应该使用什么类型的表面来进行 FBO 渲染?
或者我做错了什么?

其余的绘图代码:
//初始化并启动opengl es shanders
Shaders_Init();
{
// create a framebuffer object
glGenFramebuffers(1, &fboId);
glBindFramebuffer(GL_FRAMEBUFFER, fboId);

// create a texture object
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //GL_LINEAR_MIPMAP_LINEAR
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_HINT, GL_TRUE); // automatic mipmap
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, renderBufferWidth, renderBufferHeight, 0,
GL_RGB, GL_UNSIGNED_BYTE, 0);
//glBindTexture(GL_TEXTURE_2D, 0);


// attach the texture to FBO color attachment point
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, textureId, 0);

// check FBO status
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE) {
printf("Problem with OpenGL framebuffer after specifying color render buffer: \n%x\n", status);
} else {
printf("FBO creation succedded\n");
}
}





// Sets the clear color.
// The colours are passed per channel (red,green,blue,alpha) as float values from 0.0 to 1.0
glClearColor(0.6f, 0.8f, 1.0f, 1.0f); // clear blue

// We're going to draw a triangle to the screen so create a vertex buffer object for our triangle
{
// Interleaved vertex data
GLfloat afVertices[] = { -0.4f,-0.4f,0.0f, // Position
0.4f ,-0.4f,0.0f,
0.0f ,0.4f ,0.0f};
// Generate the vertex buffer object (VBO)
glGenBuffers(1, &ui32Vbo);

// Bind the VBO so we can fill it with data
glBindBuffer(GL_ARRAY_BUFFER, ui32Vbo);

// Set the buffer's data
unsigned int uiSize = 3 * (sizeof(GLfloat) * 3); // Calc afVertices size (3 vertices * stride (3 GLfloats per vertex))
glBufferData(GL_ARRAY_BUFFER, uiSize, afVertices, GL_STATIC_DRAW);
}

// Draw a triangle
{
glClear(GL_COLOR_BUFFER_BIT);
if (!TestEGLError("glClear")) goto cleanup;



// First gets the location of that variable in the shader using its name
int i32Location = glGetUniformLocation(uiProgramObject, "myPMVMatrix");

// Then passes the matrix to that variable
glUniformMatrix4fv( i32Location, 1, GL_FALSE, pfIdentity);

/*
Enable the custom vertex attribute at index VERTEX_ARRAY.
We previously binded that index to the variable in our shader "vec4 MyVertex;"
*/
glEnableVertexAttribArray(VERTEX_ARRAY);

// Sets the vertex data to this attribute index
glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, 0);

/*
Draws a non-indexed triangle array from the pointers previously given.
This function allows the use of other primitive types : triangle strips, lines, ...
For indexed geometry, use the function glDrawElements() with an index list.
*/
glDrawArrays(GL_TRIANGLES, 0, 3);
if (!TestEGLError("glDrawArrays")) goto cleanup;

// get the image data
long imageSize = x * y * 3;
unsigned char *data = new unsigned char[imageSize];
glReadPixels(0,0,x,y,GL_RGB,GL_UNSIGNED_BYTE,data);

提前致谢!!!!!
问候,
格萨

最佳答案

解决方案如下(没有错误处理):

    #ifdef CONTEXT_ES20
EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE };
#endif

// Step 1 - Get the default display.
eglDisplay = eglGetDisplay((EGLNativeDisplayType)0);

// Step 2 - Initialize EGL.
eglInitialize(eglDisplay, 0, 0);

#ifdef CONTEXT_ES20
// Step 3 - Make OpenGL ES the current API.
eglBindAPI(EGL_OPENGL_ES_API);

// Step 4 - Specify the required configuration attributes.
EGLint pi32ConfigAttribs[5];
pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
pi32ConfigAttribs[4] = EGL_NONE;
#else
EGLint pi32ConfigAttribs[3];
pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
pi32ConfigAttribs[2] = EGL_NONE;
#endif

// Step 5 - Find a config that matches all requirements.
int iConfigs;
eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1,
&iConfigs);

if (iConfigs != 1) {
printf("Error: eglChooseConfig(): config not found.\n");
exit(-1);
}

// Step 6 - Create a surface to draw to.
EGLSurface eglSurface;
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig,
(EGLNativeWindowType)NULL, NULL);

// Step 7 - Create a context.
#ifdef CONTEXT_ES20
eglContext = eglCreateContext(eglDisplay, eglConfig, NULL,
ai32ContextAttribs);
#else
eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, NULL);
#endif

// Step 8 - Bind the context to the current thread
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);

关于opengl-es-2.0 - 用于 FBO 渲染的 OpenGL ES2.0 离屏上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12662227/

56 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com