static gboolean _set_uniform (GQuark field_id, const GValue * value, gpointer user_data) { GstGLShader *shader = user_data; const gchar *field_name = g_quark_to_string (field_id); if (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_INT)) { gst_gl_shader_set_uniform_1i (shader, field_name, g_value_get_int (value)); } else if (G_TYPE_CHECK_VALUE_TYPE ((value), G_TYPE_FLOAT)) { gst_gl_shader_set_uniform_1f (shader, field_name, g_value_get_float (value)); #ifdef HAVE_GRAPHENE } else if (G_TYPE_CHECK_VALUE_TYPE ((value), GRAPHENE_TYPE_VEC2)) { graphene_vec2_t *vec2 = g_value_get_boxed (value); float x = graphene_vec2_get_x (vec2); float y = graphene_vec2_get_y (vec2); gst_gl_shader_set_uniform_2f (shader, field_name, x, y); } else if (G_TYPE_CHECK_VALUE_TYPE ((value), GRAPHENE_TYPE_VEC3)) { graphene_vec3_t *vec3 = g_value_get_boxed (value); float x = graphene_vec3_get_x (vec3); float y = graphene_vec3_get_y (vec3); float z = graphene_vec3_get_z (vec3); gst_gl_shader_set_uniform_3f (shader, field_name, x, y, z); } else if (G_TYPE_CHECK_VALUE_TYPE ((value), GRAPHENE_TYPE_VEC4)) { graphene_vec4_t *vec4 = g_value_get_boxed (value); float x = graphene_vec4_get_x (vec4); float y = graphene_vec4_get_y (vec4); float z = graphene_vec4_get_z (vec4); float w = graphene_vec4_get_w (vec4); gst_gl_shader_set_uniform_4f (shader, field_name, x, y, z, w); } else if (G_TYPE_CHECK_VALUE_TYPE ((value), GRAPHENE_TYPE_MATRIX)) { graphene_matrix_t *matrix = g_value_get_boxed (value); float matrix_f[16]; graphene_matrix_to_float (matrix, matrix_f); gst_gl_shader_set_uniform_matrix_4fv (shader, field_name, 1, FALSE, matrix_f); #endif } else { /* FIXME: Add support for unsigned ints, non 4x4 matrices, etc */ GST_FIXME ("Don't know how to set the \'%s\' paramater. Unknown type", field_name); return TRUE; } return TRUE; }
static void gst_gl_transformation_callback (gpointer stuff) { GstGLFilter *filter = GST_GL_FILTER (stuff); GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter); GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable; GLfloat temp_matrix[16]; gst_gl_context_clear_shader (GST_GL_BASE_FILTER (filter)->context); gl->BindTexture (GL_TEXTURE_2D, 0); gl->ClearColor (0.f, 0.f, 0.f, 1.f); gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gst_gl_shader_use (transformation->shader); gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, transformation->in_tex); gst_gl_shader_set_uniform_1i (transformation->shader, "texture", 0); graphene_matrix_to_float (&transformation->mvp_matrix, temp_matrix); gst_gl_shader_set_uniform_matrix_4fv (transformation->shader, "mvp", 1, GL_FALSE, temp_matrix); if (!transformation->vertex_buffer) { transformation->attr_position = gst_gl_shader_get_attribute_location (transformation->shader, "position"); transformation->attr_texture = gst_gl_shader_get_attribute_location (transformation->shader, "uv"); if (gl->GenVertexArrays) { gl->GenVertexArrays (1, &transformation->vao); gl->BindVertexArray (transformation->vao); } gl->GenBuffers (1, &transformation->vertex_buffer); gl->GenBuffers (1, &transformation->vbo_indices); gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, transformation->vbo_indices); gl->BufferData (GL_ELEMENT_ARRAY_BUFFER, sizeof (indices), indices, GL_STATIC_DRAW); transformation->caps_change = TRUE; } if (gl->GenVertexArrays) gl->BindVertexArray (transformation->vao); if (transformation->caps_change) { _upload_vertices (transformation); _bind_buffer (transformation); if (gl->GenVertexArrays) { gl->BindVertexArray (0); gl->BindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0); gl->BindBuffer (GL_ARRAY_BUFFER, 0); } } else if (!gl->GenVertexArrays) { _bind_buffer (transformation); } gl->DrawElements (GL_TRIANGLE_STRIP, 5, GL_UNSIGNED_SHORT, indices); if (gl->GenVertexArrays) gl->BindVertexArray (0); else _unbind_buffer (transformation); gst_gl_context_clear_shader (GST_GL_BASE_FILTER (filter)->context); transformation->caps_change = FALSE; }
// The MAIN function, from here we start the application and run the game loop int main() { // Init GLFW glfwInit(); // Set all the required options for GLFW glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Create a GLFWwindow object that we can use for GLFW's functions GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", NULL, NULL); glfwMakeContextCurrent(window); // Set the required callback functions glfwSetKeyCallback(window, key_callback); // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions glewExperimental = GL_TRUE; // Initialize GLEW to setup the OpenGL Function pointers glewInit(); // Define the viewport dimensions glViewport(0, 0, WIDTH, HEIGHT); // Setup OpenGL options glEnable(GL_DEPTH_TEST); // Build and compile our shader program shader our_shader = shader_new("shader.vs", "shader.frag"); // Set up vertex data (and buffer(s)) and attribute pointers GLfloat vertices[] = { -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 1.0f, -0.5f, 0.5f, 0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, -0.5f, 1.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.5f, -0.5f, 0.5f, 1.0f, 0.0f, -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, -0.5f, -0.5f, -0.5f, 0.0f, 1.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.5f, 0.5f, -0.5f, 1.0f, 1.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.5f, 0.5f, 0.5f, 1.0f, 0.0f, -0.5f, 0.5f, 0.5f, 0.0f, 0.0f, -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; // World space positions of our cubes graphene_point3d_t cubePositions[] = { GRAPHENE_POINT3D_INIT(0.0f, 0.0f, 0.0f), GRAPHENE_POINT3D_INIT( 2.0f, 5.0f, -15.0f), GRAPHENE_POINT3D_INIT(-1.5f, -2.2f, -2.5f), GRAPHENE_POINT3D_INIT(-3.8f, -2.0f, -12.3f), GRAPHENE_POINT3D_INIT( 2.4f, -0.4f, -3.5f), GRAPHENE_POINT3D_INIT(-1.7f, 3.0f, -7.5f), GRAPHENE_POINT3D_INIT( 1.3f, -2.0f, -2.5f), GRAPHENE_POINT3D_INIT( 1.5f, 2.0f, -2.5f), GRAPHENE_POINT3D_INIT( 1.5f, 0.2f, -1.5f), GRAPHENE_POINT3D_INIT(-1.3f, 1.0f, -1.5f) }; GLuint VBO, VAO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // Position attribute glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); // TexCoord attribute glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(2); glBindVertexArray(0); // Unbind VAO // Load and create a texture GLuint texture1; GLuint texture2; // ==================== // Texture 1 // ==================== glGenTextures(1, &texture1); glBindTexture(GL_TEXTURE_2D, texture1); // All upcoming GL_TEXTURE_2D operations now have effect on our texture object // Set our texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); // Set texture wrapping to GL_REPEAT glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Load, create texture and generate mipmaps int width, height; unsigned char* image = SOIL_load_image("container.jpg", &width, &height, 0, SOIL_LOAD_RGB); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glGenerateMipmap(GL_TEXTURE_2D); SOIL_free_image_data(image); glBindTexture(GL_TEXTURE_2D, 0); // Unbind texture when done, so we won't accidentily mess up our texture. // =================== // Texture 2 // =================== glGenTextures(1, &texture2); glBindTexture(GL_TEXTURE_2D, texture2); // Set our texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Load, create texture and generate mipmaps image = SOIL_load_image("awesomeface.png", &width, &height, 0, SOIL_LOAD_RGB); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glGenerateMipmap(GL_TEXTURE_2D); SOIL_free_image_data(image); glBindTexture(GL_TEXTURE_2D, 0); // Game loop while (!glfwWindowShouldClose(window)) { // Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions glfwPollEvents(); // Render // Clear the colorbuffer glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Bind Textures using texture units glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texture1); glUniform1i(glGetUniformLocation(our_shader.program, "ourTexture1"), 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texture2); glUniform1i(glGetUniformLocation(our_shader.program, "ourTexture2"), 1); // Activate shader shader_use(&our_shader); // Create transformations graphene_matrix_t view; graphene_point3d_t view_point; graphene_matrix_init_translate(&view, graphene_point3d_init(&view_point, 0.0f, 0.0f, -3.0f)); graphene_matrix_t projection; graphene_matrix_init_perspective(&projection, 45.0f, (GLfloat) WIDTH / (GLfloat) HEIGHT, 0.1f, 100.0f); // Get their uniform location GLint modelLoc = glGetUniformLocation(our_shader.program, "model"); GLint viewLoc = glGetUniformLocation(our_shader.program, "view"); GLint projLoc = glGetUniformLocation(our_shader.program, "projection"); // Pass the matrices to the shader GLfloat view_f[16] = {}; graphene_matrix_to_float(&view, view_f); GLfloat proj_f[16] = {}; graphene_matrix_to_float(&projection, proj_f); glUniformMatrix4fv(viewLoc, 1, GL_FALSE, view_f); // Note: currently we set the projection matrix each frame, but since the projection matrix rarely changes it's often best practice to set it outside the main loop only once. glUniformMatrix4fv(projLoc, 1, GL_FALSE, proj_f); glBindVertexArray(VAO); for (GLuint i = 0; i < 10; i++) { // Calculate the model matrix for each object and pass it to shader before drawing graphene_matrix_t model; graphene_matrix_init_translate(&model, &cubePositions[i]); GLfloat angle = 5.0f * i; graphene_vec3_t axis; graphene_vec3_init(&axis, -1.3f, 1.0f, -1.5f); graphene_matrix_rotate(&model, angle, &axis); GLfloat model_f[16] = {}; graphene_matrix_to_float(&model, model_f); glUniformMatrix4fv(modelLoc, 1, GL_FALSE, model_f); glDrawArrays(GL_TRIANGLES, 0, 36); } glBindVertexArray(0); // Swap the screen buffers glfwSwapBuffers(window); } // Properly de-allocate all resources once they've outlived their purpose glDeleteVertexArrays(1, &VAO); glDeleteBuffers(1, &VBO); // Terminate GLFW, clearing any resources allocated by GLFW. glfwTerminate(); return 0; }
/** * graphene_euler_init_from_matrix: * @e: the #graphene_euler_t to initialize * @m: (nullable): a rotation matrix * @order: the order used to apply the rotations * * Initializes a #graphene_euler_t using the given rotation matrix. * * If the #graphene_matrix_t @m is %NULL, the #graphene_euler_t will * be initialized with all angles set to 0. * * Returns: (transfer none): the initialized #graphene_euler_t * * Since: 1.2 */ graphene_euler_t * graphene_euler_init_from_matrix (graphene_euler_t *e, const graphene_matrix_t *m, graphene_euler_order_t order) { float me[16]; float m11, m12, m13; float m21, m22, m23; float m31, m32, m33; float x, y, z; if (m == NULL) return graphene_euler_init_with_order (e, 0.f, 0.f, 0.f, order); graphene_matrix_to_float (m, me); /* isolate the rotation components */ m11 = me[0]; m21 = me[4]; m31 = me[8]; m12 = me[1]; m22 = me[5]; m32 = me[9]; m13 = me[2]; m23 = me[6]; m33 = me[10]; x = y = z = 0.f; e->order = order; switch (graphene_euler_get_order (e)) { case GRAPHENE_EULER_ORDER_XYZ: y = asinf (CLAMP (m13, -1.f, 1.f)); if (fabsf (m13) < 1.f) { x = atan2f (-1.f * m23, m33); z = atan2f (-1.f * m12, m11); } else { x = atan2f (m32, m22); z = 0.f; } break; case GRAPHENE_EULER_ORDER_YXZ: x = asinf (-1.f * CLAMP (m23, -1, 1)); if (fabsf (m23) < 1.f) { y = atan2f (m13, m33); z = atan2f (m21, m22); } else { y = atan2f (-1.f * m31, m11); z = 0.f; } break; case GRAPHENE_EULER_ORDER_ZXY: x = asinf (CLAMP (m32, -1.f, 1.f)); if (fabsf (m32) < 1.f) { y = atan2f (-1.f * m31, m33); z = atan2f (-1.f * m12, m22); } else { y = 0.f; z = atan2f (m21, m11); } break; case GRAPHENE_EULER_ORDER_ZYX: y = asinf (-1.f * CLAMP (m31, -1.f, 1.f)); if (fabsf (m31) < 1.f) { x = atan2f (m32, m33); z = atan2f (m21, m11); } else { x = 0.f; z = atan2f (-1.f * m12, m22); } break; case GRAPHENE_EULER_ORDER_YZX: z = asinf (CLAMP (m21, -1.f, 1.f)); if (fabsf (m21) < 1.f) { x = atan2f (-1.f * m23, m22); y = atan2f (-1.f * m31, m11); } else { x = 0.f; y = atan2f (m13, m33); } break; case GRAPHENE_EULER_ORDER_XZY: z = asinf (-1.f * CLAMP (m12, -1.f, 1.f)); if (fabsf (m12) < 1.f) { x = atan2f (m32, m22); y = atan2f (m13, m11); } else { x = atan2f (-1.f * m23, m33); y = 0.f; } break; case GRAPHENE_EULER_ORDER_DEFAULT: break; } graphene_vec3_init (&e->angles, x, y, z); return e; }
static void gst_gl_transformation_callback (gpointer stuff) { GstGLFilter *filter = GST_GL_FILTER (stuff); GstGLTransformation *transformation = GST_GL_TRANSFORMATION (filter); GstGLFuncs *gl = filter->context->gl_vtable; /* *INDENT-OFF* */ const GLfloat positions[] = { -transformation->aspect, 1.0, 0.0, 1.0, transformation->aspect, 1.0, 0.0, 1.0, transformation->aspect, -1.0, 0.0, 1.0, -transformation->aspect, -1.0, 0.0, 1.0, }; const GLfloat texture_coordinates[] = { 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, }; /* *INDENT-ON* */ GLushort indices[] = { 0, 1, 2, 3, 0 }; GLfloat temp_matrix[16]; GLint attr_position_loc = 0; GLint attr_texture_loc = 0; gst_gl_context_clear_shader (filter->context); gl->BindTexture (GL_TEXTURE_2D, 0); gl->ClearColor (0.f, 0.f, 0.f, 0.f); gl->Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gst_gl_shader_use (transformation->shader); attr_position_loc = gst_gl_shader_get_attribute_location (transformation->shader, "position"); attr_texture_loc = gst_gl_shader_get_attribute_location (transformation->shader, "uv"); /* Load the vertex position */ gl->VertexAttribPointer (attr_position_loc, 4, GL_FLOAT, GL_FALSE, 0, positions); /* Load the texture coordinate */ gl->VertexAttribPointer (attr_texture_loc, 2, GL_FLOAT, GL_FALSE, 0, texture_coordinates); gl->EnableVertexAttribArray (attr_position_loc); gl->EnableVertexAttribArray (attr_texture_loc); gl->ActiveTexture (GL_TEXTURE0); gl->BindTexture (GL_TEXTURE_2D, transformation->in_tex); gst_gl_shader_set_uniform_1i (transformation->shader, "texture", 0); graphene_matrix_to_float (&transformation->mvp_matrix, temp_matrix); gst_gl_shader_set_uniform_matrix_4fv (transformation->shader, "mvp", 1, GL_FALSE, temp_matrix); gl->DrawElements (GL_TRIANGLE_STRIP, 5, GL_UNSIGNED_SHORT, indices); gl->DisableVertexAttribArray (attr_position_loc); gl->DisableVertexAttribArray (attr_texture_loc); gst_gl_context_clear_shader (filter->context); }