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

📄 vs_gl_draw.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / 3D rendering module * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC 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 Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  * */#include "visual_surface.h"#include <gpac/options.h>#include "gl_inc.h"/*!! HORRIBLE HACK, but on my test devices, it seems that glClipPlanex is missing on the device but not in the SDK lib !!*/#if defined(GL_MAX_CLIP_PLANES) && defined(__SYMBIAN32__)#undef GL_MAX_CLIP_PLANES#endif#define CHECK_GL_EXT(name) ((strstr(ext, name) != NULL) ? 1 : 0)void R3D_LoadExtensions(Render3D *sr){	const char *ext = (const char *) glGetString(GL_EXTENSIONS);	/*store OGL extension to config for app usage*/	gf_cfg_set_key(sr->compositor->user->config, "Render3D", "OpenGLExtensions", ext);	if (!ext) return;	memset(&sr->hw_caps, 0, sizeof(HardwareCaps));	if (CHECK_GL_EXT("GL_ARB_multisample") || CHECK_GL_EXT("GLX_ARB_multisample") || CHECK_GL_EXT("WGL_ARB_multisample")) 		sr->hw_caps.multisample = 1;	if (CHECK_GL_EXT("GL_ARB_texture_non_power_of_two")) 		sr->hw_caps.npot_texture = 1;	if (CHECK_GL_EXT("GL_EXT_abgr")) 		sr->hw_caps.abgr_texture = 1;	if (CHECK_GL_EXT("GL_EXT_bgra")) 		sr->hw_caps.bgra_texture = 1;	if (CHECK_GL_EXT("GL_EXT_texture_rectangle") || CHECK_GL_EXT("GL_NV_texture_rectangle")) 		sr->hw_caps.rect_texture = 1;}void VS3D_Setup(VisualSurface *surf){    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);	glEnable(GL_DEPTH_TEST);	glDepthFunc(GL_LEQUAL);    glEnable(GL_CULL_FACE);    glFrontFace(GL_CCW);    glCullFace(GL_BACK);#ifdef GPAC_USE_OGL_ES	glClearDepthx(FIX_ONE);	glLightModelx(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);	glMaterialx(GL_FRONT_AND_BACK, GL_SHININESS, FLT2FIX(0.2f * 128) );#else	glClearDepth(1.0f);	glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);	glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, (float) (0.2 * 128));#endif    glShadeModel(GL_SMOOTH);	glGetIntegerv(GL_MAX_LIGHTS, (GLint*)&surf->max_lights);#ifdef GL_MAX_CLIP_PLANES	glGetIntegerv(GL_MAX_CLIP_PLANES, &surf->max_clips);#endif	if (surf->render->compositor->high_speed) {		glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);		glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);		glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);		glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST);#ifdef GL_POLYGON_SMOOTH_HINT		glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);#endif	} else {		glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);		glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);		glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);		glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);#ifdef GL_POLYGON_SMOOTH_HINT		glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);#endif	}	if (surf->render->compositor->antiAlias == GF_ANTIALIAS_FULL) {		glEnable(GL_LINE_SMOOTH);		glEnable(GL_POINT_SMOOTH);#ifndef GPAC_USE_OGL_ES		if (surf->render->poly_aa)			glEnable(GL_POLYGON_SMOOTH);		else			glDisable(GL_POLYGON_SMOOTH);#endif	} else {		glDisable(GL_LINE_SMOOTH);		glDisable(GL_POINT_SMOOTH);#ifndef GPAC_USE_OGL_ES		glDisable(GL_POLYGON_SMOOTH);#endif	}	glDisable(GL_COLOR_MATERIAL);	glDisable(GL_LIGHTING);	glEnable(GL_BLEND);	glDisable(GL_TEXTURE_2D);	glDisable(GL_CULL_FACE);	glDisable(GL_FOG);	/*Note: we cannot enable/disable normalization on the fly, because we have no clue when the GL implementation	will actually compute the related fragments. Since a typical world always use scaling, we always turn normalization on 	to avoid tracking scale*/	glEnable(GL_NORMALIZE);	glClear(GL_DEPTH_BUFFER_BIT);}void VS3D_SetDepthBuffer(VisualSurface *surf, Bool on){	if (on) glEnable(GL_DEPTH_TEST);	else glDisable(GL_DEPTH_TEST);}void VS3D_SetHeadlight(VisualSurface *surf, Bool bOn, GF_Camera *cam){	SFVec3f dir;	SFColor col;	if (!bOn) return;	col.blue = col.red = col.green = FIX_ONE;	if (cam->is_3D) {		dir = camera_get_target_dir(cam);	} else {		dir.x = dir.y = 0; dir.z = FIX_ONE;	}	VS3D_AddDirectionalLight(surf, 0, col, FIX_ONE, dir);}void VS3D_SetViewport(VisualSurface *surf, GF_Rect vp){	glViewport(FIX2INT(vp.x), FIX2INT(vp.y), FIX2INT(vp.width), FIX2INT(vp.height));}void VS3D_ClearDepth(VisualSurface *surf){	glClear(GL_DEPTH_BUFFER_BIT);}void VS3D_DrawAABBNode(RenderEffect3D *eff, GF_Mesh *mesh, u32 prim_type, GF_Plane *fplanes, u32 *p_indices, AABBNode *n){	u32 i;		/*if not leaf do cull*/	if (n->pos) {		u32 p_idx, cull;		SFVec3f vertices[8];		/*get box vertices*/		gf_bbox_get_vertices(n->min, n->max, vertices);		cull = CULL_INSIDE;		for (i=0; i<6; i++) {			p_idx = p_indices[i];			/*check p-vertex: if not in plane, we're out (since p-vertex is the closest point to the plane)*/			if (gf_plane_get_distance(&fplanes[i], &vertices[p_idx])<0) { cull = CULL_OUTSIDE; break; }			/*check n-vertex: if not in plane, we're intersecting*/			if (gf_plane_get_distance(&fplanes[i], &vertices[7-p_idx])<0) { cull = CULL_INTERSECTS; break;}		}		if (cull==CULL_OUTSIDE) return;		if (cull==CULL_INTERSECTS) {			VS3D_DrawAABBNode(eff, mesh, prim_type, fplanes, p_indices, n->pos);			VS3D_DrawAABBNode(eff, mesh, prim_type, fplanes, p_indices, n->neg);			return;		}	}	/*the good thing about the structure of the aabb tree is that the primitive idx is valid for both	leaf and non-leaf nodes, so we can use it as soon as we have a CULL_INSIDE.	However we must push triangles one by one since primitive order may have been swapped when	building the AABB tree*/	for (i=0; i<n->nb_idx; i++) {#ifdef GPAC_USE_OGL_ES		glDrawElements(prim_type, 3, GL_UNSIGNED_SHORT, &mesh->indices[3*n->indices[i]]);#else		glDrawElements(prim_type, 3, GL_UNSIGNED_INT, &mesh->indices[3*n->indices[i]]);#endif	}}void VS3D_DrawMeshIntern(RenderEffect3D *eff, GF_Mesh *mesh){	Bool has_col, has_tx, has_norm;	u32 prim_type;#if defined(GPAC_FIXED_POINT) && !defined(GPAC_USE_OGL_ES)	u32 i;	Float *color_array = NULL;	Float fix_scale = 1.0f;	fix_scale /= FIX_ONE;#endif	has_col = has_tx = has_norm = 0;	glEnableClientState(GL_VERTEX_ARRAY);#if defined(GPAC_USE_OGL_ES)	glVertexPointer(3, GL_FIXED, sizeof(GF_Vertex),  &mesh->vertices[0].pos);#elif defined(GPAC_FIXED_POINT)	/*scale modelview matrix*/	glPushMatrix();	glScalef(fix_scale, fix_scale, fix_scale);	glVertexPointer(3, GL_INT, sizeof(GF_Vertex),  &mesh->vertices[0].pos);#else	glVertexPointer(3, GL_FLOAT, sizeof(GF_Vertex),  &mesh->vertices[0].pos);#endif	if ((eff->mesh_has_texture != 1) && (mesh->flags & MESH_HAS_COLOR)) {		glEnable(GL_COLOR_MATERIAL);#if !defined (GPAC_USE_OGL_ES)		glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);#endif		glEnableClientState(GL_COLOR_ARRAY);		has_col = 1;#if defined (GPAC_USE_OGL_ES)		if (mesh->flags & MESH_HAS_ALPHA) {			glEnable(GL_BLEND);			eff->mesh_is_transparent = 1;		}		/*glES only accepts full RGBA colors*/		glColorPointer(4, GL_FIXED, sizeof(GF_Vertex), &mesh->vertices[0].color);#elif defined (GPAC_FIXED_POINT)		/*this is a real pain: we cannot "scale" colors through openGL, and our components are 16.16 (32 bytes) ranging		from [0 to 65536] mapping to [0, 1.0], but openGL assumes for s32 a range from [-2^31 2^31] mapping to [0, 1.0]		we must thus rebuild a dedicated array...*/		if (mesh->flags & MESH_HAS_ALPHA) {			color_array = malloc(sizeof(Float)*4*mesh->v_count);			for (i=0; i<mesh->v_count; i++) {				color_array[4*i] = FIX2FLT(mesh->vertices[i].color.red);				color_array[4*i+1] = FIX2FLT(mesh->vertices[i].color.green);				color_array[4*i+2] = FIX2FLT(mesh->vertices[i].color.blue);				color_array[4*i+3] = FIX2FLT(mesh->vertices[i].color.alpha);			}			glEnable(GL_BLEND);			glColorPointer(4, GL_FLOAT, 4*sizeof(Float), color_array);			eff->mesh_is_transparent = 1;		} else {			color_array = malloc(sizeof(Float)*3*mesh->v_count);			for (i=0; i<mesh->v_count; i++) {				color_array[3*i] = FIX2FLT(mesh->vertices[i].color.red);				color_array[3*i+1] = FIX2FLT(mesh->vertices[i].color.green);				color_array[3*i+2] = FIX2FLT(mesh->vertices[i].color.blue);			}			glColorPointer(3, GL_FLOAT, 3*sizeof(Float), color_array);		}#else			if (mesh->flags & MESH_HAS_ALPHA) {			glEnable(GL_BLEND);			glColorPointer(4, GL_FLOAT, sizeof(GF_Vertex), &mesh->vertices[0].color);			eff->mesh_is_transparent = 1;		} else {			glColorPointer(3, GL_FLOAT, sizeof(GF_Vertex), &mesh->vertices[0].color);		}#endif	}	if (eff->mesh_has_texture && !mesh->mesh_type && !(mesh->flags & MESH_NO_TEXTURE)) {		glEnableClientState(GL_TEXTURE_COORD_ARRAY );		has_tx = 1;#if defined(GPAC_USE_OGL_ES)		glTexCoordPointer(2, GL_FIXED, sizeof(GF_Vertex), &mesh->vertices[0].texcoords);#elif defined(GPAC_FIXED_POINT)		glMatrixMode(GL_TEXTURE);		glPushMatrix();		glScalef(fix_scale, fix_scale, fix_scale);		glMatrixMode(GL_MODELVIEW);		glTexCoordPointer(2, GL_INT, sizeof(GF_Vertex), &mesh->vertices[0].texcoords);#else		glTexCoordPointer(2, GL_FLOAT, sizeof(GF_Vertex), &mesh->vertices[0].texcoords);#endif	}		if (mesh->mesh_type) {		glNormal3f(0, 0, 1.0f);		glDisable(GL_CULL_FACE);		glDisable(GL_LIGHTING);		if (mesh->mesh_type==2) glDisable(GL_LINE_SMOOTH);		else glDisable(GL_POINT_SMOOTH);		glLineWidth(1.0f);	} else {		has_norm = 1;		glEnableClientState(GL_NORMAL_ARRAY );#if defined(GPAC_USE_OGL_ES)		glNormalPointer(GL_FIXED, sizeof(GF_Vertex), &mesh->vertices[0].normal);#elif defined(GPAC_FIXED_POINT)		glNormalPointer(GL_INT, sizeof(GF_Vertex), &mesh->vertices[0].normal);#else		glNormalPointer(GL_FLOAT, sizeof(GF_Vertex), &mesh->vertices[0].normal);#endif		if (!mesh->mesh_type) {			if (eff->surface->render->backcull 				&& (!eff->mesh_is_transparent || (eff->surface->render->backcull ==GF_BACK_CULL_ALPHA) )				&& (mesh->flags & MESH_IS_SOLID)) {				glEnable(GL_CULL_FACE);				glFrontFace((mesh->flags & MESH_IS_CW) ? GL_CW : GL_CCW);			} else {				glDisable(GL_CULL_FACE);			}		}	}	switch (mesh->mesh_type) {	case MESH_LINESET: prim_type = GL_LINES; break;	case MESH_POINTSET: prim_type = GL_POINTS; break;	default: prim_type = GL_TRIANGLES; break;	}	/*if inside or no aabb for the mesh draw vertex array*/	if ((eff->cull_flag==CULL_INSIDE) || !mesh->aabb_root || !mesh->aabb_root->pos) {#ifdef GPAC_USE_OGL_ES		glDrawElements(prim_type, mesh->i_count, GL_UNSIGNED_SHORT, mesh->indices);#else		glDrawElements(prim_type, mesh->i_count, GL_UNSIGNED_INT, mesh->indices);#endif	} else {		/*otherwise cull aabb against frustum - after some testing it appears (as usual) that there must 		be a compromise: we're slowing down the renderer here, however the gain is really appreciable for 		large meshes, especially terrains/elevation grids*/		/*first get transformed frustum in local space*/		GF_Matrix mx;		u32 i, p_idx[6];		GF_Plane fplanes[6];		gf_mx_copy(mx, eff->model_matrix);		gf_mx_inverse(&mx);		for (i=0; i<6; i++) {			fplanes[i] = eff->camera->planes[i];			gf_mx_apply_plane(&mx, &fplanes[i]);			p_idx[i] = gf_plane_get_p_vertex_idx(&fplanes[i]);		}		/*then recursively cull & render AABB tree*/		VS3D_DrawAABBNode(eff, mesh, prim_type, fplanes, p_idx, mesh->aabb_root->pos);		VS3D_DrawAABBNode(eff, mesh, prim_type, fplanes, p_idx, mesh->aabb_root->neg);	}	glDisableClientState(GL_VERTEX_ARRAY);	if (has_col) glDisableClientState(GL_COLOR_ARRAY);	glDisable(GL_COLOR_MATERIAL);	if (has_tx) glDisableClientState(GL_TEXTURE_COORD_ARRAY);	if (has_norm) glDisableClientState(GL_NORMAL_ARRAY);#if defined(GPAC_FIXED_POINT) && !defined(GPAC_USE_OGL_ES)	if (color_array) free(color_array);	if (!mesh->mesh_type && !(mesh->flags & MESH_NO_TEXTURE)) {		glMatrixMode(GL_TEXTURE);		glPopMatrix();		glMatrixMode(GL_MODELVIEW);	}	glPopMatrix();#endif		if (eff->mesh_is_transparent) glDisable(GL_BLEND);	eff->mesh_is_transparent = 0;}#ifdef GPAC_USE_OGL_ESu32 ogles_push_enable(u32 mask){	u32 attrib = 0;#ifndef __SYMBIAN32__	if ((mask & GL_LIGHTING) && glIsEnabled(GL_LIGHTING) ) attrib |= GL_LIGHTING;	if ((mask & GL_BLEND) && glIsEnabled(GL_BLEND) ) attrib |= GL_BLEND;	if ((mask & GL_COLOR_MATERIAL) && glIsEnabled(GL_COLOR_MATERIAL) ) attrib |= GL_COLOR_MATERIAL;	if ((mask & GL_TEXTURE_2D) && glIsEnabled(GL_TEXTURE_2D) ) attrib |= GL_TEXTURE_2D;#endif	return attrib;}void ogles_pop_enable(u32 mask){#ifndef __SYMBIAN32__	if (mask & GL_LIGHTING) glEnable(GL_LIGHTING);	if (mask & GL_BLEND) glEnable(GL_BLEND);	if (mask & GL_COLOR_MATERIAL) glEnable(GL_COLOR_MATERIAL);	if (mask & GL_TEXTURE_2D) glEnable(GL_TEXTURE_2D);#endif}#endif/*note we don't perform any culling for normal drawing...*/void VS3D_DrawNormals(RenderEffect3D *eff, GF_Mesh *mesh){	GF_Vec pt, end;	u32 i, j;	Fixed scale = mesh->bounds.radius / 4;#ifdef GPAC_USE_OGL_ES	GF_Vec va[2];	u16 indices[2];	u32 attrib = ogles_push_enable(GL_LIGHTING | GL_BLEND | GL_COLOR_MATERIAL | GL_TEXTURE_2D);	glEnableClientState(GL_VERTEX_ARRAY);#else	glPushAttrib(GL_ENABLE_BIT);#endif	glDisable(GL_LIGHTING | GL_BLEND | GL_COLOR_MATERIAL | GL_TEXTURE_2D);#ifdef GPAC_USE_OGL_ES	glColor4x(0, 0, 0, 1);#else	glColor3f(1, 1, 1);#endif	if (eff->surface->render->draw_normals==GF_NORMALS_VERTEX) {		IDX_TYPE *idx = mesh->indices;

⌨️ 快捷键说明

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