So here are the layers that create and load the texture and it’s subsequent rendering:
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
void generate_and_bind_opengl_object(GLint type, GLuint *object_id)
{
*object_id = 0;
switch(type)
{
case GL_ARRAY_BUFFER:
case GL_ELEMENT_ARRAY_BUFFER:
case GL_PIXEL_PACK_BUFFER:
case GL_PIXEL_UNPACK_BUFFER:
case GL_TRANSFORM_FEEDBACK_BUFFER:
glGenBuffers(1, object_id);
glBindBuffer(type, *object_id);
break;
case GL_FRAMEBUFFER:
glGenFramebuffers(1, object_id);
glBindFramebuffer(type, *object_id);
break;
case GL_RENDERBUFFER:
glGenRenderbuffers(1, object_id);
glBindRenderbuffer(type, *object_id);
break;
case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_TEXTURE_3D:
case GL_TEXTURE_1D_ARRAY:
case GL_TEXTURE_2D_ARRAY:
case GL_TEXTURE_CUBE_MAP:
glGenTextures(1, object_id);
glBindTexture(type, *object_id);
OpenGL_error_check(__FILE__, __LINE__, __FUNC__);
break;
case GL_VERTEX_ARRAY:
glGenVertexArrays(1, object_id);
glBindVertexArray(*object_id); // note the different parameters
break;
default:
program_error(__FILE__, __LINE__, __FUNC__,
"unrecognized object type: %d", type);
break;
}
if(*object_id == 0)
{
program_error(__FILE__, __LINE__, __FUNC__,
"generating and binding opengl object failed type: %d", type);
}
OpenGL_error_check(__FILE__, __LINE__, __FUNC__);
}
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
void textureize_image_to_opengl(IMAGE *image)
{
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// Reference the entire image
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); // restore skipping to zero
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // zero means full width!
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
// texturize the 0-th level mipmap
glTexImage2D
(
GL_TEXTURE_2D,
0, // the 0-th level mipmap
GL_RGBA,
image->width, image->length,
0, // NO borders
GL_RGBA, GL_UNSIGNED_BYTE, image->buffer
);
OpenGL_error_check(__FILE__, __LINE__, __FUNC__);
}
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
void generate_bind_textureize_and_activate_opengl_texture(IMAGE *image)
{
if(image->texture_id != 0)
{
// there is a texture already associated with the image
// which should to be deleted
glDeleteTextures(1, &image->texture_id);
}
generate_and_bind_opengl_object(GL_TEXTURE_2D, &image->texture_id);
textureize_image_to_opengl(image);
glActiveTexture(IMAGE_SAMPLER2D + GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, image->texture_id);
}
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
void set_uniform_variable_h4_matrix
(
const char *variable,
bool transpose,
GLfloat *h4_matrix
)
{
GLint location, program_id;
glGetIntegerv(GL_CURRENT_PROGRAM, &program_id); // this is boring !
location = glGetUniformLocation(program_id, variable);
if(location < 0)
{
OpenGL_status_report(__FILE__, __LINE__, __FUNC__,
"failed to locate (to set) uniform variable: '%s'\n\tin program %d",
variable, program_id);
}
glUniformMatrix4fv
(
location, // GLint variable location
1, // GLsizei count only 1
transpose, // GLboolean transpose / don't transpose the matrix?
h4_matrix // GLfloat * pointer to float matrix data
);
}
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
void OpenGL_render_matrix_inverted_image(IMAGE *image)
{
float h4_translation_matrix[16], h4_rotation_matrix[16];
float h4_scale_matrix[16], h4_ortho_matrix[16];
float x, y;
struct timeval us_start_time;
// operate on the lower left corner of the image
x = image->x_pos;
y = image->y_pos;
compute_ortho_matrix_h4(h4_ortho_matrix);
compute_translate_matrix_h4(x, y, h4_translation_matrix);
compute_rotate_matrix_h4(image->dx, image->dy, h4_rotation_matrix);
vertically_reflect_matrix_h4(h4_rotation_matrix); // reflect vertically
compute_scale_matrix_h4(image->width * image->scale, image->length * image->scale, h4_scale_matrix);
set_uniform_variable_h4_matrix("translation_matrix", TRUE, h4_translation_matrix);
set_uniform_variable_h4_matrix("rotation_matrix", FALSE, h4_rotation_matrix);
set_uniform_variable_h4_matrix("scale_matrix", FALSE, h4_scale_matrix);
glDrawArrays(GL_QUADS, 0, 4);
}
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/
// The following is done just once to load the slider image as a texture
// the slider image is 7,680 pixels wide and 2,160 pixels high
generate_bind_textureize_and_activate_opengl_texture(slider);
// The folowing is done 3,840 times to slide the existing image off screen and the
// new image on screen
OpenGL_render_matrix_inverted_image(slider);
/*------------------------------------------------------------------------------
------------------------------------------------------------------------------*/