- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我需要将 3d 模型渲染成多个 View ,并且图像尺寸比屏幕分辨率大得多,所以我无法打开这么大的窗口,也不需要打开窗口来查看渲染结果。我只想将 3d 模型渲染成许多具有不同视点的图像。
我找到这个教程,http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/ ,我尝试使用 glGetTexImage 和 glReadPixels 从 fbo 读取像素值。
问题是如果窗口没有被隐藏,就OK了。如果我使用
设置隐藏窗口glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
我只能使用 glGetTexImage 或 glReadPixels 从 fbo 读取背景颜色。并且使用 glDrawElements 绘制的模型消失了。
任何人都可以帮助我或给我举个例子吗?谢谢!
这是我读取 fbo 的代码:(如果窗口没有隐藏,它工作得很好,我的代码的其余部分与 http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/ 相同)
这是我的代码:
if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW\n");
getchar();
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 1);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_VISIBLE, GL_TRUE);
// Open a window and create its OpenGL context
int windowWidth = 4000;
int windowHeight = 3000;
window = glfwCreateWindow(windowWidth, windowHeight, "Tutorial 14 - Render To Texture", NULL, NULL);
if (window == NULL) {
fprintf(stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n");
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
getchar();
glfwTerminate();
return -1;
}
// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
// Hide the mouse and enable unlimited mouvement
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// Set the mouse at the center of the screen
glfwPollEvents();
glfwSetCursorPos(window, windowWidth / 2, windowHeight / 2);
// Dark blue background
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Enable depth test
glEnable(GL_DEPTH_TEST);
// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);
// Cull triangles which normal is not towards the camera
glEnable(GL_CULL_FACE);
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders("StandardShadingRTT.vertexshader", "StandardShadingRTT.fragmentshader");
// Get a handle for our "MVP" uniform
GLuint MatrixID = glGetUniformLocation(programID, "MVP");
GLuint ViewMatrixID = glGetUniformLocation(programID, "V");
GLuint ModelMatrixID = glGetUniformLocation(programID, "M");
// Load the texture
GLuint Texture = loadDDS("uvmap.DDS");
// Get a handle for our "myTextureSampler" uniform
GLuint TextureID = glGetUniformLocation(programID, "myTextureSampler");
// Read our .obj file
std::vector<glm::vec3> vertices;
std::vector<glm::vec2> uvs;
std::vector<glm::vec3> normals;
bool res = loadOBJ("suzanne.obj", vertices, uvs, normals);
std::vector<unsigned short> indices;
std::vector<glm::vec3> indexed_vertices;
std::vector<glm::vec2> indexed_uvs;
std::vector<glm::vec3> indexed_normals;
indexVBO(vertices, uvs, normals, indices, indexed_vertices, indexed_uvs, indexed_normals);
// Load it into a VBO
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, indexed_vertices.size() * sizeof(glm::vec3), &indexed_vertices[0], GL_STATIC_DRAW);
GLuint uvbuffer;
glGenBuffers(1, &uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glBufferData(GL_ARRAY_BUFFER, indexed_uvs.size() * sizeof(glm::vec2), &indexed_uvs[0], GL_STATIC_DRAW);
GLuint normalbuffer;
glGenBuffers(1, &normalbuffer);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glBufferData(GL_ARRAY_BUFFER, indexed_normals.size() * sizeof(glm::vec3), &indexed_normals[0], GL_STATIC_DRAW);
// Generate a buffer for the indices as well
GLuint elementbuffer;
glGenBuffers(1, &elementbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned short), &indices[0], GL_STATIC_DRAW);
// Get a handle for our "LightPosition" uniform
glUseProgram(programID);
GLuint LightID = glGetUniformLocation(programID, "LightPosition_worldspace");
// ---------------------------------------------
// Render to Texture - specific code begins here
// ---------------------------------------------
// The framebuffer, which regroups 0, 1, or more textures, and 0 or 1 depth buffer.
GLuint FramebufferName = 0;
glGenFramebuffers(1, &FramebufferName);
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
// The texture we're going to render to
GLuint renderedTexture;
glGenTextures(1, &renderedTexture);
// "Bind" the newly created texture : all future texture functions will modify this texture
glBindTexture(GL_TEXTURE_2D, renderedTexture);
// Give an empty image to OpenGL ( the last "0" means "empty" )
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, windowWidth, windowHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
// Poor filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Set "renderedTexture" as our colour attachement #0
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, renderedTexture, 0);
// Set the list of draw buffers.
GLenum DrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
glDrawBuffers(1, DrawBuffers); // "1" is the size of DrawBuffers
// Always check that our framebuffer is ok
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
return false;
// Render to our framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
glViewport(0, 0, windowWidth, windowHeight); // Render on the whole framebuffer, complete from the lower left corner to the upper right
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use our shader
glUseProgram(programID);
// Compute the MVP matrix from keyboard and mouse input
computeMatricesFromInputs();
glm::mat4 ProjectionMatrix = getProjectionMatrix();
glm::mat4 ViewMatrix = getViewMatrix();
glm::mat4 ModelMatrix = glm::mat4(1.0);
glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;
// Send our transformation to the currently bound shader,
// in the "MVP" uniform
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix[0][0]);
glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]);
glm::vec3 lightPos = glm::vec3(4, 4, 4);
glUniform3f(LightID, lightPos.x, lightPos.y, lightPos.z);
// Bind our texture in Texture Unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Texture);
// Set our "myTextureSampler" sampler to user Texture Unit 0
glUniform1i(TextureID, 0);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// 2nd attribute buffer : UVs
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glVertexAttribPointer(
1, // attribute
2, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// 3rd attribute buffer : normals
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glVertexAttribPointer(
2, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Index buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
// Draw the triangles !
glDrawElements(
GL_TRIANGLES, // mode
indices.size(), // count
GL_UNSIGNED_SHORT, // type
(void*)0 // element array buffer offset
);
unsigned char *image = new unsigned char[windowWidth * windowHeight * 3];
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glReadPixels(0, 0, windowWidth, windowHeight, GL_RGB, GL_UNSIGNED_BYTE, image);
cv::Mat img;
img = cv::Mat::zeros(windowHeight, windowWidth, CV_8UC3);
for (int i = 0; i < windowHeight; i ++) {
for (int j = 0; j < windowWidth; j ++) {
int index = (i * windowWidth + j) * 3;
cv::Vec3b px;
px.val[0] = image[index + 0];
px.val[1] = image[index + 1];
px.val[2] = image[index + 2];
img.at<cv::Vec3b>(i, j) = px;
}
}
cv::imwrite("test.png", img);
当窗口可见时效果很好
glfwWindowHint(GLFW_VISIBLE, GL_FALSE);
但是如果我把它设置为GL_TRUE,我就不能再得到结果了!
谁能帮帮我?非常感谢!
最佳答案
你检查过这个例子了吗?它使用帧缓冲区
https://www.opengl.org/wiki/Framebuffer_Object_Examples#Quick_example.2C_render_to_texture_.282D.29
下面的代码(以防将来链接断开):
//RGBA8 2D texture, 24 bit depth texture, 256x256
glGenTextures(1, &color_tex);
glBindTexture(GL_TEXTURE_2D, color_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//NULL means reserve texture memory, but texels are undefined
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
//-------------------------
glGenFramebuffersEXT(1, &fb);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
//Attach 2D texture to this FBO
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, color_tex, 0);
//-------------------------
glGenRenderbuffersEXT(1, &depth_rb);
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, depth_rb);
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, 256, 256);
//-------------------------
//Attach depth buffer to FBO
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depth_rb);
//-------------------------
//Does the GPU support current FBO configuration?
GLenum status;
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
switch(status)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
cout<<"good";
default:
HANDLE_THE_ERROR;
}
//-------------------------
//and now you can render to GL_TEXTURE_2D
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//-------------------------
glViewport(0, 0, 256, 256);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 256.0, 0.0, 256.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//-------------------------
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
//-------------------------
//**************************
//RenderATriangle, {0.0, 0.0}, {256.0, 0.0}, {256.0, 256.0}
//Read http://www.opengl.org/wiki/VBO_-_just_examples
RenderATriangle();
//-------------------------
GLubyte pixels[4*4*4];
glReadPixels(0, 0, 4, 4, GL_BGRA, GL_UNSIGNED_BYTE, pixels);
//pixels 0, 1, 2 should be white
//pixel 4 should be black
//----------------
//Bind 0, which means render to back buffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
代码清理:
//Delete resources
glDeleteTextures(1, &color_tex);
glDeleteRenderbuffersEXT(1, &depth_rb);
//Bind 0, which means render to back buffer, as a result, fb is unbound
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDeleteFramebuffersEXT(1, &fb);
关于c++ - OpenGL 离屏渲染和使用 glfw 的隐藏窗口读取像素值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37558512/
GLFW 首字母缩写词代表什么? http://www.glfw.org/是主要网站,但我在那里找不到任何线索。 Evenhere on SO 它有一个标签,但在描述中没有解释首字母缩略词。 最佳答案
我正尝试在我的 mac 上使用 xcode 使用 glfw 2.7.5,但出现以下错误: Undefined symbols for architecture i386: "_glfwGetKey
当我们必须运行多线程glfw应用程序时,如果在MainProcess中调用了glfw.create_window(),程序将停止。 这基本上是更大代码的一部分,我无法更改架构(包括多处理架构),但这是
如何使用 glfw 检测小写字母?我可以检测大写字母。例如, if ( key == 'A' && action == GLFW_PRESS ) std::cout << (char)
如何使用 glfw 检测小写字母?我可以检测大写字母。例如, if ( key == 'A' && action == GLFW_PRESS ) std::cout << (char)
我正在尝试将 GLFW 用于学校项目,并遵循了以下步骤: 1) 从 glfw.org 下载 win32 zip 2) 将/include 添加到我的解决方案的 includes 3) 将/lib-ms
我已经完成了以下视频 https://www.youtube.com/watch?v=shpdt6hCsT4 但是,我的世界窗口看起来像这样: http://s1303.photobucket.com
当我使用 GLFW 创建窗口(在 Windows 操作系统上)并通过 glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, 1); 将 GLFW_TRANSPARE
我一直在试图让我的窗口可拖动。 这是我的代码, #include #include #include #include "include/GLFW/glfw3.h" void cursor_po
我在识别我机器上的 GLFW 库的代码块 10.05 时遇到了一些困难。当我创建一个空项目并复制粘贴此 GLFW 教程中的代码时 >> http://content.gpwiki.org/index.
在我寻找跨平台框架/库的过程中,GLFW 被多次提及。所以,我决定尝试一下。现在,似乎我什至无法启动窗口。 :-/ #include #include #include int main(int ar
我想将 OpenGL 图形绘制到多个窗口中。据我所知,所有窗口都“通向”同一个“世界”: 在窗口之间共享上下文。这对 GLFW 来说是非常简单的任务,我在这方面取得了一些进展,但是,代码变得越来越模糊
最近我开始了一个涉及 GLFW(64 位,带有 GLEW)的项目。但是,我似乎无法让它正确链接。我的设置方式如下: 操作系统:Windows 8 64位 编译器:mingw64 集成开发环境:ecli
我想将 OpenGL 图形绘制到多个窗口中。据我所知,所有窗口都“通向”同一个“世界”: 在窗口之间共享上下文。这对 GLFW 来说是非常简单的任务,我在这方面取得了一些进展,但是,代码变得越来越模糊
标题已经说明了一切。使用 C 语言的 GLFW 库,我怎样才能防止窗口宽度低于 20 像素,或者 10。怎样才能防止高度不超过 100?我尝试为窗口大小调整时创建一个回调函数,如下所示: void w
所以基本上是从页面上的教程学习 OpenGL 和 GLFW 库:http://www.opengl-tutorial.org/beginners-tutorials/tutorial-6-keyboa
我正在用 OpenGL 和 GLFW 编写游戏引擎。但是,不知何故我的窗口无法关闭。我尝试了很多东西,但没有效果。我的代码有什么问题? 我找不到其中的错误 - 我觉得一切都很好。 代码: int ru
我在创建 GLFW 窗口时遇到了一些问题。我想要一个能够在窗口模式和全屏模式之间切换的程序。要在 GLFW 2.7.8 中执行此操作,必须首先销毁事件窗口,然后创建一个新窗口。我读到 3.0 版支持多
在 GLFW 中设置回调函数时要使用什么数据类型? 我尝试设置一个函数来键入 void,但给我一个编译错误。将其更改为 void __stdcall 会给我一个 RT 错误,但我如何使用 GLFW 的
为了让结果保持打开状态(窗口屏幕),我必须执行以下操作: while (glfwGetWindowParam(GLFW_OPENED)) { // do some stuff glDr
我是一名优秀的程序员,十分优秀!