Ejemplo n.º 1
0
Archivo: gl.c Proyecto: rzr/glshim
void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *uindices) {
    // TODO: split for count > 65535?
    GLushort *indices = copy_gl_array(uindices, type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count);
    // TODO: do this in a more direct fashion.
    if (should_intercept_render(mode)) {
        glBegin(mode);
        for (int i = 0; i < count; i++) {
            glArrayElement(indices[i]);
        }
        glEnd();
        free(indices);
        return;
    }

    bool compiling = (state.list.active && state.list.compiling);
    if (compiling) {
        renderlist_t *list = NULL;
        GLsizei min, max;

        if (compiling)
            list = state.list.active = extend_renderlist(state.list.active);

        normalize_indices(indices, &max, &min, count);
        list = arrays_to_renderlist(list, mode, 0, max + 1);
        list->indices = indices;
        list->len = count;

        end_renderlist(list);
        if (! compiling) {
            draw_renderlist(list);
            free_renderlist(list);
        }
    } else {
        LOAD_GLES(glDrawElements);
        gles_glDrawElements(mode, count, type, indices);
        free(indices);
    }
}
Ejemplo n.º 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 *sind = (GLushort*)((type==GL_UNSIGNED_SHORT)?indices:NULL);
	GLuint *iind = (GLuint*)((type==GL_UNSIGNED_INT)?indices:NULL);

	GLsizei min, max;
	if(sind)
		getminmax_indices_us(sind, &max, &min, count);
	else
		getminmax_indices_ui(iind, &max, &min, count);
    max++;
	GLfloat *vert = copy_gl_array(vtx->pointer, vtx->type, 
			vtx->size, vtx->stride,
			GL_FLOAT, 4, 0, max);
	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; \
		}

	if(sind) {
		for (int i=0; i<count; i++) {
			switch (mode) {
				case GL_POINTS:
					if (select_point_in_viewscreen(vert+sind[i]*4)) {
						ZMinMax(&zmin, &zmax, vert+sind[i]*4);
						FOUND();
					}
					break;
				case GL_LINES:
					if (i%2==1) {
						if (select_segment_in_viewscreen(vert+sind[(i-1)]*4, vert+sind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+sind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+sind[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+sind[(i-1)]*4, vert+sind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+sind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+sind[i]*4);
							FOUND();
						}
					}
					break;
				case GL_TRIANGLES:
					if (i%3==2) {
						if (select_triangle_in_viewscreen(vert+sind[(i-2)]*4, vert+sind[(i-1)]*4, vert+sind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+sind[i-2]*4);
							ZMinMax(&zmin, &zmax, vert+sind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+sind[i]*4);
							FOUND();
						}
					}
					break;
				case GL_TRIANGLE_STRIP:
					if (i>1) {
						if (select_triangle_in_viewscreen(vert+sind[(i-2)]*4, vert+sind[(i-1)]*4, vert+sind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+sind[i-2]*4);
							ZMinMax(&zmin, &zmax, vert+sind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+sind[i]*4);
							FOUND();
						}
					}
					break;
				case GL_TRIANGLE_FAN:
					if (i>1) {
						if (select_triangle_in_viewscreen(vert+sind[0]*4, vert+sind[(i-1)]*4, vert+sind[i]*4))
							ZMinMax(&zmin, &zmax, vert+sind[0]*4);
							ZMinMax(&zmin, &zmax, vert+sind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+sind[i]*4);
							FOUND();
					}
					break;
				default:
					return;		// Should never go there!
			}
		} 
	} else {
		for (int i=0; i<count; i++) {
			switch (mode) {
				case GL_POINTS:
					if (select_point_in_viewscreen(vert+iind[i]*4)) {
						ZMinMax(&zmin, &zmax, vert+iind[i]*4);
						FOUND();
					}
					break;
				case GL_LINES:
					if (i%2==1) {
						if (select_segment_in_viewscreen(vert+iind[(i-1)]*4, vert+iind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+iind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+iind[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+iind[(i-1)]*4, vert+iind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+iind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+iind[i]*4);
							FOUND();
						}
					}
					break;
				case GL_TRIANGLES:
					if (i%3==2) {
						if (select_triangle_in_viewscreen(vert+iind[(i-2)]*4, vert+iind[(i-1)]*4, vert+iind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+iind[i-2]*4);
							ZMinMax(&zmin, &zmax, vert+iind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+iind[i]*4);
							FOUND();
						}
					}
					break;
				case GL_TRIANGLE_STRIP:
					if (i>1) {
						if (select_triangle_in_viewscreen(vert+iind[(i-2)]*4, vert+iind[(i-1)]*4, vert+iind[i]*4)) {
							ZMinMax(&zmin, &zmax, vert+iind[i-2]*4);
							ZMinMax(&zmin, &zmax, vert+iind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+iind[i]*4);
							FOUND();
						}
					}
					break;
				case GL_TRIANGLE_FAN:
					if (i>1) {
						if (select_triangle_in_viewscreen(vert+iind[0]*4, vert+iind[(i-1)]*4, vert+iind[i]*4))
							ZMinMax(&zmin, &zmax, vert+iind[0]*4);
							ZMinMax(&zmin, &zmax, vert+iind[i-1]*4);
							ZMinMax(&zmin, &zmax, vert+iind[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
}
Ejemplo n.º 3
0
void select_glDrawArrays(const pointer_state_t* vtx, GLenum mode, GLuint first, GLuint count) {
	if (count == 0) return;
	if (vtx->pointer == NULL) return;
	if (glstate->selectbuf.buffer == NULL) return;
	GLfloat *vert = copy_gl_array(vtx->pointer, vtx->type, 
			vtx->size, vtx->stride,
			GL_FLOAT, 4, 0, count+first);
	GLfloat zmin=1e10f, zmax=-1e10f;
	int found = 0;

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

    // transform the points
	for (int i=first; i<count+first; i++) {
		select_transform(vert+i*4);
		ZMinMax(&glstate->selectbuf.zminoverall, &glstate->selectbuf.zmaxoverall, vert+i*4);
    }
    // intersect with screen now
    GLfloat *vert2 = vert + first*4;
	for (int i=0; i<count; i++) {
		switch (mode) {
			case GL_POINTS:
				if (select_point_in_viewscreen(vert2+i*4)) {
					ZMinMax(&zmin, &zmax, vert+i*4);
					FOUND();
				}
				break;
			case GL_LINES:
				if (i%2==1) {
					if (select_segment_in_viewscreen(vert2+(i-1)*4, vert2+i*4)) {
						ZMinMax(&zmin, &zmax, vert+(i-1)*4);
						ZMinMax(&zmin, &zmax, vert+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(vert2+(i-1)*4, vert2+i*4)) {
						ZMinMax(&zmin, &zmax, vert+(i-1)*4);
						ZMinMax(&zmin, &zmax, vert+i*4);
						FOUND();
					}
				}
				break;
			case GL_TRIANGLES:
				if (i%3==2) {
					if (select_triangle_in_viewscreen(vert2+(i-2)*4, vert2+(i-1)*4, vert2+i*4)) {
						ZMinMax(&zmin, &zmax, vert+(i-2)*4);
						ZMinMax(&zmin, &zmax, vert+(i-1)*4);
						ZMinMax(&zmin, &zmax, vert+i*4);
						FOUND();
					}
				}
				break;
			case GL_TRIANGLE_STRIP:
				if (i>1) {
					if (select_triangle_in_viewscreen(vert2+(i-2)*4, vert2+(i-1)*4, vert2+i*4)) {
						ZMinMax(&zmin, &zmax, vert+(i-2)*4);
						ZMinMax(&zmin, &zmax, vert+(i-1)*4);
						ZMinMax(&zmin, &zmax, vert+i*4);
						FOUND();
					}
				}
				break;
			case GL_TRIANGLE_FAN:
				if (i>1) {
					if (select_triangle_in_viewscreen(vert2, vert2+(i-1)*4, vert2+i*4)) {
						ZMinMax(&zmin, &zmax, vert);
						ZMinMax(&zmin, &zmax, vert+(i-1)*4);
						ZMinMax(&zmin, &zmax, vert+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
}
Ejemplo n.º 4
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, 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
}
Ejemplo n.º 5
0
void select_glDrawArrays(const pointer_state_t* vtx, GLenum mode, GLuint first, GLuint count) {
	if (count == 0) return;
	if (vtx->pointer == NULL) return;
	if (state.selectbuf.buffer == NULL) return;
	GLfloat *vert = copy_gl_array(vtx->pointer, vtx->type, 
			vtx->size, vtx->stride,
			GL_FLOAT, 3, 0, count+first);
	GLfloat tmp[3];
	GLfloat zmin=1.0f, zmax=0.0f;
	init_select();

	#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;                                         \
		}
    // transform the points
	for (int i=first; i<count+first; 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];
    }
    // intersect with screen now
    GLfloat *vert2 = vert + first*3;
	for (int i=0; i<count; i++) {
		switch (mode) {
			case GL_POINTS:
				if (select_point_in_viewscreen(vert2+i*3))
					FOUND();
				break;
			case GL_LINES:
				if (i%2==1) {
					if (select_segment_in_viewscreen(vert2+(i-1)*3, vert2+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(vert2+(i-1)*3, vert2+i*3))
						FOUND();
				}
				break;
			case GL_TRIANGLES:
				if (i%3==2) {
					if (select_triangle_in_viewscreen(vert2+(i-2)*3, vert2+(i-1)*3, vert2+i*3))
						FOUND();
				}
				break;
			case GL_TRIANGLE_STRIP:
				if (i>1) {
					if (select_triangle_in_viewscreen(vert2+(i-2)*3, vert2+(i-1)*3, vert2+i*3))
						FOUND();
				}
				break;
			case GL_TRIANGLE_FAN:
				if (i>1) {
					if (select_triangle_in_viewscreen(vert2, vert2+(i-1)*3, vert2+i*3))
						FOUND();
				}
				break;
			default:
				return;		// Should never go there!
		}
	}
	free(vert);
	#undef FOUND
}