⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpu_util.c

📁 游戏编程精粹6第中关于粒子的实时流体仿真系统,对入门的游戏开发者很有帮助.
💻 C
📖 第 1 页 / 共 2 页
字号:
	for (y = 0; y < height; y++)
		for (x = 0; x < width; x++)
		{
			index = 4*(x + y*width);
			switch (n_components)
			{
			case 1:
				gput_printf("(%d, %d); x=%e\n", 
					x + x0, y + y0, buf[index]);
				break;
			case 2:
				gput_printf("(%d, %d); x=%e, y=%e\n", 
					x + x0, y + y0, buf[index], buf[index + 1]);
				break;
			case 3:
				gput_printf("(%d, %d); x=%.4f, y=%.4f, z=%.4f\n", 
					x + x0, y + y0, buf[index], buf[index + 1], buf[index + 2]);
				break;
			case 4:
				gput_printf("(%d, %d); x=%e, y=%e, z=%e w=%e\n", 
					x + x0, y + y0, buf[index], buf[index + 1], buf[index + 2], buf[index + 3]);
				break;
			}
		}

	check_gl_error();

	//gput_pbuffer_end(pbuf);
	free(buf);
}


void DrawQuad(int w, int h, int tw, int th)
{
    glBegin(GL_QUADS);
    glTexCoord2f(0,         0);         glVertex2f(0,        0);
    glTexCoord2f((float)tw, 0);         glVertex2f((float)w, 0);
    glTexCoord2f((float)tw, (float)th); glVertex2f((float)w, (float) h);
    glTexCoord2f(0,         (float)th); glVertex2f(0,        (float) h);
    glEnd();
}



#ifndef NO_NVCG
void gput_set_transferfp(CGprogram fp)
{
	passthru = fp;
}
#endif

void gput_pbuffer_float_set(gput_pbuffer* buf, int width, int height, void* pixels)
{
	gput_context c;

	gput_context_get_current(&c);
	gput_pbuffer_activate(buf);
	

#ifndef NO_NVCG
	cgGLBindProgram(passthru);
	cgGLEnableProfile(CG_PROFILE_FP30);
	glActiveTextureARB(GL_TEXTURE0_ARB);
    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_FLOAT_RGB_NV, width, height, 0, GL_RGB, GL_FLOAT, pixels);
    DrawQuad(width, height, width, height);
    cgGLDisableProfile(CG_PROFILE_FP30);
#endif
	//gput_pbuffer_end(buf);

	gput_context_activate(&c);
}






GLuint gput_create_float_buffer(GLint internalformat, GLsizei width, GLsizei height, GLenum format, void* pixels)
{
	GLuint tex;

	glGenTextures(1, &tex);
//	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);

	glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, internalformat,
		width, height, 0, format, GL_FLOAT, pixels);

	/*
	glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_FLOAT_R32_NV,
		width, height, 0, GL_RGB, GL_FLOAT, pixels);
*/
	check_gl_error();
	
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);

	return tex;
}

void gput_bind_float_buffer(GLuint tex)
{
	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex);
}


void gput_intlist_create(gput_intlist* l)
{
	l->size = 0;
	l->cap = 10;
	l->array = (GLint*)malloc(l->cap*sizeof(GLint));
}

void gput_intlist_pushpair(gput_intlist* l, GLint i0, GLint i1)
{
	if (l->cap < (l->size + 2))
	{
		GLint* newarray;

		newarray = (GLint*)malloc(2*l->cap*sizeof(GLint));
		l->cap *= 2;
		memcpy(newarray, l->array, l->size*sizeof(GLint));
		free(l->array);
		l->array = newarray;
	}

	l->array[l->size] = i0;
	l->array[l->size + 1] = i1;
	l->size += 2;
}

void gput_intlist_push(gput_intlist* l, GLint i)
{
	if (l->cap == l->size)
	{
		GLint* newarray;

		newarray = (GLint*)malloc(2*l->cap*sizeof(GLint));
		l->cap *= 2;
		memcpy(newarray, l->array, l->size*sizeof(GLint));
		free(l->array);
		l->array = newarray;
	}

	l->array[l->size] = i;
	l->size++;
}


void gput_intlist_destroy(gput_intlist* l)
{
	free(l->array);
}

void gput_pbuffer_create_array(gput_pbuffer* buf, GLenum target, int width, int height,
							   const GLint* iattr, const GLint* pattr)
{
	unsigned int pformats[MAX_FORMATS];
	GLuint nformat;
	HDC hdc;

	const float fattriblist[] =
	{
		0
	};

	hdc = wglGetCurrentDC();

	if (!hdc) 
	{
		gput_printf("unable to get current device context\n");
		return;
	}

	if (!wglChoosePixelFormatARB(hdc, iattr, fattriblist, MAX_FORMATS, pformats, &nformat)) 
	{
		gput_printf("can't choose pixel format\n");
		return;
	}
	

	buf->hpbuf = wglCreatePbufferARB(hdc, pformats[0], width, height, pattr);
	
	if (!buf->hpbuf) {
		gput_printf("can't create pbuffer\n");
		return;
	}

	buf->hdc = wglGetPbufferDCARB(buf->hpbuf);
	if (!buf->hdc) {
		gput_printf("can't get pbuffer device context.\n");
		return;
	}

	buf->hglrc = wglCreateContext(buf->hdc);
	if (!buf->hglrc) {
		gput_printf("can't create context for pbuffer.\n");
		return;
	}

	/* Share OpenGL context between pbuffer & window */
	wglShareLists(wglGetCurrentContext(), buf->hglrc);
	//buf->hglrc = wglGetCurrentContext();

	buf->target = target;

	//wglGetLastError();
	check_gl_error();
}

void gput_pbuffer_cubemap_create(gput_pbuffer* buf, int width, int height)
{
	GLint iattr[] = {
		WGL_DRAW_TO_PBUFFER_ARB, GL_TRUE,
		WGL_BIND_TO_TEXTURE_RGB_ARB, GL_TRUE,
		WGL_DOUBLE_BUFFER_ARB, GL_FALSE,
		0
	};
	GLint pattr[] = {
		WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGB_ARB,
		WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_CUBE_MAP_ARB,
		0
	};

	gput_pbuffer_create_array(buf, GL_TEXTURE_CUBE_MAP_ARB, width, height, iattr, pattr);
	glGenTextures(1, &buf->tex);
	glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, buf->tex);
	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
}

void gput_pbuffer_create(gput_pbuffer* buf, GLenum target, int width, int height, ...)
{
#define MAX_PBUF_PARAM 10
	va_list list;
	int n_attr;
	int count;
	GLint iattr[2*MAX_PBUF_PARAM + 1];
	GLint pattr[2*MAX_PBUF_PARAM + 1];
	GLint* attr;

	n_attr = 0;
	count = 0;
	attr = iattr;
	va_start(list, height);
	for (;;)
	{
		GLint type;
		GLint value;
		
		type = va_arg(list, GLint);
		if (type == 0)
		{
			attr[2*count] = 0;
			if (n_attr == 0)
			{
				n_attr++;
				count = 0;
				attr = pattr;
				continue;
			}
			else break;
		}
		value = va_arg(list, GLint);
		attr[2*count]     = type;
		attr[2*count + 1] = value;

		count++;
		if (count == MAX_PBUF_PARAM)
		{
			gput_printf("gput_pbuffer_create: Too many attributes\n");
			assert(0);
		}
	}
	va_end(list);

	gput_pbuffer_create_array(buf, target, width, height, iattr, pattr);
}
			


void gput_context_get_current(gput_context* c)
{
	c->hdc = wglGetCurrentDC();
	c->hglrc = wglGetCurrentContext();
}

void gput_context_activate(gput_context* c)
{
	if (!wglMakeCurrent(c->hdc, c->hglrc))
	{
		gput_printf("gput_context_activate: Cannot switch OpenGL context\n");
		assert(0);
	}
}


void gput_pbuffer_activate(gput_pbuffer* buf)
{
	//buf->windowid = glutGetWindow();
	
	/*
	if (!wglReleaseTexImageARB(buf->hpbuf, WGL_FRONT_LEFT_ARB))
	{
		gput_printf("pbuffer_begin: Cannot release\n");
		return;
	}*/
	
	if (!wglMakeCurrent(buf->hdc, buf->hglrc))
		assert(0);
}

/*
void gput_pbuffer_end(gput_pbuffer* buf)
{
	glutSetWindow(buf->windowid);
	//wglMakeCurrent(
}
*/

void gput_pbuffer_bind(gput_pbuffer* pbuf)
{
	glBindTexture(pbuf->target, pbuf->tex);
	//glBindTexture(target, pbuf->tex);
	/*
	if (!wglReleaseTexImageARB(pbuf->hpbuf, WGL_FRONT_LEFT_ARB))
	{
		gput_printf("pbuffer_bind: Cannot release\n");
		return;
	}*/
	wglBindTexImageARB(pbuf->hpbuf, WGL_FRONT_LEFT_ARB);
	/*

	if (!wglBindTexImageARB(pbuf->hpbuf, WGL_FRONT_LEFT_ARB))
	{
		gput_printf("cannot bind\n");
		return;
	}*/
}


void gput_pbuffer_float_create(gput_pbuffer* buf, int n_components, int width, int height)
{
	unsigned int pformats[MAX_FORMATS];
	GLuint nformat;
	HDC hdc;
	gput_context c;

	int iattriblist[] = 
	{
		WGL_DRAW_TO_PBUFFER_ARB, GL_TRUE,
		WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV, 1,
		WGL_FLOAT_COMPONENTS_NV, GL_TRUE,
		WGL_COLOR_BITS_ARB, 32,
		0
	};

	const float fattriblist[] =
	{
		0
	};

	int pattriblist[] = 
	{
		WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_FLOAT_R_NV,
		WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_RECTANGLE_NV,
		0
	};

	hdc = wglGetCurrentDC();

	if (!hdc) 
	{
		gput_printf("unable to get current device context\n");
		return;
	}

	switch (n_components)
	{
	case 1:
		iattriblist[2] = WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV;
		iattriblist[7] = 32;
		pattriblist[1] = WGL_TEXTURE_FLOAT_R_NV;
		break;
	case 2:
		iattriblist[2] = WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV;
		iattriblist[7] = 64;
		pattriblist[1] = WGL_TEXTURE_FLOAT_RG_NV;
		break;
	case 3:
		iattriblist[2] = WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV;
		iattriblist[7] = 96;
		pattriblist[1] = WGL_TEXTURE_FLOAT_RGB_NV;
		break;
	case 4:
		iattriblist[2] = WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV;
		iattriblist[7] = 128;
		pattriblist[1] = WGL_TEXTURE_FLOAT_RGBA_NV;
		break;
	default:
		assert(0);
	}

	if (!wglChoosePixelFormatARB(hdc, iattriblist, fattriblist, MAX_FORMATS, pformats, &nformat)) 
	{
		gput_printf("can't choose pixel format\n");
		return;
	}

	buf->hpbuf = wglCreatePbufferARB(hdc, pformats[0],
		width, height, pattriblist);
	if (!buf->hpbuf) {
		gput_printf("can't create pbuffer\n");
		return;
	}

	buf->hdc = wglGetPbufferDCARB(buf->hpbuf);
	if (!buf->hdc) {
		gput_printf("can't get pbuffer device context.\n");
		return;
	}

	buf->hglrc = wglCreateContext(buf->hdc);
	if (!buf->hglrc) {
		gput_printf("can't create context for pbuffer.\n");
		return;
	}

	wglShareLists(wglGetCurrentContext(), buf->hglrc);

	buf->target = GL_TEXTURE_RECTANGLE_ARB;

	/* create the pbuffer texture object. */
	glGenTextures(1, &buf->tex);

	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, buf->tex);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);	

    /* EBUG HERE */


	{
		//gput_context c;

		gput_context_get_current(&c);
		gput_pbuffer_activate(buf);
		gput_set_orthorenderview(0, 0, width, height);
		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#ifndef NO_NVCG
		cgGLBindProgram(passthru);
		cgGLEnableProfile(CG_PROFILE_FP30);
		glActiveTextureARB(GL_TEXTURE0_ARB);
		glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_FLOAT_RGB_NV, width, height, 0, GL_RGB, GL_FLOAT, NULL);
		DrawQuad(width, height, width, height);
		cgGLDisableProfile(CG_PROFILE_FP30);
		//gput_pbuffer_end(buf);
#endif
		gput_context_activate(&c);
	}
	//gput_pbuffer_float_set(buf, width, height, NULL);
	//glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_FLOAT_RGB_NV, width, height, 0, GL_RGB, GL_FLOAT, NULL);

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -