Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • mesa/kmscube
  • rantogno/kmscube
  • allocator/kmscube
  • mvicomoya/kmscube
  • ds-hwang/kmscube
  • jianhuilee/kmscube
  • lyudess/kmscube
  • robclark/kmscube
  • strassek/kmscube
  • borneoa/kmscube
  • alex.kanavin/kmscube
  • ezequielgarcia/kmscube
  • lemon.py/kmscube
  • afd/kmscube
  • KhaledEmaraDev/kmscube
  • dv1/kmscube
  • nirmoy/kmscube
  • cubanismo/kmscube
  • ayaka/kmscube
  • antonovitch/kmscube
  • vitalyp/kmscube
  • anholt/kmscube
  • festevam/kmscube
  • austriancoder/kmscube
  • Yaong/kmscube
  • tagr/kmscube
  • nroberts/kmscube
  • lynxeye/kmscube
  • gediz/kmscube
  • dhobsong/kmscube
  • tantan/kmscube
  • rui/kmscube
  • uniontechWu/kmscube
  • tomstokes/kmscube
  • lfrb/kmscube
  • lauramazzuca21/kmscube
  • bbrezillon/kmscube
  • larumbe/kmscube
  • asahilina/kmscube
  • tq-steina/kmscube
  • moiman/kmscube
  • enunes/kmscube
  • lumag/kmscube
  • ralphcampbell/kmscube
  • oreaus/kmscube
  • eric/kmscube
  • bbatson/kmscube
  • swick/kmscube
  • mairacanal/kmscube
  • hugues.fruchet/kmscube
  • ericsmith/kmscube
  • maccraft/kmscube
52 results
Show changes
Commits on Source (5)
workflow:
rules:
# do not duplicate pipelines on merge pipelines
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push"
when: never
# Everything else gets a pipeline
- when: always
.meson: .meson:
stage: build stage: build
script: script:
...@@ -10,7 +18,7 @@ ...@@ -10,7 +18,7 @@
latest-meson: latest-meson:
extends: .meson extends: .meson
image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/archlinux:base-devel image: archlinux:base-devel
before_script: before_script:
- pacman -Syu --noconfirm --needed - pacman -Syu --noconfirm --needed
meson meson
...@@ -22,7 +30,7 @@ latest-meson: ...@@ -22,7 +30,7 @@ latest-meson:
oldest-meson: oldest-meson:
extends: .meson extends: .meson
image: $CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX/debian:stable image: debian:stable
before_script: before_script:
- printf > /etc/dpkg/dpkg.cfg.d/99-exclude-cruft "%s\n" - printf > /etc/dpkg/dpkg.cfg.d/99-exclude-cruft "%s\n"
'path-exclude=/usr/share/doc/*' 'path-exclude=/usr/share/doc/*'
......
...@@ -175,6 +175,7 @@ enum mode { ...@@ -175,6 +175,7 @@ enum mode {
const struct egl * init_cube_smooth(const struct gbm *gbm, int samples); const struct egl * init_cube_smooth(const struct gbm *gbm, int samples);
const struct egl * init_cube_tex(const struct gbm *gbm, enum mode mode, int samples); const struct egl * init_cube_tex(const struct gbm *gbm, enum mode mode, int samples);
const struct egl * init_cube_gears(const struct gbm *gbm, int samples);
#ifdef HAVE_GLES3 #ifdef HAVE_GLES3
const struct egl * init_cube_shadertoy(const struct gbm *gbm, const char *shadertoy, int samples); const struct egl * init_cube_shadertoy(const struct gbm *gbm, const char *shadertoy, int samples);
......
/*
* Copyright (c) 2023 Scott Moreau <oreaus@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#define _GNU_SOURCE /* for sincos */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <math.h>
#include <GL/gl.h>
#include "common.h"
#include "esUtil.h"
#define STRIPS_PER_TOOTH 7
#define VERTICES_PER_TOOTH 46
#define GEAR_VERTEX_STRIDE 6
/* Each vertex consist of GEAR_VERTEX_STRIDE GLfloat attributes */
typedef GLfloat GearVertex[GEAR_VERTEX_STRIDE];
struct gears_framebuffer {
GLuint fb;
GLuint db;
GLuint cb_tex;
GLuint db_tex;
};
static struct {
struct egl egl;
struct gears_framebuffer gears_fb;
GLfloat aspect;
const struct gbm *gbm;
GLuint program_face, program_gears;
GLint modelviewmatrix, modelviewprojectionmatrix, normalmatrix;
GLint in_position, in_normal, in_texcoord;
GLint texture;
GLuint vbo;
GLuint positionsoffset, texcoordsoffset, normalsoffset;
} gl;
/**
* Struct representing a gear.
*/
struct gear {
/** The array of vertices comprising the gear */
GearVertex *vertices;
/** The number of vertices comprising the gear */
int nvertices;
/** The Vertex Buffer Object holding the vertices in the graphics card */
GLuint vbo;
};
/** The gears */
static struct gear *gear1, *gear2, *gear3;
/** The current gear rotation angle */
static GLfloat angle = 0.0;
/** The location of the gears shader uniforms */
static GLuint
modelview_projection_matrix_location,
normal_matrix_location,
material_color_location,
position_location,
normals_location;
/** The gears projection matrix */
static ESMatrix gears_projection_matrix;
/**
* Fills a gear vertex.
*
* @param v the vertex to fill
* @param x the x coordinate
* @param y the y coordinate
* @param z the z coortinate
* @param n pointer to the normal table
*
* @return the operation error code
*/
static GearVertex *
vert(GearVertex *v, GLfloat x, GLfloat y, GLfloat z, GLfloat n[3])
{
v[0][0] = x;
v[0][1] = y;
v[0][2] = z;
v[0][3] = n[0];
v[0][4] = n[1];
v[0][5] = n[2];
return v + 1;
}
/**
* Create a gear wheel.
*
* @param inner_radius radius of hole at center
* @param outer_radius radius at center of teeth
* @param width width of gear
* @param teeth number of teeth
* @param tooth_depth depth of tooth
*
* @return pointer to the constructed struct gear
*/
static struct gear *
create_gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
GLint teeth, GLfloat tooth_depth)
{
GLfloat r0, r1, r2;
GLfloat da;
GearVertex *v;
struct gear *gear;
double s[5], c[5];
GLfloat normal[3];
int cur_strip_start = 0;
int i;
/* Allocate memory for the gear */
gear = malloc(sizeof *gear);
if (gear == NULL)
return NULL;
/* Calculate the radii used in the gear */
r0 = inner_radius;
r1 = outer_radius - tooth_depth / 2.0;
r2 = outer_radius + tooth_depth / 2.0;
da = 2.0 * M_PI / teeth / 4.0;
/* the first tooth doesn't need the first strip-restart sequence */
assert(teeth > 0);
gear->nvertices = VERTICES_PER_TOOTH + (VERTICES_PER_TOOTH + 2) * (teeth - 1);
/* Allocate memory for the vertices */
gear->vertices = calloc(gear->nvertices, sizeof(*gear->vertices));
v = gear->vertices;
for (i = 0; i < teeth; i++) {
/* Calculate needed sin/cos for varius angles */
sincos(i * 2.0 * M_PI / teeth, &s[0], &c[0]);
sincos(i * 2.0 * M_PI / teeth + da, &s[1], &c[1]);
sincos(i * 2.0 * M_PI / teeth + da * 2, &s[2], &c[2]);
sincos(i * 2.0 * M_PI / teeth + da * 3, &s[3], &c[3]);
sincos(i * 2.0 * M_PI / teeth + da * 4, &s[4], &c[4]);
/* A set of macros for making the creation of the gears easier */
#define GEAR_POINT(r, da) { (r) * c[(da)], (r) * s[(da)] }
#define SET_NORMAL(x, y, z) do { \
normal[0] = (x); normal[1] = (y); normal[2] = (z); \
} while(0)
#define GEAR_VERT(v, point, sign) vert((v), p[(point)].x, p[(point)].y, (sign) * width * 0.5, normal)
#define START_STRIP do { \
cur_strip_start = (v - gear->vertices); \
if (cur_strip_start) \
v += 2; \
} while(0);
/* emit prev last vertex
emit first vertex */
#define END_STRIP do { \
if (cur_strip_start) { \
memcpy(gear->vertices + cur_strip_start, \
gear->vertices + (cur_strip_start - 1), sizeof(GearVertex)); \
memcpy(gear->vertices + cur_strip_start + 1, \
gear->vertices + (cur_strip_start + 2), sizeof(GearVertex)); \
} \
} while (0)
#define QUAD_WITH_NORMAL(p1, p2) do { \
SET_NORMAL((p[(p1)].y - p[(p2)].y), -(p[(p1)].x - p[(p2)].x), 0); \
v = GEAR_VERT(v, (p1), -1); \
v = GEAR_VERT(v, (p1), 1); \
v = GEAR_VERT(v, (p2), -1); \
v = GEAR_VERT(v, (p2), 1); \
} while(0)
struct point {
GLfloat x;
GLfloat y;
};
/* Create the 7 points (only x,y coords) used to draw a tooth */
struct point p[7] = {
GEAR_POINT(r2, 1), // 0
GEAR_POINT(r2, 2), // 1
GEAR_POINT(r1, 0), // 2
GEAR_POINT(r1, 3), // 3
GEAR_POINT(r0, 0), // 4
GEAR_POINT(r1, 4), // 5
GEAR_POINT(r0, 4), // 6
};
/* Front face */
START_STRIP;
SET_NORMAL(0, 0, 1.0);
v = GEAR_VERT(v, 0, +1);
v = GEAR_VERT(v, 1, +1);
v = GEAR_VERT(v, 2, +1);
v = GEAR_VERT(v, 3, +1);
v = GEAR_VERT(v, 4, +1);
v = GEAR_VERT(v, 5, +1);
v = GEAR_VERT(v, 6, +1);
END_STRIP;
/* Back face */
START_STRIP;
SET_NORMAL(0, 0, -1.0);
v = GEAR_VERT(v, 0, -1);
v = GEAR_VERT(v, 1, -1);
v = GEAR_VERT(v, 2, -1);
v = GEAR_VERT(v, 3, -1);
v = GEAR_VERT(v, 4, -1);
v = GEAR_VERT(v, 5, -1);
v = GEAR_VERT(v, 6, -1);
END_STRIP;
/* Outer face */
START_STRIP;
QUAD_WITH_NORMAL(0, 2);
END_STRIP;
START_STRIP;
QUAD_WITH_NORMAL(1, 0);
END_STRIP;
START_STRIP;
QUAD_WITH_NORMAL(3, 1);
END_STRIP;
START_STRIP;
QUAD_WITH_NORMAL(5, 3);
END_STRIP;
/* Inner face */
START_STRIP;
SET_NORMAL(-c[0], -s[0], 0);
v = GEAR_VERT(v, 4, -1);
v = GEAR_VERT(v, 4, 1);
SET_NORMAL(-c[4], -s[4], 0);
v = GEAR_VERT(v, 6, -1);
v = GEAR_VERT(v, 6, 1);
END_STRIP;
}
assert(gear->nvertices == (v - gear->vertices));
/* Store the vertices in a vertex buffer object (VBO) */
glGenBuffers(1, &gear->vbo);
glBindBuffer(GL_ARRAY_BUFFER, gear->vbo);
glBufferData(GL_ARRAY_BUFFER, gear->nvertices * sizeof(GearVertex),
gear->vertices, GL_STATIC_DRAW);
return gear;
}
static const GLfloat vVertices[] = {
// front
-1.0f, -1.0f, +1.0f,
+1.0f, -1.0f, +1.0f,
-1.0f, +1.0f, +1.0f,
+1.0f, +1.0f, +1.0f,
// back
+1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
+1.0f, +1.0f, -1.0f,
-1.0f, +1.0f, -1.0f,
// right
+1.0f, -1.0f, +1.0f,
+1.0f, -1.0f, -1.0f,
+1.0f, +1.0f, +1.0f,
+1.0f, +1.0f, -1.0f,
// left
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, +1.0f,
-1.0f, +1.0f, -1.0f,
-1.0f, +1.0f, +1.0f,
// top
-1.0f, +1.0f, +1.0f,
+1.0f, +1.0f, +1.0f,
-1.0f, +1.0f, -1.0f,
+1.0f, +1.0f, -1.0f,
// bottom
-1.0f, -1.0f, -1.0f,
+1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, +1.0f,
+1.0f, -1.0f, +1.0f,
};
static const GLfloat vTexCoords[] = {
//front
1.0f, 1.0f,
0.0f, 1.0f,
1.0f, 0.0f,
0.0f, 0.0f,
//back
1.0f, 1.0f,
0.0f, 1.0f,
1.0f, 0.0f,
0.0f, 0.0f,
//right
1.0f, 1.0f,
0.0f, 1.0f,
1.0f, 0.0f,
0.0f, 0.0f,
//left
1.0f, 1.0f,
0.0f, 1.0f,
1.0f, 0.0f,
0.0f, 0.0f,
//top
1.0f, 1.0f,
0.0f, 1.0f,
1.0f, 0.0f,
0.0f, 0.0f,
//bottom
1.0f, 0.0f,
0.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
};
static const GLfloat vNormals[] = {
// front
+0.0f, +0.0f, +1.0f, // forward
+0.0f, +0.0f, +1.0f, // forward
+0.0f, +0.0f, +1.0f, // forward
+0.0f, +0.0f, +1.0f, // forward
// back
+0.0f, +0.0f, -1.0f, // backward
+0.0f, +0.0f, -1.0f, // backward
+0.0f, +0.0f, -1.0f, // backward
+0.0f, +0.0f, -1.0f, // backward
// right
+1.0f, +0.0f, +0.0f, // right
+1.0f, +0.0f, +0.0f, // right
+1.0f, +0.0f, +0.0f, // right
+1.0f, +0.0f, +0.0f, // right
// left
-1.0f, +0.0f, +0.0f, // left
-1.0f, +0.0f, +0.0f, // left
-1.0f, +0.0f, +0.0f, // left
-1.0f, +0.0f, +0.0f, // left
// top
+0.0f, +1.0f, +0.0f, // up
+0.0f, +1.0f, +0.0f, // up
+0.0f, +1.0f, +0.0f, // up
+0.0f, +1.0f, +0.0f, // up
// bottom
+0.0f, -1.0f, +0.0f, // down
+0.0f, -1.0f, +0.0f, // down
+0.0f, -1.0f, +0.0f, // down
+0.0f, -1.0f, +0.0f // down
};
static const char gears_vertex_shader[] =
"attribute vec3 position; \n"
"attribute vec3 normal; \n"
" \n"
"uniform mat4 ModelViewProjectionMatrix; \n"
"uniform mat4 NormalMatrix; \n"
"vec4 LightSourcePosition = vec4(2.0, 2.0, 20.0, 0.0); \n"
"uniform vec4 MaterialColor; \n"
" \n"
"varying vec4 Color; \n"
" \n"
"void main(void) \n"
"{ \n"
" // Transform the normal to eye coordinates \n"
" vec3 N = normalize(vec3(NormalMatrix * vec4(normal, 1.0))); \n"
" \n"
" // The LightSourcePosition is actually its direction for directional light \n"
" vec3 L = normalize(LightSourcePosition.xyz); \n"
" \n"
" float diffuse = max(dot(N, L), 0.0); \n"
" float ambient = 0.2; \n"
" \n"
" // Multiply the diffuse value by the vertex color (which is fixed in this case) \n"
" // to get the actual color that we will use to draw this vertex with \n"
" Color = vec4((ambient + diffuse) * MaterialColor.xyz, 1.0); \n"
" \n"
" // Transform the position to clip coordinates \n"
" gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0); \n"
"}";
static const char gears_fragment_shader[] =
"precision mediump float; \n"
"varying vec4 Color; \n"
" \n"
"void main(void) \n"
"{ \n"
" gl_FragColor = Color; \n"
"}";
static const char *cube_vertex_shader =
"uniform mat4 modelviewMatrix; \n"
"uniform mat4 modelviewprojectionMatrix; \n"
"uniform mat3 normalMatrix; \n"
" \n"
"attribute vec4 in_position; \n"
"attribute vec3 in_normal; \n"
"attribute vec2 in_texcoord; \n"
" \n"
"vec4 lightSource = vec4(2.0, 2.0, 20.0, 0.0); \n"
" \n"
"varying vec4 vVaryingColor; \n"
"varying vec2 vTexCoord; \n"
" \n"
"void main() \n"
"{ \n"
" gl_Position = modelviewprojectionMatrix * in_position; \n"
" vec3 vEyeNormal = normalMatrix * in_normal; \n"
" vec4 vPosition4 = modelviewMatrix * in_position; \n"
" vec3 vPosition3 = vPosition4.xyz / vPosition4.w; \n"
" vec3 vLightDir = normalize(lightSource.xyz - vPosition3); \n"
" float diff = max(0.0, dot(vEyeNormal, vLightDir)); \n"
" vVaryingColor = vec4(diff * vec3(1.0, 1.0, 1.0), 1.0); \n"
" vTexCoord = in_texcoord; \n"
"} \n";
static const char *cube_fragment_shader =
"precision mediump float; \n"
" \n"
"uniform sampler2D uTex; \n"
" \n"
"varying vec4 vVaryingColor; \n"
"varying vec2 vTexCoord; \n"
" \n"
"void main() \n"
"{ \n"
" if (vTexCoord.x < 0.01 || vTexCoord.x > 0.99 || \n"
" vTexCoord.y < 0.01 || vTexCoord.y > 0.99) \n"
" gl_FragColor = vec4(0.7, 0.7, 0.7, 1.0); \n"
" else \n"
" gl_FragColor = vVaryingColor * texture2D(uTex, vTexCoord); \n"
"} \n";
static const uint32_t texw = 512, texh = 512;
static void
gears_framebuffer_destroy()
{
glDeleteTextures(1, &gl.gears_fb.cb_tex);
glDeleteTextures(1, &gl.gears_fb.db_tex);
glDeleteRenderbuffers(1, &gl.gears_fb.db);
glDeleteFramebuffers(1, &gl.gears_fb.fb);
}
static bool
gears_framebuffer_create()
{
glGenTextures(1, &gl.gears_fb.cb_tex);
glBindTexture(GL_TEXTURE_2D, gl.gears_fb.cb_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texw, texh, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glGenTextures(1, &gl.gears_fb.db_tex);
glBindTexture(GL_TEXTURE_2D, gl.gears_fb.db_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, texw, texh, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);
glGenFramebuffers(1, &gl.gears_fb.fb);
glBindFramebuffer(GL_FRAMEBUFFER, gl.gears_fb.fb);
glGenRenderbuffers(1, &gl.gears_fb.db);
glBindRenderbuffer(GL_RENDERBUFFER, gl.gears_fb.db);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, gl.gears_fb.db_tex, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl.gears_fb.cb_tex, 0);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
printf("failed framebuffer check for created target buffer\n");
gears_framebuffer_destroy();
return false;
}
return true;
}
/**
* Draws a gear.
*
* @param gear the gear to draw
* @param transform the current transformation matrix
* @param x the x position to draw the gear at
* @param y the y position to draw the gear at
* @param angle the rotation angle of the gear
* @param color the color of the gear
*/
static void
draw_gear(struct gear *gear, ESMatrix *transform,
GLfloat x, GLfloat y, GLfloat angle, const GLfloat color[4])
{
ESMatrix model_view;
ESMatrix normal_matrix;
ESMatrix model_view_projection;
/* Translate and rotate the gear */
memcpy(&model_view, transform, sizeof(model_view));
esTranslate(&model_view, x, y, 0);
esRotate(&model_view, angle, 0, 0, 1);
/* Create and set the ModelViewProjectionMatrix */
memcpy(&model_view_projection, &gears_projection_matrix.m[0][0], sizeof(model_view_projection));
esMatrixMultiply(&model_view_projection, &model_view, &model_view_projection);
glUniformMatrix4fv(modelview_projection_matrix_location, 1, GL_FALSE,
&model_view_projection.m[0][0]);
/*
* Create and set the NormalMatrix. It's the inverse transpose of the
* ModelView matrix.
*/
memcpy(&normal_matrix, &model_view, sizeof (normal_matrix));
esInvert(&normal_matrix);
esTranspose(&normal_matrix);
glUniformMatrix4fv(normal_matrix_location, 1, GL_FALSE, &normal_matrix.m[0][0]);
/* Set the gear color */
glUniform4fv(material_color_location, 1, color);
/* Set the vertex buffer object to use */
glBindBuffer(GL_ARRAY_BUFFER, gear->vbo);
/* Set up the position of the attributes in the vertex buffer object */
glVertexAttribPointer(position_location, 3, GL_FLOAT, GL_FALSE,
6 * sizeof(GLfloat), 0);
glVertexAttribPointer(normals_location, 3, GL_FLOAT, GL_FALSE,
6 * sizeof(GLfloat), (GLfloat *) 0 + 3);
/* Enable the attributes */
glEnableVertexAttribArray(position_location);
glEnableVertexAttribArray(normals_location);
/* Draw the triangle strips that comprise the gear */
glDrawArrays(GL_TRIANGLE_STRIP, 0, gear->nvertices);
/* Disable the attributes */
glDisableVertexAttribArray(position_location);
glDisableVertexAttribArray(normals_location);
}
static void
draw_gears(unsigned i)
{
int current_fb;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &current_fb);
static const GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
static const GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
static const GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
ESMatrix transform;
esMatrixLoadIdentity(&transform);
static double tRot0 = -1.0;
struct timeval tv;
gettimeofday(&tv, NULL);
double ms = tv.tv_sec * 1000 + tv.tv_usec / 1000;
double dt, t = ms / 1000.0;
if (tRot0 < 0.0)
tRot0 = t;
dt = t - tRot0;
tRot0 = t;
/* advance rotation for next frame */
angle += 70.0 * dt; /* 70 degrees per second */
if (angle > 3600.0)
angle -= 3600.0;
/* Translate the view */
esTranslate(&transform, 0, 0, -40);
assert(gears_framebuffer_create());
glViewport(0, 0, texw, texh);
glClearColor(0.5, 0.5, 0.5, 1.0);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(gl.program_gears);
draw_gear(gear1, &transform, -3.0, -2.0, angle, red);
draw_gear(gear2, &transform, 3.1, -2.0, -2 * angle - 9.0, green);
draw_gear(gear3, &transform, -3.1, 4.2, -2 * angle - 25.0, blue);
glBindFramebuffer(GL_FRAMEBUFFER, current_fb);
glBindTexture(GL_TEXTURE_2D, gl.gears_fb.cb_tex);
glUseProgram(gl.program_face);
glBindBuffer(GL_ARRAY_BUFFER, gl.vbo);
glEnableVertexAttribArray(gl.in_position);
glEnableVertexAttribArray(gl.in_normal);
glEnableVertexAttribArray(gl.in_texcoord);
glViewport(0, 0, gl.gbm->width, gl.gbm->height);
ESMatrix modelview;
/* clear the color buffer */
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
esMatrixLoadIdentity(&modelview);
esTranslate(&modelview, 0.0f, 0.0f, -8.0f);
esRotate(&modelview, 45.0f + (0.25f * i), 1.0f, 0.0f, 0.0f);
esRotate(&modelview, 45.0f - (0.5f * i), 0.0f, 1.0f, 0.0f);
esRotate(&modelview, 10.0f + (0.15f * i), 0.0f, 0.0f, 1.0f);
ESMatrix projection;
esFrustum(&projection, -2.8f, +2.8f, -2.8f * gl.aspect, +2.8f * gl.aspect, 6.0f, 10.0f);
ESMatrix modelviewprojection;
esMatrixLoadIdentity(&modelviewprojection);
esMatrixMultiply(&modelviewprojection, &modelview, &projection);
float normal[9];
normal[0] = modelview.m[0][0];
normal[1] = modelview.m[0][1];
normal[2] = modelview.m[0][2];
normal[3] = modelview.m[1][0];
normal[4] = modelview.m[1][1];
normal[5] = modelview.m[1][2];
normal[6] = modelview.m[2][0];
normal[7] = modelview.m[2][1];
normal[8] = modelview.m[2][2];
glUniformMatrix4fv(gl.modelviewmatrix, 1, GL_FALSE, &modelview.m[0][0]);
glUniformMatrix4fv(gl.modelviewprojectionmatrix, 1, GL_FALSE, &modelviewprojection.m[0][0]);
glUniformMatrix3fv(gl.normalmatrix, 1, GL_FALSE, normal);
glUniform1i(gl.texture, 0); /* '0' refers to texture unit 0. */
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 16, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 20, 4);
glUseProgram(0);
glDisableVertexAttribArray(gl.in_position);
glDisableVertexAttribArray(gl.in_normal);
glDisableVertexAttribArray(gl.in_texcoord);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
gears_framebuffer_destroy();
}
const struct egl *
init_cube_gears(const struct gbm *gbm, int samples)
{
int ret;
ret = init_egl(&gl.egl, gbm, samples);
if (ret)
return NULL;
if (egl_check(&gl.egl, eglCreateImageKHR) ||
egl_check(&gl.egl, glEGLImageTargetTexture2DOES) ||
egl_check(&gl.egl, eglDestroyImageKHR))
return NULL;
gl.aspect = (GLfloat)(gbm->height) / (GLfloat)(gbm->width);
gl.gbm = gbm;
ret = create_program(cube_vertex_shader, cube_fragment_shader);
if (ret < 0)
return NULL;
gl.program_face = ret;
gl.in_position = 0;
gl.in_normal = 1;
gl.in_texcoord = 2;
glBindAttribLocation(gl.program_face, gl.in_position, "in_position");
glBindAttribLocation(gl.program_face, gl.in_normal, "in_normal");
glBindAttribLocation(gl.program_face, gl.in_texcoord, "in_texcoord");
ret = link_program(gl.program_face);
if (ret)
return NULL;
glUseProgram(gl.program_face);
gl.modelviewmatrix = glGetUniformLocation(gl.program_face, "modelviewMatrix");
gl.modelviewprojectionmatrix = glGetUniformLocation(gl.program_face, "modelviewprojectionMatrix");
gl.normalmatrix = glGetUniformLocation(gl.program_face, "normalMatrix");
gl.texture = glGetUniformLocation(gl.program_face, "uTex");
glViewport(0, 0, gbm->width, gbm->height);
glEnable(GL_CULL_FACE);
gl.positionsoffset = 0;
gl.texcoordsoffset = sizeof(vVertices);
gl.normalsoffset = sizeof(vVertices) + sizeof(vTexCoords);
glGenBuffers(1, &gl.vbo);
glBindBuffer(GL_ARRAY_BUFFER, gl.vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vVertices) + sizeof(vTexCoords) + sizeof(vNormals), 0, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, gl.positionsoffset, sizeof(vVertices), &vVertices[0]);
glBufferSubData(GL_ARRAY_BUFFER, gl.texcoordsoffset, sizeof(vTexCoords), &vTexCoords[0]);
glBufferSubData(GL_ARRAY_BUFFER, gl.normalsoffset, sizeof(vNormals), &vNormals[0]);
glVertexAttribPointer(gl.in_position, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)(intptr_t)gl.positionsoffset);
glEnableVertexAttribArray(gl.in_position);
glVertexAttribPointer(gl.in_normal, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)(intptr_t)gl.normalsoffset);
glEnableVertexAttribArray(gl.in_normal);
glVertexAttribPointer(gl.in_texcoord, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)(intptr_t)gl.texcoordsoffset);
glEnableVertexAttribArray(gl.in_texcoord);
ret = create_program(gears_vertex_shader, gears_fragment_shader);
if (ret < 0)
return NULL;
gl.program_gears = ret;
position_location = 3;
normals_location = 4;
glBindAttribLocation(gl.program_gears, position_location, "position");
glBindAttribLocation(gl.program_gears, normals_location, "normal");
ret = link_program(gl.program_gears);
if (ret)
return NULL;
glUseProgram(gl.program_gears);
/* Get the locations of the uniforms so we can access them */
modelview_projection_matrix_location = glGetUniformLocation(gl.program_gears, "ModelViewProjectionMatrix");
normal_matrix_location = glGetUniformLocation(gl.program_gears, "NormalMatrix");
material_color_location = glGetUniformLocation(gl.program_gears, "MaterialColor");
/* create the gears */
gear1 = create_gear(1.0, 4.0, 1.0, 20, 0.7);
gear2 = create_gear(0.5, 2.0, 2.0, 10, 0.7);
gear3 = create_gear(1.3, 2.0, 0.5, 10, 0.7);
esFrustum(&gears_projection_matrix, -1.0, 1.0, -1.0, 1.0, 5.0, 60.0);
gl.egl.draw = draw_gears;
return &gl.egl;
}
...@@ -392,12 +392,12 @@ static int get_plane_id(void) ...@@ -392,12 +392,12 @@ static int get_plane_id(void)
} }
const struct drm * init_drm_atomic(const char *device, const char *mode_str, const struct drm * init_drm_atomic(const char *device, const char *mode_str,
unsigned int vrefresh, unsigned int count) int connector_id, unsigned int vrefresh, unsigned int count)
{ {
uint32_t plane_id; uint32_t plane_id;
int ret; int ret;
ret = init_drm(&drm, device, mode_str, vrefresh, count); ret = init_drm(&drm, device, mode_str, connector_id, vrefresh, count);
if (ret) if (ret)
return NULL; return NULL;
......
...@@ -238,8 +238,39 @@ static int find_drm_device(drmModeRes **resources) ...@@ -238,8 +238,39 @@ static int find_drm_device(drmModeRes **resources)
return fd; return fd;
} }
static drmModeConnector * find_drm_connector(int fd, drmModeRes *resources,
int connector_id)
{
drmModeConnector *connector = NULL;
int i;
if (connector_id >= 0) {
if (connector_id >= resources->count_connectors)
return NULL;
connector = drmModeGetConnector(fd, resources->connectors[connector_id]);
if (connector && connector->connection == DRM_MODE_CONNECTED)
return connector;
drmModeFreeConnector(connector);
return NULL;
}
for (i = 0; i < resources->count_connectors; i++) {
connector = drmModeGetConnector(fd, resources->connectors[i]);
if (connector && connector->connection == DRM_MODE_CONNECTED) {
/* it's connected, let's use this! */
break;
}
drmModeFreeConnector(connector);
connector = NULL;
}
return connector;
}
int init_drm(struct drm *drm, const char *device, const char *mode_str, int init_drm(struct drm *drm, const char *device, const char *mode_str,
unsigned int vrefresh, unsigned int count) int connector_id, unsigned int vrefresh, unsigned int count)
{ {
drmModeRes *resources; drmModeRes *resources;
drmModeConnector *connector = NULL; drmModeConnector *connector = NULL;
...@@ -266,15 +297,7 @@ int init_drm(struct drm *drm, const char *device, const char *mode_str, ...@@ -266,15 +297,7 @@ int init_drm(struct drm *drm, const char *device, const char *mode_str,
} }
/* find a connected connector: */ /* find a connected connector: */
for (i = 0; i < resources->count_connectors; i++) { connector = find_drm_connector(drm->fd, resources, connector_id);
connector = drmModeGetConnector(drm->fd, resources->connectors[i]);
if (connector->connection == DRM_MODE_CONNECTED) {
/* it's connected, let's use this! */
break;
}
drmModeFreeConnector(connector);
connector = NULL;
}
if (!connector) { if (!connector) {
/* we could be fancy and listen for hotplug events and wait for /* we could be fancy and listen for hotplug events and wait for
......
...@@ -76,10 +76,10 @@ struct drm_fb { ...@@ -76,10 +76,10 @@ struct drm_fb {
struct drm_fb * drm_fb_get_from_bo(struct gbm_bo *bo); struct drm_fb * drm_fb_get_from_bo(struct gbm_bo *bo);
int init_drm(struct drm *drm, const char *device, const char *mode_str, unsigned int vrefresh, unsigned int count); int init_drm(struct drm *drm, const char *device, const char *mode_str, int connector_id, unsigned int vrefresh, unsigned int count);
int init_drm_render(struct drm *drm, const char *device, const char *mode_str, unsigned int count); int init_drm_render(struct drm *drm, const char *device, const char *mode_str, unsigned int count);
const struct drm * init_drm_legacy(const char *device, const char *mode_str, unsigned int vrefresh, unsigned int count); const struct drm * init_drm_legacy(const char *device, const char *mode_str, int connector_id, unsigned int vrefresh, unsigned int count);
const struct drm * init_drm_atomic(const char *device, const char *mode_str, unsigned int vrefresh, unsigned int count); const struct drm * init_drm_atomic(const char *device, const char *mode_str, int connector_id, unsigned int vrefresh, unsigned int count);
const struct drm * init_drm_offscreen(const char *device, const char *mode_str, unsigned int count); const struct drm * init_drm_offscreen(const char *device, const char *mode_str, unsigned int count);
#endif /* _DRM_COMMON_H */ #endif /* _DRM_COMMON_H */
...@@ -170,11 +170,11 @@ static int legacy_run(const struct gbm *gbm, const struct egl *egl) ...@@ -170,11 +170,11 @@ static int legacy_run(const struct gbm *gbm, const struct egl *egl)
} }
const struct drm * init_drm_legacy(const char *device, const char *mode_str, const struct drm * init_drm_legacy(const char *device, const char *mode_str,
unsigned int vrefresh, unsigned int count) int connector_id, unsigned int vrefresh, unsigned int count)
{ {
int ret; int ret;
ret = init_drm(&drm, device, mode_str, vrefresh, count); ret = init_drm(&drm, device, mode_str, connector_id, vrefresh, count);
if (ret) if (ret)
return NULL; return NULL;
......
...@@ -77,54 +77,29 @@ esTranslate(ESMatrix *result, GLfloat tx, GLfloat ty, GLfloat tz) ...@@ -77,54 +77,29 @@ esTranslate(ESMatrix *result, GLfloat tx, GLfloat ty, GLfloat tz)
void ESUTIL_API void ESUTIL_API
esRotate(ESMatrix *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) esRotate(ESMatrix *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
{ {
GLfloat sinAngle, cosAngle; GLfloat s, c;
GLfloat mag = sqrtf(x * x + y * y + z * z); ESMatrix r;
sinAngle = sinf ( angle * PI / 180.0f ); s = sinf(angle * PI / 180.0f);
cosAngle = cosf ( angle * PI / 180.0f ); c = cosf(angle * PI / 180.0f);
if ( mag > 0.0f ) r.m[0][0] = x * x * (1 - c) + c;
{ r.m[0][1] = y * x * (1 - c) + z * s;
GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs; r.m[0][2] = x * z * (1 - c) - y * s;
GLfloat oneMinusCos; r.m[0][3] = 0;
ESMatrix rotMat; r.m[1][0] = x * y * (1 - c) - z * s;
r.m[1][1] = y * y * (1 - c) + c;
x /= mag; r.m[1][2] = y * z * (1 - c) + x * s;
y /= mag; r.m[1][3] = 0;
z /= mag; r.m[2][0] = x * z * (1 - c) + y * s;
r.m[2][1] = y * z * (1 - c) - x * s;
xx = x * x; r.m[2][2] = z * z * (1 - c) + c;
yy = y * y; r.m[2][3] = 0;
zz = z * z; r.m[3][0] = 0;
xy = x * y; r.m[3][1] = 0;
yz = y * z; r.m[3][2] = 0;
zx = z * x; r.m[3][3] = 1;
xs = x * sinAngle;
ys = y * sinAngle; esMatrixMultiply(result, &r, result);
zs = z * sinAngle;
oneMinusCos = 1.0f - cosAngle;
rotMat.m[0][0] = (oneMinusCos * xx) + cosAngle;
rotMat.m[0][1] = (oneMinusCos * xy) - zs;
rotMat.m[0][2] = (oneMinusCos * zx) + ys;
rotMat.m[0][3] = 0.0F;
rotMat.m[1][0] = (oneMinusCos * xy) + zs;
rotMat.m[1][1] = (oneMinusCos * yy) + cosAngle;
rotMat.m[1][2] = (oneMinusCos * yz) - xs;
rotMat.m[1][3] = 0.0F;
rotMat.m[2][0] = (oneMinusCos * zx) - ys;
rotMat.m[2][1] = (oneMinusCos * yz) + xs;
rotMat.m[2][2] = (oneMinusCos * zz) + cosAngle;
rotMat.m[2][3] = 0.0F;
rotMat.m[3][0] = 0.0F;
rotMat.m[3][1] = 0.0F;
rotMat.m[3][2] = 0.0F;
rotMat.m[3][3] = 1.0F;
esMatrixMultiply( result, &rotMat, result );
}
} }
void ESUTIL_API void ESUTIL_API
...@@ -135,6 +110,8 @@ esFrustum(ESMatrix *result, float left, float right, float bottom, float top, fl ...@@ -135,6 +110,8 @@ esFrustum(ESMatrix *result, float left, float right, float bottom, float top, fl
float deltaZ = farZ - nearZ; float deltaZ = farZ - nearZ;
ESMatrix frust; ESMatrix frust;
esMatrixLoadIdentity(result);
if ( (nearZ <= 0.0f) || (farZ <= 0.0f) || if ( (nearZ <= 0.0f) || (farZ <= 0.0f) ||
(deltaX <= 0.0f) || (deltaY <= 0.0f) || (deltaZ <= 0.0f) ) (deltaX <= 0.0f) || (deltaY <= 0.0f) || (deltaZ <= 0.0f) )
return; return;
...@@ -233,3 +210,49 @@ esMatrixLoadIdentity(ESMatrix *result) ...@@ -233,3 +210,49 @@ esMatrixLoadIdentity(ESMatrix *result)
result->m[3][3] = 1.0f; result->m[3][3] = 1.0f;
} }
void ESUTIL_API
esTranspose(ESMatrix *result)
{
ESMatrix tmp;
tmp.m[0][0] = result->m[0][0];
tmp.m[0][1] = result->m[1][0];
tmp.m[0][2] = result->m[2][0];
tmp.m[0][3] = result->m[3][0];
tmp.m[1][0] = result->m[0][1];
tmp.m[1][1] = result->m[1][1];
tmp.m[1][2] = result->m[2][1];
tmp.m[1][3] = result->m[3][1];
tmp.m[2][0] = result->m[0][2];
tmp.m[2][1] = result->m[1][2];
tmp.m[2][2] = result->m[2][2];
tmp.m[2][3] = result->m[3][2];
tmp.m[3][0] = result->m[0][3];
tmp.m[3][1] = result->m[1][3];
tmp.m[3][2] = result->m[2][3];
tmp.m[3][3] = result->m[3][3];
memcpy(result, &tmp, sizeof(tmp));
}
void ESUTIL_API
esInvert(ESMatrix *result)
{
ESMatrix tmp;
esMatrixLoadIdentity(&tmp);
// Extract and invert the translation part 't'. The inverse of a
// translation matrix can be calculated by negating the translation
// coordinates.
tmp.m[3][0] = -result->m[3][0];
tmp.m[3][1] = -result->m[3][1];
tmp.m[3][2] = -result->m[3][2];
// Invert the rotation part 'r'. The inverse of a rotation matrix is
// equal to its transpose.
result->m[3][0] = result->m[3][1] = result->m[3][2] = 0;
esTranspose(result);
// inv(m) = inv(r) * inv(t)
esMatrixMultiply(result, &tmp, result);
}
...@@ -256,7 +256,7 @@ void ESUTIL_API esTranslate(ESMatrix *result, GLfloat tx, GLfloat ty, GLfloat tz ...@@ -256,7 +256,7 @@ void ESUTIL_API esTranslate(ESMatrix *result, GLfloat tx, GLfloat ty, GLfloat tz
void ESUTIL_API esRotate(ESMatrix *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); void ESUTIL_API esRotate(ESMatrix *result, GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
// //
// \brief multiply matrix specified by result with a perspective matrix and return new matrix in result /// \brief multiply matrix specified by result with a perspective matrix and return new matrix in result
/// \param result Specifies the input matrix. new matrix is returned in result. /// \param result Specifies the input matrix. new matrix is returned in result.
/// \param left, right Coordinates for the left and right vertical clipping planes /// \param left, right Coordinates for the left and right vertical clipping planes
/// \param bottom, top Coordinates for the bottom and top horizontal clipping planes /// \param bottom, top Coordinates for the bottom and top horizontal clipping planes
...@@ -291,11 +291,24 @@ void ESUTIL_API esOrtho(ESMatrix *result, float left, float right, float bottom, ...@@ -291,11 +291,24 @@ void ESUTIL_API esOrtho(ESMatrix *result, float left, float right, float bottom,
void ESUTIL_API esMatrixMultiply(ESMatrix *result, ESMatrix *srcA, ESMatrix *srcB); void ESUTIL_API esMatrixMultiply(ESMatrix *result, ESMatrix *srcA, ESMatrix *srcB);
// //
//// \brief return an identity matrix /// \brief return an identity matrix
//// \param result returns identity matrix /// \param result returns identity matrix
// //
void ESUTIL_API esMatrixLoadIdentity(ESMatrix *result); void ESUTIL_API esMatrixLoadIdentity(ESMatrix *result);
//
/// \brief Transposes a 4x4 matrix.
/// \param result Specifies the matrix to transpose. New matrix is returned in result.
//
void ESUTIL_API esTranspose(ESMatrix *result);
//
/// \brief Inverts a 4x4 matrix.
/// \param result Specifies the input matrix. New matrix is returned in result.
//
void ESUTIL_API esInvert(ESMatrix *result);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -41,15 +41,17 @@ static const struct egl *egl; ...@@ -41,15 +41,17 @@ static const struct egl *egl;
static const struct gbm *gbm; static const struct gbm *gbm;
static const struct drm *drm; static const struct drm *drm;
static const char *shortopts = "Ac:D:f:M:m:Op:S:s:V:v:x"; static const char *shortopts = "Ac:D:f:gM:m:n:Op:S:s:V:v:x";
static const struct option longopts[] = { static const struct option longopts[] = {
{"atomic", no_argument, 0, 'A'}, {"atomic", no_argument, 0, 'A'},
{"count", required_argument, 0, 'c'}, {"count", required_argument, 0, 'c'},
{"device", required_argument, 0, 'D'}, {"device", required_argument, 0, 'D'},
{"format", required_argument, 0, 'f'}, {"format", required_argument, 0, 'f'},
{"gears", no_argument, 0, 'g'},
{"mode", required_argument, 0, 'M'}, {"mode", required_argument, 0, 'M'},
{"modifier", required_argument, 0, 'm'}, {"modifier", required_argument, 0, 'm'},
{"connector_id", required_argument, 0, 'n'},
{"offscreen", no_argument, 0, 'O'}, {"offscreen", no_argument, 0, 'O'},
{"perfcntr", required_argument, 0, 'p'}, {"perfcntr", required_argument, 0, 'p'},
{"samples", required_argument, 0, 's'}, {"samples", required_argument, 0, 's'},
...@@ -61,19 +63,21 @@ static const struct option longopts[] = { ...@@ -61,19 +63,21 @@ static const struct option longopts[] = {
static void usage(const char *name) static void usage(const char *name)
{ {
printf("Usage: %s [-ADfMmSsVvx]\n" printf("Usage: %s [-ADfgMmSsVvx]\n"
"\n" "\n"
"options:\n" "options:\n"
" -A, --atomic use atomic modesetting and fencing\n" " -A, --atomic use atomic modesetting and fencing\n"
" -c, --count run for the specified number of frames\n" " -c, --count=N run for the specified number of frames\n"
" -D, --device=DEVICE use the given device\n" " -D, --device=DEVICE use the given device\n"
" -f, --format=FOURCC framebuffer format\n" " -f, --format=FOURCC framebuffer format\n"
" -g, --gears render gears on each cube face\n"
" -M, --mode=MODE specify mode, one of:\n" " -M, --mode=MODE specify mode, one of:\n"
" smooth - smooth shaded cube (default)\n" " smooth - smooth shaded cube (default)\n"
" rgba - rgba textured cube\n" " rgba - rgba textured cube\n"
" nv12-2img - yuv textured (color conversion in shader)\n" " nv12-2img - yuv textured (color conversion in shader)\n"
" nv12-1img - yuv textured (single nv12 texture)\n" " nv12-1img - yuv textured (single nv12 texture)\n"
" -m, --modifier=MODIFIER hardcode the selected modifier\n" " -m, --modifier=MODIFIER hardcode the selected modifier\n"
" -n, --connector_id=N use connector ID N (see drm_info)\n"
" -O, --offscreen use offscreen rendering (e.g. for render nodes)\n" " -O, --offscreen use offscreen rendering (e.g. for render nodes)\n"
" -p, --perfcntr=LIST sample specified performance counters using\n" " -p, --perfcntr=LIST sample specified performance counters using\n"
" the AMD_performance_monitor extension (comma\n" " the AMD_performance_monitor extension (comma\n"
...@@ -101,7 +105,9 @@ int main(int argc, char *argv[]) ...@@ -101,7 +105,9 @@ int main(int argc, char *argv[])
uint64_t modifier = DRM_FORMAT_MOD_LINEAR; uint64_t modifier = DRM_FORMAT_MOD_LINEAR;
int samples = 0; int samples = 0;
int atomic = 0; int atomic = 0;
int gears = 0;
int offscreen = 0; int offscreen = 0;
int connector_id = -1;
int opt; int opt;
unsigned int len; unsigned int len;
unsigned int vrefresh = 0; unsigned int vrefresh = 0;
...@@ -139,6 +145,9 @@ int main(int argc, char *argv[]) ...@@ -139,6 +145,9 @@ int main(int argc, char *argv[])
fourcc[2], fourcc[3]); fourcc[2], fourcc[3]);
break; break;
} }
case 'g':
gears = 1;
break;
case 'M': case 'M':
if (strcmp(optarg, "smooth") == 0) { if (strcmp(optarg, "smooth") == 0) {
mode = SMOOTH; mode = SMOOTH;
...@@ -157,6 +166,9 @@ int main(int argc, char *argv[]) ...@@ -157,6 +166,9 @@ int main(int argc, char *argv[])
case 'm': case 'm':
modifier = strtoull(optarg, NULL, 0); modifier = strtoull(optarg, NULL, 0);
break; break;
case 'n':
connector_id = strtoul(optarg, NULL, 0);
break;
case 'O': case 'O':
offscreen = 1; offscreen = 1;
break; break;
...@@ -204,9 +216,9 @@ int main(int argc, char *argv[]) ...@@ -204,9 +216,9 @@ int main(int argc, char *argv[])
if (offscreen) if (offscreen)
drm = init_drm_offscreen(device, mode_str, count); drm = init_drm_offscreen(device, mode_str, count);
else if (atomic) else if (atomic)
drm = init_drm_atomic(device, mode_str, vrefresh, count); drm = init_drm_atomic(device, mode_str, connector_id, vrefresh, count);
else else
drm = init_drm_legacy(device, mode_str, vrefresh, count); drm = init_drm_legacy(device, mode_str, connector_id, vrefresh, count);
if (!drm) { if (!drm) {
printf("failed to initialize %s DRM\n", printf("failed to initialize %s DRM\n",
offscreen ? "offscreen" : offscreen ? "offscreen" :
...@@ -221,7 +233,9 @@ int main(int argc, char *argv[]) ...@@ -221,7 +233,9 @@ int main(int argc, char *argv[])
return -1; return -1;
} }
if (mode == SMOOTH) if (gears)
egl = init_cube_gears(gbm, samples);
else if (mode == SMOOTH)
egl = init_cube_smooth(gbm, samples); egl = init_cube_smooth(gbm, samples);
else if (mode == VIDEO) else if (mode == VIDEO)
egl = init_cube_video(gbm, video, samples); egl = init_cube_video(gbm, video, samples);
......
...@@ -36,6 +36,7 @@ endif ...@@ -36,6 +36,7 @@ endif
sources = files( sources = files(
'common.c', 'common.c',
'cube-smooth.c', 'cube-smooth.c',
'cube-gears.c',
'cube-tex.c', 'cube-tex.c',
'drm-atomic.c', 'drm-atomic.c',
'drm-common.c', 'drm-common.c',
......
...@@ -950,7 +950,7 @@ int main(int argc, char *argv[]) ...@@ -950,7 +950,7 @@ int main(int argc, char *argv[])
print_summary(); print_summary();
/* no real need for atomic here: */ /* no real need for atomic here: */
drm = init_drm_legacy(device, mode_str, vrefresh, ~0); drm = init_drm_legacy(device, mode_str, -1, vrefresh, ~0);
if (!drm) { if (!drm) {
printf("failed to initialize DRM\n"); printf("failed to initialize DRM\n");
return -1; return -1;
......