我正在尝试用opengl绘制纹理。
我发现这个简单明了的c代码可以做到这一点(见最后)。 它在纹理上绘制一个立方体,然后使用前一个纹理在屏幕上绘制一个立方体。生成的图像是一个立方体,在纹理中,立方体内的立方体内有很多立方体等。:它似乎是一个递归循环。
但为什么呢?我只期待2个立方体。它似乎是一个无限的递归循环..实际的递归在哪里?什么时候停止?
/* ============================================================================
**
** Demonstration of rendering to texture
** Copyright (C) 2005 Julien Guertault
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation; either version 2
** of the License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** ========================================================================= */
#include <stdio.h>
#include <stdlib.h>
#include <GL/glut.h>
#include <math.h>
#define SIZE 256
static unsigned char texture[3 * SIZE * SIZE];
static unsigned int texture_id;
static int window_width = 500;
static int window_height = 500;
/*
** Just a textured cube
*/
void Cube(void)
{
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex3f(-1, -1, -1);
glTexCoord2i(0, 1); glVertex3f(-1, -1, 1);
glTexCoord2i(1, 1); glVertex3f(-1, 1, 1);
glTexCoord2i(1, 0); glVertex3f(-1, 1, -1);
glTexCoord2i(0, 0); glVertex3f( 1, -1, -1);
glTexCoord2i(0, 1); glVertex3f( 1, -1, 1);
glTexCoord2i(1, 1); glVertex3f( 1, 1, 1);
glTexCoord2i(1, 0); glVertex3f( 1, 1, -1);
glTexCoord2i(0, 0); glVertex3f(-1, -1, -1);
glTexCoord2i(0, 1); glVertex3f(-1, -1, 1);
glTexCoord2i(1, 1); glVertex3f( 1, -1, 1);
glTexCoord2i(1, 0); glVertex3f( 1, -1, -1);
glTexCoord2i(0, 0); glVertex3f(-1, 1, -1);
glTexCoord2i(0, 1); glVertex3f(-1, 1, 1);
glTexCoord2i(1, 1); glVertex3f( 1, 1, 1);
glTexCoord2i(1, 0); glVertex3f( 1, 1, -1);
glTexCoord2i(0, 0); glVertex3f(-1, -1, -1);
glTexCoord2i(0, 1); glVertex3f(-1, 1, -1);
glTexCoord2i(1, 1); glVertex3f( 1, 1, -1);
glTexCoord2i(1, 0); glVertex3f( 1, -1, -1);
glTexCoord2i(0, 0); glVertex3f(-1, -1, 1);
glTexCoord2i(0, 1); glVertex3f(-1, 1, 1);
glTexCoord2i(1, 1); glVertex3f( 1, 1, 1);
glTexCoord2i(1, 0); glVertex3f( 1, -1, 1);
glEnd();
}
/*
** Function called to update rendering
*/
void DisplayFunc(void)
{
static float alpha = 20;
glLoadIdentity();
glTranslatef(0, 0, -10);
glRotatef(alpha, 1, 0, 0);
glRotatef(20 , 0, 1, 0);
/* Define a view-port adapted to the texture */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(20, 1, 5, 15);
glViewport(0, 0, SIZE, SIZE);
glMatrixMode(GL_MODELVIEW);
/* Render to buffer */
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Cube();
glFlush();
/* Copy buffer to texture */
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 5, 5, 0, 0, SIZE - 10, SIZE - 10);
/* Render to screen */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(20, window_width / (float) window_height, 5, 15);
glViewport(0, 0, window_width, window_height);
glMatrixMode(GL_MODELVIEW);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Cube();
/* End */
glFlush();
glutSwapBuffers();
/* Update again and again */
alpha = alpha + 0.1;
glutPostRedisplay();
}
/*
** Function called when the window is created or resized
*/
void ReshapeFunc(int width, int height)
{
window_width = width;
window_height = height;
glutPostRedisplay();
}
/*
** Function called when a key is hit
*/
void KeyboardFunc(unsigned char key, int x, int y)
{
int foo;
foo = x + y; /* Has no effect: just to avoid a warning */
printf("%d",foo);
if ('q' == key || 'Q' == key || 27 == key)
exit(0);
}
int main(int argc, char **argv)
{
/* Creation of the window */
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutCreateWindow("Render to texture");
/* OpenGL settings */
glEnable(GL_DEPTH_TEST);
/* Texture setting */
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SIZE, SIZE, 0, GL_RGB,
GL_UNSIGNED_BYTE, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
/* Declaration of the callbacks */
glutDisplayFunc(&DisplayFunc);
glutReshapeFunc(&ReshapeFunc);
glutKeyboardFunc(&KeyboardFunc);
/* Loop */
glutMainLoop();
/* Never reached */
return 0;
}
/* ========================================================================= */
答案 0 :(得分:0)
但为什么呢?我只期待2个立方体。它似乎是一个无限的递归循环..实际的递归在哪里?什么时候停止?
这是一个反馈循环。小实验:将网络摄像头连接到计算机,让它显示网络摄像头的实时图片。现在将网络摄像头指向屏幕,以便它查看它产生的图像。
这就是这里发生的事情:绘制具有纹理的立方体。该图片现在被复制到纹理中。然后再次绘制立方体,但这次纹理已经包含该立方体,因此它是一个立方体,上面有立方体。此外,为了您的乐趣,同一个立方体被绘制到屏幕上,但不会反馈。
如果您希望深度嵌套,则必须在绘制复制到纹理的多维数据集时禁用纹理。
void DisplayFunc(void)
{
首先渲染没有纹理所以我们不反馈。同时使绘图颜色变黑,这样会在黑色背景上产生坚固的黑色立方体。
/* Render to buffer */
glClearColor(1, 1, 1, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_TEXTURE_2D); /* <<<<<< */
glColor3f(0,0,0); /* <<<<<< */
Cube();
旁注:为此,应该使用帧缓冲区对象,而不是依靠后台缓冲区来防止(重叠窗口可能会使像素所有权测试失败)。
/* Copy buffer to texture */
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 5, 5, 0, 0, SIZE-10, SIZE-10);
/* Render to screen */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(20, window_width / (float) window_height, 5, 15);
glViewport(0, 0, window_width, window_height);
glMatrixMode(GL_MODELVIEW);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
重新启用纹理并将颜色切换为白色,以便我们可以看到纹理(或使用GL_REPLACE纹理模式)。
glEnable(GL_TEXTURE_2D);
glColor3f(1,1,1);
Cube();
/* End */
glFlush();
glutSwapBuffers();
/* Update again and again */
alpha = alpha + 0.1;
glutPostRedisplay();
}