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

📄 gpu_util.c

📁 游戏编程精粹6第中关于粒子的实时流体仿真系统,对入门的游戏开发者很有帮助.
💻 C
📖 第 1 页 / 共 2 页
字号:
/**
 * Uitility functions for OpenGL
 *
 * Copyright (c) Takashi AMADA  All Rights Reseved
 */

#include "gpu_util.h"

#include <windows.h>
#include <GL/glut.h>

//#define _USE_DEVIL_
#ifdef _USE_DEVIL_
#include <il/il.h>
#endif

#define MAX_FORMATS 1

#ifndef NO_NVCG
static CGprogram passthru;
static CGcontext cg_context;
#endif

void gput_init()
{
#ifndef NO_NVCG
	cg_context = cgCreateContext();
#endif
#ifdef _USE_DEVIL_
	ilInit();
#endif
}

#ifndef NO_NVCG
CGcontext gput_cg_context()
{
	return cg_context;
}
#endif

/**
 * Print GPU profile
 */
void gput_print_gpu_profile()
{
	GLint i;

	glGetIntegerv(GL_MAX_TEXTURE_UNITS, &i);
	gput_printf("GL_MAX_TEXTURE_UNITS = %d\n", i);
}

void gput_mat_init(gput_mat* mat)
{
}

void gput_mat_diffuse(gput_mat* mat, GLfloat r, GLfloat g, GLfloat b, GLfloat a)
{
	mat->diffuse[0] = r;
	mat->diffuse[1] = g;
	mat->diffuse[2] = b;
	mat->diffuse[3] = a;
}

void gput_mat_specular(gput_mat* mat, GLfloat r, GLfloat g, GLfloat b, GLfloat a)
{
	mat->specular[0] = r;
	mat->specular[1] = g;
	mat->specular[2] = b;
	mat->specular[3] = a;
}

void gput_mat_shininess(gput_mat* mat, GLfloat s)
{
	mat->shininess = s;
}

void gput_mat_bind(gput_mat* mat)
{
	glMaterialfv(GL_FRONT, GL_DIFFUSE, mat->diffuse);
	glMaterialfv(GL_FRONT, GL_SPECULAR, mat->specular);
	glMaterialf(GL_FRONT, GL_SHININESS, mat->shininess);
}

void gput_light_init(gput_light* l)
{
}

void gput_light_position(gput_light* l, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
	l->position[0] = x;
	l->position[1] = y;
	l->position[2] = z;
	l->position[3] = w;
}

void gput_light_diffuse(gput_light* l, GLfloat r, GLfloat g, GLfloat b, GLfloat a)
{
	l->diffuse[0] = r;
	l->diffuse[1] = g;
	l->diffuse[2] = b;
	l->diffuse[3] = a;
}

void gput_light_ambient(gput_light* l, GLfloat r, GLfloat g, GLfloat b, GLfloat a)
{
	l->ambient[0] = r;
	l->ambient[1] = g;
	l->ambient[2] = b;
	l->ambient[3] = a;
}

void gput_light_bind(gput_light* l, GLenum light)
{
	glLightfv(light, GL_POSITION, l->position);
	glLightfv(light, GL_DIFFUSE, l->diffuse);
	glLightfv(light, GL_AMBIENT, l->ambient);
}


void gput_write_screen(const char* filename, int width, int height)
{
#ifdef _USE_DEVIL_
	char* pixels;
	ILuint image0;

	pixels = (char*)malloc(3*width*height*sizeof(char));
	glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);

	ilGenImages(1, &image0);
	ilBindImage(image0);
	ilTexImage(width, height, 1, 3, IL_RGB, IL_UNSIGNED_BYTE, pixels);
	ilSetData(pixels);
	ilSaveImage(filename);
	ilDeleteImages(1, &image0);
	free(pixels);
#endif
}

GPUT_BOOL gput_load_texture(GLenum target, const char* filename)
{
	HANDLE hFile;
	DWORD read;
	DWORD fileSizeHigh;
	DWORD fileSize;
	char* buf;

//	char* buf2;
//	int i;

	BITMAPFILEHEADER* pBMFH;
	BITMAPINFOHEADER* pBMIH;

	hFile = CreateFile(filename,
		GENERIC_READ | GENERIC_WRITE,
		0,
		NULL,
		OPEN_EXISTING,
		0,
		NULL);
	
	if (hFile == INVALID_HANDLE_VALUE)
	{
		return GPUT_FALSE;
	}

	fileSize = GetFileSize(hFile, &fileSizeHigh);
	buf = (char*)malloc(fileSize*sizeof(char));//new char[fileSize];

	if (!ReadFile(hFile, buf, fileSize, &read, NULL))
	{
		return GPUT_FALSE;
	}

	pBMFH = (BITMAPFILEHEADER*)buf;
	pBMIH = (BITMAPINFOHEADER*)(buf + sizeof(BITMAPFILEHEADER));

	buf += (fileSize - 3*pBMIH->biWidth*pBMIH->biHeight);
/*
	buf2 = (char*)malloc(3*pBMIH->biWidth*pBMIH->biHeight);

	for (i = 3*pBMIH->biWidth*pBMIH->biHeight - 1; i >= 0; i--)
	{
		buf2[i] = buf[3*pBMIH->biWidth*pBMIH->biHeight - i - 1];
	}*/
/*
	glBindTexture(GL_TEXTURE_2D, tex);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);*/
//	glTexImage2D(GL_TEXTURE_2D, 0, 3, tex_width, tex_height, 0, GL_RGB, GL_UNSIGNED_BYTE, pix);
	glTexImage2D(target, 0, 3, pBMIH->biWidth, pBMIH->biHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, buf);

	//free(buf2);

//	memcpy(pixels, buf, 3*pBMIH->biWidth*pBMIH->biHeight);

	buf -= (fileSize - 3*pBMIH->biWidth*pBMIH->biHeight);

	CloseHandle(hFile);
	free(buf);

	return GPUT_TRUE;
}

void gput_profile_init(gput_profile* p)
{
	p->start = 0;
	p->elapsed = 0;
	p->count = 0;
}

void gput_profile_begin(gput_profile* p)
{
	p->start = GetTickCount();
	p->count++;
}

void gput_profile_end(gput_profile* p)
{
	DWORD elapsed;
	glFinish();
	elapsed = GetTickCount() - p->start;
	p->elapsed += elapsed;
	//gput_printf("%s: %d msec. elapsed.\n", name, GetTickCount() - bm_start);
}

void gput_profile_print(gput_profile* p, const char* name)
{
	gput_printf("%s: %d msec. elapsed.\n", name, p->elapsed/p->count);
}

void check_gl_error(void)
{
	GLenum err;
	err = glGetError();
	if (err != GL_NO_ERROR)
	{
		gput_printf("GL Error: %x\n", err);
		assert(0);
	}
}

#ifndef NO_NVCG
void check_cg_error(void)
{
	CGerror err = cgGetError();

	if (err != CG_NO_ERROR)
	{
		gput_printf("Cg Error: %s\n", cgGetErrorString(err));
		assert(0);
		//exit(1);
	}
}


CGprogram gput_create_program_from_file(const char* program_file, CGprofile profile, CGcontext context)
{
	CGprogram new_fp;

	new_fp = cgCreateProgramFromFile(context,
		CG_SOURCE, program_file,
		profile,
		NULL, NULL);

	cgGLLoadProgram(new_fp);

	check_cg_error();

	return new_fp;
}

void gput_cache_program(CGprogram prog, CGprofile prof)
{
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	cgGLEnableProfile(prof);
	cgGLBindProgram(prog);
	glBegin(GL_POINTS);
	glVertex2i(0, 0);
	glEnd();
	cgGLDisableProfile(prof);
}

CGprogram gput_create_program(const char* src, CGprofile profile, CGcontext context)
{
	CGprogram new_fp;

	new_fp = cgCreateProgram(context,
		CG_SOURCE, src,
		profile,
		NULL, NULL);

//	cgCompileProgram(new_fp);
	cgGLLoadProgram(new_fp);

	/*
	cgGLEnableProfile(profile);
	cgGLBindProgram(new_fp);
	glBegin(GL_POINTS);
	glVertex2i(0, 0);
	glEnd();
	cgGLDisableProfile(profile);
	*/

	check_cg_error();

	return new_fp;
}
#endif

GLuint gput_cubemap_create_from_file(const char* filename[6])
{
	int i;
	GLuint tex;

	static GLenum targets[6] = {
		GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
		GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
		GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
		GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
		GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
		GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
	};

	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, tex);

	for (i = 0; i < 6; i++)
		if (!gput_load_texture(targets[i], filename[i]))
			gput_printf("Cannot load texture '%s'\n", filename[i]);

	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);

	return tex;
}

void gput_cubemap_enable()
//void gput_cubemap_enable(GLuint tex)
{
	GLint mode;

//	glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, map->tex);

	glEnable(GL_TEXTURE_CUBE_MAP_ARB);
	glEnable(GL_TEXTURE_GEN_S);
	glEnable(GL_TEXTURE_GEN_T);
	glEnable(GL_TEXTURE_GEN_R);

	//mode = GL_NORMAL_MAP_EXT;
	mode = GL_REFLECTION_MAP_ARB;

	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, mode);
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, mode);
	glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, mode);
}

//void gput_cubemap_disable()
void gput_cubemap_disable()
{
	glDisable(GL_TEXTURE_CUBE_MAP_ARB);
	glDisable(GL_TEXTURE_GEN_S);
	glDisable(GL_TEXTURE_GEN_T);
	glDisable(GL_TEXTURE_GEN_R);
}


void gput_cubemap_skybox()
{
    GLfloat s_plane[] = { 1.0, 0.0, 0.0, 0.0 };
    GLfloat t_plane[] = { 0.0, 1.0, 0.0, 0.0 };
    GLfloat r_plane[] = { 0.0, 0.0, 1.0, 0.0 };

	glEnable(GL_TEXTURE_CUBE_MAP_ARB);
	
	glEnable(GL_TEXTURE_GEN_S);
	glEnable(GL_TEXTURE_GEN_T);
	glEnable(GL_TEXTURE_GEN_R);

	glMatrixMode(GL_TEXTURE);
	glPushMatrix();
	glLoadIdentity();
	glTexGenfv(GL_S, GL_EYE_PLANE, s_plane);
    glTexGenfv(GL_T, GL_EYE_PLANE, t_plane);
    glTexGenfv(GL_R, GL_EYE_PLANE, r_plane);

	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
	glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);

	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

	glDisable(GL_CULL_FACE);
	glutSolidCube(2.0);
	glEnable(GL_CULL_FACE);

	glDisable(GL_TEXTURE_CUBE_MAP_ARB);
	glMatrixMode(GL_TEXTURE);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glDisable(GL_TEXTURE_GEN_S);
	glDisable(GL_TEXTURE_GEN_T);
	glDisable(GL_TEXTURE_GEN_R);
}

void gput_vert2i_tex1f(int vx, int vy, GLfloat tx)
{
	glMultiTexCoord1fARB(GL_TEXTURE0_ARB, tx);
	glVertex2i(vx, vy);
}

void gput_vert2i_tex2f(int vx, int vy,
					   GLfloat tx, GLfloat ty)
{
	glMultiTexCoord2fARB(GL_TEXTURE0_ARB, tx, ty);
	glVertex2i(vx, vy);
}

void gput_vert2i_2tex2f(int vx, int vy,
						GLfloat x0, GLfloat y0, 
						GLfloat x1, GLfloat y1)
{
	glMultiTexCoord2fARB(GL_TEXTURE0_ARB, x0, y0);
	glMultiTexCoord2fARB(GL_TEXTURE1_ARB, x1, y1);
	glVertex2i(vx, vy);
}


void gput_vert2i_3tex2f(int vx, int vy,
						GLfloat x0, GLfloat y0, 
						GLfloat x1, GLfloat y1,
						GLfloat x2, GLfloat y2)
{
	glMultiTexCoord2fARB(GL_TEXTURE0_ARB, x0, y0);
	glMultiTexCoord2fARB(GL_TEXTURE1_ARB, x1, y1);
	glMultiTexCoord2fARB(GL_TEXTURE2_ARB, x2, y2);
	glVertex2i(vx, vy);
}


void gput_set_orthorenderview(int x, int y, int view_width, int view_height)
{
	glViewport(x, y, view_width, view_height);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0.0, view_width, 0.0, view_height);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void gput_dump_frame(const char* name, int n_components, int x0, int y0, int width, int height)
{
	GLfloat* buf;
	int x;
	int y;
	int index;

	gput_printf("pbufferf_dump: you should fix\n");

	/*
	buf = (GLfloat*)malloc(pbuf->width*pbuf->height*4*sizeof(GLfloat));
	glReadPixels(0, 0, pbuf->width, pbuf->height, GL_RGBA, GL_FLOAT, buf);
	*/

	buf = (GLfloat*)malloc(width*height*4*sizeof(GLfloat));
	glReadPixels(x0, y0, width, height, GL_RGBA, GL_FLOAT, buf);
	gput_printf("NAME: %s -------------------\n", name);

⌨️ 快捷键说明

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