Example #1
0
int gl_m4_stack_new(struct gl_m4_stack **out)
{
	struct gl_m4_stack *stack;

	if (!out)
		return -EINVAL;

	stack = malloc(sizeof(*stack));
	if (!stack)
		return -ENOMEM;

	memset(stack, 0, sizeof(*stack));
	gl_m4_identity(stack->stack.matrix);

	*out = stack;
	return 0;
}
Example #2
0
float *gl_m4_stack_pop(struct gl_m4_stack *stack)
{
	struct gl_m4_entry *entry;

	if (!stack)
		return NULL;

	entry = stack->stack.next;
	if (!entry) {
		gl_m4_identity(stack->stack.matrix);
		return stack->stack.matrix;
	}

	stack->stack.next = entry->next;
	entry->next = stack->cache;
	stack->cache = entry;

	gl_m4_copy(stack->stack.matrix, entry->matrix);

	return stack->stack.matrix;
}
Example #3
0
int uterm_drm3d_display_fill(struct uterm_display *disp,
			     uint8_t r, uint8_t g, uint8_t b,
			     unsigned int x, unsigned int y,
			     unsigned int width, unsigned int height)
{
	struct uterm_drm3d_video *v3d;
	unsigned int sw, sh, tmp, i;
	float mat[16];
	float vertices[6 * 2], colors[6 * 4];
	int ret;

	v3d = uterm_drm_video_get_data(disp->video);
	ret = uterm_drm3d_display_use(disp, NULL);
	if (ret)
		return ret;
	ret = init_shaders(disp->video);
	if (ret)
		return ret;

	sw = uterm_drm_mode_get_width(disp->current_mode);
	sh = uterm_drm_mode_get_height(disp->current_mode);

	for (i = 0; i < 6; ++i) {
		colors[i * 4 + 0] = r / 255.0;
		colors[i * 4 + 1] = g / 255.0;
		colors[i * 4 + 2] = b / 255.0;
		colors[i * 4 + 3] = 1.0;
	}

	vertices[0] = -1.0;
	vertices[1] = -1.0;
	vertices[2] = -1.0;
	vertices[3] = +1.0;
	vertices[4] = +1.0;
	vertices[5] = +1.0;

	vertices[6] = -1.0;
	vertices[7] = -1.0;
	vertices[8] = +1.0;
	vertices[9] = +1.0;
	vertices[10] = +1.0;
	vertices[11] = -1.0;

	tmp = x + width;
	if (tmp < x || x >= sw)
		return -EINVAL;
	if (tmp > sw)
		width = sw - x;
	tmp = y + height;
	if (tmp < y || y >= sh)
		return -EINVAL;
	if (tmp > sh)
		height = sh - y;

	/* Caution:
	 * opengl uses a coordinate system with the origin at _lower-left_ corner
	 * and positive y-axis up, while other parts uses a coordinate system
	 * with the origin at _upper-left_ corner and positive y-axis down.
	 */
	y = sh - y; // invert y-axis
	y -= height; // move origin to lower left corner

	glViewport(x, y, width, height);
	glDisable(GL_BLEND);

	gl_shader_use(v3d->fill_shader);
	gl_m4_identity(mat);
	glUniformMatrix4fv(v3d->uni_fill_proj, 1, GL_FALSE, mat);
	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
	glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, colors);
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);
	glDrawArrays(GL_TRIANGLES, 0, 6);
	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);

	if (gl_has_error(v3d->fill_shader)) {
		log_warning("GL error");
		return -EFAULT;
	}

	return 0;
}
Example #4
0
static int display_blend(struct uterm_display *disp,
			 const struct uterm_video_buffer *buf,
			 unsigned int x, unsigned int y,
			 uint8_t fr, uint8_t fg, uint8_t fb,
			 uint8_t br, uint8_t bg, uint8_t bb)
{
	struct uterm_drm3d_video *v3d;
	unsigned int sw, sh, tmp, width, height, i;
	float mat[16];
	float vertices[6 * 2], texpos[6 * 2], fgcol[3], bgcol[3];
	int ret;
	uint8_t *packed, *src, *dst;

	if (!buf || buf->format != UTERM_FORMAT_GREY)
		return -EINVAL;

	v3d = uterm_drm_video_get_data(disp->video);
	ret = uterm_drm3d_display_use(disp, NULL);
	if (ret)
		return ret;
	ret = init_shaders(disp->video);
	if (ret)
		return ret;

	sw = uterm_drm_mode_get_width(disp->current_mode);
	sh = uterm_drm_mode_get_height(disp->current_mode);

	vertices[0] = -1.0;
	vertices[1] = -1.0;
	vertices[2] = -1.0;
	vertices[3] = +1.0;
	vertices[4] = +1.0;
	vertices[5] = +1.0;

	vertices[6] = -1.0;
	vertices[7] = -1.0;
	vertices[8] = +1.0;
	vertices[9] = +1.0;
	vertices[10] = +1.0;
	vertices[11] = -1.0;

	texpos[0] = 0.0;
	texpos[1] = 1.0;
	texpos[2] = 0.0;
	texpos[3] = 0.0;
	texpos[4] = 1.0;
	texpos[5] = 0.0;

	texpos[6] = 0.0;
	texpos[7] = 1.0;
	texpos[8] = 1.0;
	texpos[9] = 0.0;
	texpos[10] = 1.0;
	texpos[11] = 1.0;

	fgcol[0] = fr / 255.0;
	fgcol[1] = fg / 255.0;
	fgcol[2] = fb / 255.0;
	bgcol[0] = br / 255.0;
	bgcol[1] = bg / 255.0;
	bgcol[2] = bb / 255.0;

	tmp = x + buf->width;
	if (tmp < x || x >= sw)
		return -EINVAL;
	if (tmp > sw)
		width = sw - x;
	else
		width = buf->width;

	tmp = y + buf->height;
	if (tmp < y || y >= sh)
		return -EINVAL;
	if (tmp > sh)
		height = sh - y;
	else
		height = buf->height;

	glViewport(x, sh - y - height, width, height);
	glDisable(GL_BLEND);

	gl_shader_use(v3d->blend_shader);

	gl_m4_identity(mat);
	glUniformMatrix4fv(v3d->uni_blend_proj, 1, GL_FALSE, mat);

	glUniform3fv(v3d->uni_blend_fgcol, 1, fgcol);
	glUniform3fv(v3d->uni_blend_bgcol, 1, bgcol);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, v3d->tex);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

	if (v3d->supports_rowlen) {
		glPixelStorei(GL_UNPACK_ROW_LENGTH, buf->stride);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
			     GL_ALPHA, GL_UNSIGNED_BYTE, buf->data);
		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
	} else if (buf->stride == width) {
		glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
			     GL_ALPHA, GL_UNSIGNED_BYTE, buf->data);
	} else {
		packed = malloc(width * height);
		if (!packed)
			return -ENOMEM;

		src = buf->data;
		dst = packed;
		for (i = 0; i < height; ++i) {
			memcpy(dst, src, width);
			dst += width;
			src += buf->stride;
		}

		glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
			     GL_ALPHA, GL_UNSIGNED_BYTE, packed);

		free(packed);
	}

	glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
	glUniform1i(v3d->uni_blend_tex, 0);

	glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, texpos);
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);
	glDrawArrays(GL_TRIANGLES, 0, 6);
	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);

	if (gl_has_error(v3d->blend_shader)) {
		log_warning("GL error");
		return -EFAULT;
	}

	return 0;
}
Example #5
0
static void kmscon_buffer_draw(struct kmscon_buffer *buf,
				struct font_screen *fscr)
{
	unsigned int i, j, k, num;
	struct line *iter, *line = NULL;
	struct cell *cell;
	int idx;
	float m[16];

	if (!buf || !fscr)
		return;

	font_screen_draw_start(fscr);

	iter = buf->position;
	k = 0;
	idx = 0;
	for (i = 0; i < buf->size_y; ++i) {
		if (iter) {
			line = iter;
			iter = iter->next;
		} else {
			if (idx == 0) {
				if (k < buf->mtop_y) {
					line = buf->mtop_buf[k];
				} else {
					k = 0;
					idx = 1;
				}
			}
			if (idx == 1) {
				if (k < buf->scroll_y) {
					line = buf->scroll_buf[k];
				} else {
					k = 0;
					idx = 2;
				}
			}
			if (idx == 2) {
				if (k < buf->mbottom_y)
					line = buf->mbottom_buf[k];
				else
					break;
			}
			k++;
		}

		if (!line)
			continue;

		if (line->size < buf->size_x)
			num = line->size;
		else
			num = buf->size_x;

		for (j = 0; j < num; ++j) {
			cell = &line->cells[j];
			font_screen_draw_char(fscr, cell->ch, j, i, 1, 1);
		}
	}

	gl_m4_identity(m);
	font_screen_draw_perform(fscr, m);
}