为了创造一种屏保 我希望能够:
我可以轻松地做到这一点,但效率不高。事实上,我必须再次进行所有初始化(上下文创建,vao,vbo,编译着色器......),我不重用任何东西。 如果窗口刚刚被用户隐藏,那就好了,但显然,你不能用GLFW隐藏全屏窗口。
有谁知道什么可以安全再次使用,以及如何使用?
也许代码(不重新打开新窗口)可以帮助您回答我的问题:
...
int main (int argc, char *argv[])
{
GLFWwindow* window;
const GLFWvidmode *mode;
GLenum glew_status;
float vertices[] = {
-1.0f, 1.0f,
1.0f, 1.0f,
-1.0f, -1.0f,
1.0f, -1.0f
};
GLuint vao;
GLuint vbo;
GLuint vertexShader;
GLuint fragmentShader;
GLuint shaderProgram;
GLint posAttrib;
GLint Resolution;
GLint Time;
glfwSetErrorCallback(error_callback);
if (!glfwInit())
return 1;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
window = glfwCreateWindow(mode->width, mode->height, "OpenGL", glfwGetPrimaryMonitor(), NULL); // Fullscreen
if (!window) {
glfwTerminate();
return 2;
}
glfwMakeContextCurrent(window);
glfwSetKeyCallback(window, key_callback);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetInputMode(window,GLFW_CURSOR,GLFW_CURSOR_HIDDEN);
// Initialize GLEW
glewExperimental = GL_TRUE;
glew_status = glewInit();
if (glew_status != GLEW_OK) {
//Problem: glewInit failed, something is seriously wrong.
fprintf(stderr,"glewInit failed, Error: %s\n", glewGetErrorString(glew_status));
return 3;
}
// Create Vertex Array Object
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create a Vertex Buffer Object and copy the vertex data to it
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Create and compile the vertex shader
vertexShader = LoadShader("/home/celestin/Documents/C/OpenGL/my_openGL/simple_shader/triangle.v.glsl",GL_VERTEX_SHADER);
fragmentShader = LoadShader("/home/celestin/Documents/C/OpenGL/my_openGL/simple_shader/triangle.f.glsl",GL_FRAGMENT_SHADER);
// Link the vertex and fragment shader into a shader program
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
// Specify the layout of the vertex data
posAttrib = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
Resolution = glGetUniformLocation(shaderProgram, "resolution");
Time = glGetUniformLocation(shaderProgram, "time");
// Clear the screen to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glfwSetTime(0.0);
// Loop until the user closes the window
while (!glfwWindowShouldClose(window))
{
glUniform1f(Time,glfwGetTime());
glUniform2f(Resolution,mode->width,mode->height);
glClear(GL_COLOR_BUFFER_BIT);
// Draw a triangle from the 3 vertices
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Swap front and back buffers
glfwSwapBuffers(window);
// Poll for and process events
glfwPollEvents();
}
glDeleteProgram(shaderProgram);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
答案 0 :(得分:0)
确实无法创建最初隐藏的全屏GLFW窗口。但是,如果您使用的是足够现代的OpenGL,您可以假设支持framebuffer对象,则可以使用隐藏的窗口模式窗口渲染到纹理。窗口默认帧缓冲区的大小无关紧要。
如果您想在窗口之间等待,可以将此纹理的图像数据保存到RAM中并保留以供日后使用。
如果你不介意生命重叠,你可以通过上下文共享将这个纹理分享到新窗口的上下文中。这是通过glfwCreateWindow
的最后一个参数完成的。上下文共享还将承载许多其他对象类型:
可以在上下文之间共享的对象包括缓冲对象,程序 和着色器对象,渲染缓冲对象,采样器对象,同步对象和纹理 对象(名为零的纹理对象除外)。 - OpenGL 4.5 Specification, chapter 5