コード例 #1
0
ファイル: render.c プロジェクト: thielj/glshim
void select_glDrawElements(const pointer_state_t* vtx, GLenum mode, GLuint count, GLenum type, GLvoid * indices) {
	if (count == 0) return;
	if (vtx->pointer == NULL) return;

	GLushort *ind = (GLushort*)indices;

	GLsizei min, max;
	getminmax_indices(indices, &max, &min, count);
    max++;
	GLfloat *vert = copy_gl_array(vtx->pointer, vtx->type, 
			vtx->size, vtx->stride,
			GL_FLOAT, 3, 0, max);
	GLfloat tmp[3];
	init_select();
	GLfloat zmin=1.0f, zmax=0.0f;
	for (int i=min; i<max; i++) {
		select_transform(vert+i*3);
		if (vert[i*3+2]<zmin) zmin=vert[i*3+2];
		if (vert[i*3+2]>zmax) zmax=vert[i*3+2];
	}
	if (zmin<0.0f) zmin = 0.0f;
	if (zmax>1.0f) zmax = 1.0f;

	#define FOUND()	{ 		\
		if (zmin<state.selectbuf.zmin) 	state.selectbuf.zmin=zmin;	\
		if (zmax>state.selectbuf.zmax) 	state.selectbuf.zmax=zmax;	\
		state.selectbuf.hit = 1; \
        free(vert);              \
        return;                  \
		}

	for (int i=0; i<count; i++) {
		switch (mode) {
			case GL_POINTS:
				if (select_point_in_viewscreen(vert+ind[i]*3))
					FOUND();
				break;
			case GL_LINES:
				if (i%2==1) {
					if (select_segment_in_viewscreen(vert+ind[(i-1)]*3, vert+ind[i]*3))
						FOUND();
				}
				break;
			case GL_LINE_STRIP:
			case GL_LINE_LOOP:		//FIXME: the last "loop" segment is missing here
				if (i>0) {
					if (select_segment_in_viewscreen(vert+ind[(i-1)]*3, vert+ind[i]*3))
						FOUND();
				}
				break;
			case GL_TRIANGLES:
				if (i%3==2) {
					if (select_triangle_in_viewscreen(vert+ind[(i-2)]*3, vert+ind[(i-1)]*3, vert+ind[i]*3))
						FOUND();
				}
				break;
			case GL_TRIANGLE_STRIP:
				if (i>1) {
					if (select_triangle_in_viewscreen(vert+ind[(i-2)]*3, vert+ind[(i-1)]*3, vert+ind[i]*3))
						FOUND();
				}
				break;
			case GL_TRIANGLE_FAN:
				if (i>1) {
					if (select_triangle_in_viewscreen(vert+ind[0]*3, vert+ind[(i-1)]*3, vert+ind[i]*3))
						FOUND();
				}
				break;
			default:
				return;		// Should never go there!
		}
	}
	free(vert);
	#undef FOUND
}
コード例 #2
0
void select_glDrawElements(const pointer_state_t* vtx, GLenum mode, GLuint count, GLenum type, GLvoid * indices) {
	if (count == 0) return;
	if (vtx->pointer == NULL) return;

	GLushort *ind = (GLushort*)indices;

	GLsizei min, max;
	getminmax_indices(indices, &max, &min, count);
    max++;
	GLfloat *vert = copy_gl_array(vtx->pointer, vtx->type, 
			vtx->size, vtx->stride,
			GL_FLOAT, 4, 0, max);
	init_select();
	GLfloat zmin=1e10f, zmax=-10e6f;
	int found = 0;
	for (int i=min; i<max; i++) {
		select_transform(vert+i*4);
		ZMinMax(&glstate->selectbuf.zminoverall, &glstate->selectbuf.zmaxoverall, vert+i*4);
	}

	#define FOUND()	{ 				\
		found = 1;					\
		glstate->selectbuf.hit = 1; \
		}

	for (int i=0; i<count; i++) {
		switch (mode) {
			case GL_POINTS:
				if (select_point_in_viewscreen(vert+ind[i]*4)) {
					ZMinMax(&zmin, &zmax, vert+ind[i]*4);
					FOUND();
				}
				break;
			case GL_LINES:
				if (i%2==1) {
					if (select_segment_in_viewscreen(vert+ind[(i-1)]*4, vert+ind[i]*4)) {
						ZMinMax(&zmin, &zmax, vert+ind[i-1]*4);
						ZMinMax(&zmin, &zmax, vert+ind[i]*4);
						FOUND();
					}
				}
				break;
			case GL_LINE_STRIP:
			case GL_LINE_LOOP:		//FIXME: the last "loop" segment is missing here
				if (i>0) {
					if (select_segment_in_viewscreen(vert+ind[(i-1)]*4, vert+ind[i]*4)) {
						ZMinMax(&zmin, &zmax, vert+ind[i-1]*4);
						ZMinMax(&zmin, &zmax, vert+ind[i]*4);
						FOUND();
					}
				}
				break;
			case GL_TRIANGLES:
				if (i%3==2) {
					if (select_triangle_in_viewscreen(vert+ind[(i-2)]*4, vert+ind[(i-1)]*4, vert+ind[i]*4)) {
						ZMinMax(&zmin, &zmax, vert+ind[i-2]*4);
						ZMinMax(&zmin, &zmax, vert+ind[i-1]*4);
						ZMinMax(&zmin, &zmax, vert+ind[i]*4);
						FOUND();
					}
				}
				break;
			case GL_TRIANGLE_STRIP:
				if (i>1) {
					if (select_triangle_in_viewscreen(vert+ind[(i-2)]*4, vert+ind[(i-1)]*4, vert+ind[i]*4)) {
						ZMinMax(&zmin, &zmax, vert+ind[i-2]*4);
						ZMinMax(&zmin, &zmax, vert+ind[i-1]*4);
						ZMinMax(&zmin, &zmax, vert+ind[i]*4);
						FOUND();
					}
				}
				break;
			case GL_TRIANGLE_FAN:
				if (i>1) {
					if (select_triangle_in_viewscreen(vert+ind[0]*4, vert+ind[(i-1)]*4, vert+ind[i]*4))
						ZMinMax(&zmin, &zmax, vert+ind[0]*4);
						ZMinMax(&zmin, &zmax, vert+ind[i-1]*4);
						ZMinMax(&zmin, &zmax, vert+ind[i]*4);
						FOUND();
				}
				break;
			default:
				return;		// Should never go there!
		}
	}
	free(vert);
	if(found) {
		if (zmin<glstate->selectbuf.zmin) 	glstate->selectbuf.zmin=zmin;
		if (zmax>glstate->selectbuf.zmax) 	glstate->selectbuf.zmax=zmax;
	}

	#undef FOUND
}