コード例 #1
0
ファイル: uterm_drm3d_render.c プロジェクト: Aetf/kmscon
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;
}
コード例 #2
0
ファイル: uterm_drm3d_render.c プロジェクト: Aetf/kmscon
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;
}
コード例 #3
0
ファイル: test_output.c プロジェクト: myra/kmscon
static int set_outputs(struct uterm_video *video)
{
	struct uterm_display *iter;
	int j, ret;
	struct gl_shader *shader;
	struct uterm_screen *screen;

	ret = gl_shader_new(&shader);
	if (ret) {
		log_err("Cannot create shader: %d", ret);
		return ret;
	}

	j = 0;
	iter = uterm_video_get_displays(video);
	for ( ; iter; iter = uterm_display_next(iter)) {
		log_notice("Activating display %d %p...", j, iter);
		ret = uterm_display_activate(iter, NULL);
		if (ret)
			log_err("Cannot activate display %d: %d", j, ret);
		else
			log_notice("Successfully activated display %d", j);

		ret = uterm_display_set_dpms(iter, UTERM_DPMS_ON);
		if (ret)
			log_err("Cannot set DPMS to ON: %d", ret);

		++j;
	}

	iter = uterm_video_get_displays(video);
	for ( ; iter; iter = uterm_display_next(iter)) {
		if (uterm_display_get_state(iter) != UTERM_DISPLAY_ACTIVE)
			continue;

		ret = uterm_screen_new_single(&screen, iter);
		if (ret) {
			log_err("Cannot create temp-screen object: %d", ret);
			continue;
		}

		ret = uterm_screen_use(screen);
		if (ret) {
			log_err("Cannot use screen: %d", ret);
			uterm_screen_unref(screen);
			continue;
		}

		glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		glViewport(0, 0,
				uterm_screen_width(screen),
				uterm_screen_height(screen));

		gl_shader_draw_def(shader, d_vert, d_col, 6);
		if (gl_has_error())
			log_err("GL error occurred");

		ret = uterm_screen_swap(screen);
		if (ret) {
			log_err("Cannot swap screen: %d", ret);
			uterm_screen_unref(screen);
			continue;
		}

		log_notice("Successfully set screen on display %p", iter);
		uterm_screen_unref(screen);
	}

	log_notice("Waiting 5 seconds...");
	ev_eloop_run(eloop, 5000);
	log_notice("Exiting...");

	gl_shader_unref(shader);

	return 0;
}
コード例 #4
0
ファイル: text_gltex.c プロジェクト: tmpvar/kmscon
static int gltex_set(struct kmscon_text *txt)
{
	struct gltex *gt = txt->data;
	int ret;
	static char *attr[] = { "position", "texture_position",
				"fgcolor", "bgcolor" };
	GLint s;
	const char *ext;
	struct uterm_mode *mode;
	bool opengl;

	memset(gt, 0, sizeof(*gt));
	shl_dlist_init(&gt->atlases);

	ret = shl_hashtable_new(&gt->glyphs, shl_direct_hash,
				shl_direct_equal, NULL,
				free_glyph);
	if (ret)
		return ret;

	ret = shl_hashtable_new(&gt->bold_glyphs, shl_direct_hash,
				shl_direct_equal, NULL,
				free_glyph);
	if (ret)
		goto err_htable;

	ret = uterm_display_use(txt->disp, &opengl);
	if (ret < 0 || !opengl) {
		if (ret == -EOPNOTSUPP)
			log_error("display doesn't support hardware-acceleration");
		goto err_bold_htable;
	}

	gl_clear_error();

	ret = gl_shader_new(&gt->shader, gl_static_gltex_vert,
			    gl_static_gltex_frag, attr, 4, log_llog, NULL);
	if (ret)
		goto err_bold_htable;

	gt->uni_proj = gl_shader_get_uniform(gt->shader, "projection");
	gt->uni_atlas = gl_shader_get_uniform(gt->shader, "atlas");
	gt->uni_advance_htex = gl_shader_get_uniform(gt->shader,
						     "advance_htex");
	gt->uni_advance_vtex = gl_shader_get_uniform(gt->shader,
						     "advance_vtex");

	if (gl_has_error(gt->shader)) {
		log_warning("cannot create shader");
		goto err_shader;
	}

	mode = uterm_display_get_current(txt->disp);
	gt->sw = uterm_mode_get_width(mode);
	gt->sh = uterm_mode_get_height(mode);

	txt->cols = gt->sw / FONT_WIDTH(txt);
	txt->rows = gt->sh / FONT_HEIGHT(txt);

	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &s);
	if (s <= 0)
		s = 64;
	else if (s > 2048)
		s = 2048;
	gt->max_tex_size = s;

	gl_clear_error();

	ext = (const char*)glGetString(GL_EXTENSIONS);
	if (ext && strstr((const char*)ext, "GL_EXT_unpack_subimage")) {
		gt->supports_rowlen = true;
	} else {
		log_warning("your GL implementation does not support GL_EXT_unpack_subimage, glyph-rendering may be slower than usual");
	}

	return 0;

err_shader:
	gl_shader_unref(gt->shader);
err_bold_htable:
	shl_hashtable_free(gt->bold_glyphs);
err_htable:
	shl_hashtable_free(gt->glyphs);
	return ret;
}
コード例 #5
0
ファイル: static_gl_shader.c プロジェクト: microcai/kmscon
int gl_shader_new(struct gl_shader **out, const char *vert, const char *frag,
		  char **attr, size_t attr_count, llog_submit_t llog)
{
	struct gl_shader *shader;
	int ret, i;
	char msg[512];
	GLint status = 1;

	if (!out || !vert || !frag)
		return -EINVAL;

	shader = malloc(sizeof(*shader));
	if (!shader)
		return -ENOMEM;
	memset(shader, 0, sizeof(*shader));
	shader->ref = 1;
	shader->llog = llog;

	llog_debug(shader, "new shader");

	shader->vshader = compile_shader(shader, GL_VERTEX_SHADER, vert);
	if (shader->vshader == GL_NONE) {
		ret = -EFAULT;
		goto err_free;
	}

	shader->fshader = compile_shader(shader, GL_FRAGMENT_SHADER, frag);
	if (shader->fshader == GL_NONE) {
		ret = -EFAULT;
		goto err_vshader;
	}

	shader->program = glCreateProgram();
	glAttachShader(shader->program, shader->vshader);
	glAttachShader(shader->program, shader->fshader);

	for (i = 0; i < attr_count; ++i)
		glBindAttribLocation(shader->program, i, attr[i]);

	glLinkProgram(shader->program);
	glGetProgramiv(shader->program, GL_LINK_STATUS, &status);
	if (status == GL_FALSE) {
		msg[0] = 0;
		glGetProgramInfoLog(shader->program, sizeof(msg), NULL, msg);
		llog_warning(shader, "cannot link shader: %s", msg);
		ret = -EFAULT;
		goto err_link;
	}

	if (gl_has_error(shader)) {
		llog_warning(shader, "shader creation failed");
		ret = -EFAULT;
		goto err_link;
	}

	*out = shader;
	return 0;

err_link:
	glDeleteProgram(shader->program);
	glDeleteShader(shader->fshader);
err_vshader:
	glDeleteShader(shader->vshader);
err_free:
	free(shader);
	return ret;
}