3#include <cgv_gl/gl/gl.h>
4#include <cgv/render/frame_buffer.h>
5#include <cgv/render/attribute_array_binding.h>
6#include <cgv/math/ftransform.h>
7#include <cgv/render/shader_program.h>
10#ifndef GL_CLAMP_TO_EDGE
11#define GL_CLAMP_TO_EDGE 0x812F
21float black[4] = { 0, 0, 0, 1 };
22float white[4] = { 1, 1, 1, 1 };
23float gray[4] = { 0.25f, 0.25f, 0.25f, 1 };
24float green[4] = { 0, 1, 0, 1 };
25float brown[4] = { 0.3f, 0.1f, 0, 1 };
26float dark_red[4] = { 0.4f, 0, 0, 1 };
27float cyan[4] = { 0, 1, 1, 1 };
28float yellow[4] = { 1, 1, 0, 1 };
29float red[4] = { 1, 0, 0, 1 };
30float blue[4] = { 0, 0, 1, 1 };
35 static unsigned cf_to_gl[] = {
53 static unsigned cf_to_gl_integer[] = {
59 GL_LUMINANCE_INTEGER_EXT,
60 GL_LUMINANCE_INTEGER_EXT,
61 GL_LUMINANCE_ALPHA_INTEGER_EXT,
62 GL_LUMINANCE_ALPHA_INTEGER_EXT,
74 if (cii == CII_INTEGER)
75 return cf_to_gl_integer[cf];
81 static unsigned ti_to_gl[] = {
102 if (ti_to_gl[ti] == 0) {
103 std::cerr <<
"could not map component type " << ti <<
" to gl type" << std::endl;
104 return GL_UNSIGNED_BYTE;
111 GLint gl_cube_map_target[] = {
112 GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT,
113 GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT,
114 GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT,
115 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT,
116 GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT,
117 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT
119 return gl_cube_map_target[side];
122GLuint gl_tex_dim[] = { GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_CUBE_MAP_EXT };
124bool generate_mipmaps(
unsigned int dim,
bool is_cubemap,
bool is_array, std::string* last_error)
126 if (dim == 0 || dim > 3) {
128 *last_error =
"wrong dimension of texture";
131 if(is_array && (dim < 2 || dim > 3)) {
133 *last_error =
"wrong dimension for array texture";
136 if(is_cubemap && dim != 2) {
138 *last_error =
"wrong dimension for cubemap texture";
143 *last_error =
"automatic generation of mipmaps not supported";
150 glGenerateMipmap(gl_tex_dim[dim-1]);
154static const GLenum gl_std_texture_format_ids[] =
169 GL_LUMINANCE4_ALPHA4,
170 GL_LUMINANCE6_ALPHA2,
171 GL_LUMINANCE8_ALPHA8,
172 GL_LUMINANCE12_ALPHA4,
173 GL_LUMINANCE12_ALPHA12,
174 GL_LUMINANCE16_ALPHA16,
201static const char* std_texture_formats[] = {
228 "uint8[R:3,G:3,B:2]",
240 "uint8[R:5,G:5,B:5,A:1]",
242 "uint16[R:10,G:10,B:10,A:2]",
243 "uint16:12[R,G,B,A]",
247static const GLenum gl_float_texture_format_ids[] =
254 GL_LUMINANCE_ALPHA32F_ARB,
261 GL_LUMINANCE_ALPHA16F_ARB,
265static const char* float_texture_formats[] = {
282static const GLenum gl_snorm_texture_format_ids[] =
290 GL_LUMINANCE_ALPHA_SNORM,
298 GL_LUMINANCE8_ALPHA8_SNORM,
305 GL_LUMINANCE16_SNORM,
306 GL_LUMINANCE16_ALPHA16_SNORM,
310static const char* snorm_texture_formats[] = {
338static const GLenum gl_int_texture_format_ids[] =
343 GL_INTENSITY32UI_EXT,
344 GL_LUMINANCE32UI_EXT,
345 GL_LUMINANCE_ALPHA32UI_EXT,
350 GL_INTENSITY16UI_EXT,
351 GL_LUMINANCE16UI_EXT,
352 GL_LUMINANCE_ALPHA16UI_EXT,
359 GL_LUMINANCE_ALPHA8UI_EXT,
366 GL_LUMINANCE_ALPHA32I_EXT,
373 GL_LUMINANCE_ALPHA16I_EXT,
380 GL_LUMINANCE_ALPHA8I_EXT
383static const char* int_texture_formats[] = {
428static const GLenum gl_depth_format_ids[] =
431 GL_DEPTH_COMPONENT16_ARB,
432 GL_DEPTH_COMPONENT24_ARB,
433 GL_DEPTH_COMPONENT32_ARB
436static const char* depth_formats[] =
445static const GLenum gl_rg_texture_format_ids[] =
481static const char* rg_texture_formats[] = {
526 cf = *palettes->at(0).get_format();
528 std::cout <<
"find best match in std_texture_formats:" << std::endl;
532 unsigned gl_format = gl_std_texture_format_ids[i];
536 std::cout <<
"find best match in depth_formats:" << std::endl;
541 gl_format = gl_depth_format_ids[i];
546 std::cout <<
"find best match in snorm_texture_formats:" << std::endl;
551 gl_format = gl_snorm_texture_format_ids[i];
556 std::cout <<
"find best match in int_texture_formats:" << std::endl;
561 gl_format = gl_int_texture_format_ids[i];
566 std::cout <<
"find best match in float_texture_formats:" << std::endl;
571 gl_format = gl_float_texture_format_ids[i];
576 std::cout <<
"find best match in rg_texture_formats:" << std::endl;
581 gl_format = gl_rg_texture_format_ids[i];
588unsigned configure_src_format(
const cgv::data::const_data_view& data, GLuint& src_type, GLuint& src_fmt,
const std::vector<data_view>* palettes)
602 src_fmt = GL_COLOR_INDEX;
605 nr_comp = pf.get_nr_components();
606 unsigned comp_size = pf.get_entry_size() / pf.get_nr_components();
607 std::vector<float> tmp;
608 tmp.resize(pf.get_width());
609 for (
unsigned ci=0; ci<nr_comp; ++ci) {
610 glPixelTransferf(GL_RED_BIAS, 0.000001f);
611 for (
unsigned i=0; i<pf.get_width(); ++i)
612 tmp[i] = pf.get<
unsigned char>(ci, pv.step_i(pv.get_ptr<
unsigned char>(), i))/255.0f;
613 switch (pf.get_component_name(ci)[0]) {
614 case 'R' : glPixelMapfv(GL_PIXEL_MAP_I_TO_R, GLsizei(pf.get_width()), &tmp.front());
break;
615 case 'G' : glPixelMapfv(GL_PIXEL_MAP_I_TO_G, GLsizei(pf.get_width()), &tmp.front());
break;
616 case 'B' : glPixelMapfv(GL_PIXEL_MAP_I_TO_B, GLsizei(pf.get_width()), &tmp.front());
break;
617 case 'A' : glPixelMapfv(GL_PIXEL_MAP_I_TO_A, GLsizei(pf.get_width()), &tmp.front());
break;
619 glPixelMapfv(GL_PIXEL_MAP_I_TO_R, GLsizei(pf.get_width()), &tmp.front());
620 glPixelMapfv(GL_PIXEL_MAP_I_TO_G, GLsizei(pf.get_width()), &tmp.front());
621 glPixelMapfv(GL_PIXEL_MAP_I_TO_B, GLsizei(pf.get_width()), &tmp.front());
633 const unsigned char* data_ptr = data.
get_ptr<
unsigned char>();
635 bool cube_map = (nr_dim == 2) && (cube_side != -1);
636 bool texture_array = (nr_dim > 0) && (nr_dim < 4) && !cube_map && num_array_layers != 0;
639 texture_array =
false;
641 GLuint src_type, src_fmt;
642 unsigned nr_comp = configure_src_format(data, src_type, src_fmt, palettes);
644 bool gen_mipmap = level == -1;
650 glTexImage2D(GL_TEXTURE_1D_ARRAY, level, gl_tex_format, w, 1, 0, src_fmt, src_type, data_ptr);
652 glTexImage1D(GL_TEXTURE_1D, level, gl_tex_format, w, 0, src_fmt, src_type, data_ptr);
657 if(num_array_layers < 0) {
658 glTexImage2D(GL_TEXTURE_1D_ARRAY, level, gl_tex_format, w, GLsizei(data.
get_format()->
get_height()), 0, src_fmt, src_type, data_ptr);
661 glTexImage3D(GL_TEXTURE_2D_ARRAY, level, gl_tex_format, w, GLsizei(data.
get_format()->
get_height()), 1, 0, src_fmt, src_type, data_ptr);
673 if(num_array_layers > 0)
676 glTexImage3D(GL_TEXTURE_2D_ARRAY, level, gl_tex_format, w, GLsizei(data.
get_format()->
get_height()),
677 num_layers, 0, src_fmt, src_type, data_ptr);
688 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
696 const unsigned char* data_ptr = data.
get_ptr<
unsigned char>();
698 bool cube_map = (nr_dim == 2) && (z != -1);
700 GLuint src_type, src_fmt;
701 unsigned nr_comp = configure_src_format(data, src_type, src_fmt, palettes);
703 bool gen_mipmap = level == -1;
708 glTexSubImage1D(GL_TEXTURE_1D, level, x, w, src_fmt, src_type, data_ptr);
715 glTexSubImage2D(GL_TEXTURE_2D, level, x, y, w,
719 glTexSubImage3D(GL_TEXTURE_3D, level, x, y, z, w,
725 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
731 return create_texture(dv,mipmap?(
unsigned)-1:0, (unsigned)-1, palettes, tex_id);
737 glGenTextures(1,&tex_id);
739 if ((nr_dim == 2) && (cube_side != -1))
740 glBindTexture(gl_tex_dim[3], tex_id);
742 glBindTexture(gl_tex_dim[nr_dim-1], tex_id);
746 if (
load_texture(dv, gl_tex_format, level, cube_side,
false, palettes))
747 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
749 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
751 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
752 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
753 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
758bool cover_screen(
context& ctx,
shader_program* prog_ptr,
bool flip_tex_v_coord,
float xmin,
float ymin,
float xmax,
float ymax,
float umin,
float vmin,
float umax,
float vmax)
770 int pos_idx = prog.get_position_index();
771 int tex_idx = prog.get_texcoord_index();
773 ctx.
error(
"cgv::render::gl::render_2d_texture_to_screen() passed program does not have position vertex attributes", &prog);
783 vec4 positions[4] = {
784 vec4(xmin,ymin, 0, 1),
785 vec4(xmax,ymin, 0, 1),
786 vec4(xmin,ymax, 0, 1),
787 vec4(xmax,ymax, 0, 1)
789 vec2 texcoords[8] = {
806 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
821void gl_texture_to_screen(
float xmin,
float ymin,
float xmax,
float ymax,
float umin,
float vmin,
float umax,
float vmax)
824 glGetIntegerv(GL_MATRIX_MODE, &mm);
826 glMatrixMode(GL_MODELVIEW);
830 glMatrixMode(GL_PROJECTION);
835 glTexCoord2f(umin,vmin);
836 glVertex2f(xmin, ymin);
838 glTexCoord2f(umax,vmin);
839 glVertex2f(xmax, ymin);
841 glTexCoord2f(umax,vmax);
842 glVertex2f(xmax, ymax);
844 glTexCoord2f(umin,vmax);
845 glVertex2f(xmin, ymax);
850 glMatrixMode(GL_MODELVIEW);
859 glGetIntegerv(GL_MATRIX_MODE, &mm);
861 glMatrixMode(GL_MODELVIEW);
865 glMatrixMode(GL_PROJECTION);
871 glVertex2f(xmin, ymin);
873 glTexCoord1f(vary_along_x ? 1.0f : 0.0f);
874 glVertex2f(xmax, ymin);
877 glVertex2f(xmax, ymax);
879 glTexCoord1f(vary_along_x ? 0.0f : 1.0f);
880 glVertex2f(xmin, ymax);
885 glMatrixMode(GL_MODELVIEW);
893 const char* vertex_shader_source =
"\
896uniform float slice_coord;\n\
897layout(location = 0) in vec3 position;\n\
898layout(location = 3) in vec2 texcoord;\n\
899out vec3 tex_coord;\n\
903 tex_coord.xy = texcoord;\n\
904 tex_coord.z = slice_coord;\n\
905 gl_Position = vec4(position,1.0);\n\
908 if (!prog.
attach_code(ctx, vertex_shader_source, cgv::render::ST_VERTEX)) {
910 *error_message =
"could not attach vertex shader source";
913 if (!prog.
link(ctx)) {
915 *error_message =
"could not link render to texture 3D program";
930 std::cerr <<
"ERROR in cgv:render::gl::render_to_texture3D: texture resolution of target_tex2 does not match resolution of target_tex" << std::endl;
936 std::cerr <<
"ERROR in cgv:render::gl::render_to_texture3D: texture resolution of target_tex3 does not match resolution of target_tex" << std::endl;
942 std::cerr <<
"ERROR in cgv:render::gl::render_to_texture3D: texture resolution of target_tex4 does not match resolution of target_tex" << std::endl;
948 fbo.
create(ctx,
int(tex_res[0]),
int(tex_res[1]));
949 fbo.
attach(ctx, target_tex, 0, 0, 0);
951 std::cerr <<
"fbo to update volume gradient not complete" << std::endl;
954 static float V[4 * 3] = {
955 -1, -1, 0, +1, -1, 0,
958 static int F[1 * 4] = {
966 T[0] = T[6] = float(-0.5 / tex_res[0]);
967 T[2] = T[4] = float(1.0 + 0.5 / tex_res[0]);
968 T[1] = T[3] = float(-0.5 / tex_res[1]);
969 T[5] = T[7] = float(1.0 + 0.5 / tex_res[1]);
975 for (
int i = 0; i < (int) tex_res[2]; i++) {
977 if (slice_coord_loc != -1) {
978 float slice_coord = (texture_sampling ==
TS_CELL) ? (i + 0.5f) / tex_res[2] : (float)i / (tex_res[2] - 1);
979 prog.
set_uniform(ctx, slice_coord_loc, slice_coord);
982 fbo.
attach(ctx, target_tex, i, 0, 0);
984 fbo.
attach(ctx, *target_tex2, i, 0, 1);
986 fbo.
attach(ctx, *target_tex3, i, 0, 2);
988 fbo.
attach(ctx, *target_tex4, i, 0, 3);
The const_data_view has the functionality of the data_view but uses a const pointer and therefore doe...
const data_format * get_format() const
return the component format
cgv::type::func::transfer_const< P, S * >::type get_ptr() const
return a data pointer to type S
the data view gives access to a data array of one, two, three or four dimensions.
static bool enable_global_array(const context &ctx, int loc)
enable attribute array of given location
static bool set_global_attribute_array(const context &ctx, int loc, const vertex_buffer &vbo, type_descriptor td, size_t size, size_t offset, unsigned stride=0)
point array of vertex attribute at location loc to vertex buffer array array stored in CPU memory; in...
static bool disable_global_array(const context &ctx, int loc)
disable attribute array of given location
base class for all drawables, which is independent of the used rendering API.
void push_window_transformation_array()
push a copy of the current viewport and depth range arrays defining the window transformations
virtual void set_color(const rgba &clr)
set the current color
virtual void error(const std::string &message, const render_component *rc=0) const
error handling
virtual shader_program & ref_default_shader_program(bool texture_support=false)=0
return a reference to a shader program used to render without illumination
virtual void draw_faces(const float *vertices, const float *normals, const float *tex_coords, const int *vertex_indices, const int *normal_indices, const int *tex_coord_indices, int nr_faces, int face_degree, bool flip_normals=false) const =0
pass geometry of given faces to current shader program and generate draw calls to render triangles
virtual void pop_window_transformation_array()
restore previous viewport and depth range arrays defining the window transformations
void pop_projection_matrix()
see push_P for an explanation
void push_projection_matrix()
same as push_V but for the projection matrix - a different matrix stack is used.
virtual void set_projection_matrix(const dmat4 &P)
set the current projection matrix, which transforms from eye to clip space
void pop_modelview_matrix()
see push_V for an explanation
void push_modelview_matrix()
push the current viewing matrix onto a matrix stack for viewing matrices.
virtual void set_viewport(const ivec4 &viewport, int array_index=-1)
set the current viewport or one of the viewports in the window transformation array
virtual void set_modelview_matrix(const dmat4 &MV)
set the current modelview matrix, which transforms from world to eye space
this class encapsulate frame buffers that live on the GPU and can be used as destination for the rend...
bool create(const context &ctx, int _width=-1, int _height=-1)
create framebuffer if extension is supported, otherwise return false.
bool is_complete(const context &ctx) const
check for completeness, if not complete, get the reason in last_error
bool attach(const context &ctx, const render_buffer &rb, int i=0)
attach render buffer to depth buffer if it is a depth buffer, to stencil if it is a stencil buffer or...
bool enable(context &ctx, int i0=-1, int i1=-1, int i2=-1, int i3=-1, int i4=-1, int i5=-1, int i6=-1, int i7=-1, int i8=-1, int i9=-1, int i10=-1, int i11=-1, int i12=-1, int i13=-1, int i14=-1, int i15=-1)
enable the framebuffer either with all color attachments if no arguments are given or if arguments ar...
bool disable(context &ctx)
disable the framebuffer object
a shader program combines several shader code fragments to a complete definition of the shading pipel...
bool enable(context &ctx)
enable the shader program
bool disable(context &ctx)
disable shader program and restore fixed functionality
bool set_uniform(const context &ctx, const std::string &name, const T &value, bool generate_error=false)
Set the value of a uniform by name, where the type can be any of int, unsigned, float,...
bool attach_code(const context &ctx, const shader_code &code)
attach a compiled shader code instance that is managed outside of program
bool link(const context &ctx, bool show_error=false)
link shaders to an executable program
bool is_enabled() const
check whether program is currently enabled
int get_uniform_location(const context &ctx, const std::string &name) const
query location index of an uniform
the texture class encapsulates all functionality independent of the rendering api.
namespace for data management components
ComponentFormat
define standard formats, which should be used to avoid wrong assignment of component names
ComponentIntegerInterpretation
define different interpretations of integer components
unsigned find_best_match(const component_format &fmt, const char **format_descriptions, const component_format *fmt0, bool(*fmt1_better_match)(const component_format &fmt, const component_format &fmt1, const component_format &fmt2), bool show_debug_info)
find the best matching format in a list of formats described by strings and return index of best matc...
bool fmt1_compares_better(const component_format &fmt, const component_format &fmt1, const component_format &fmt2)
default function to check whether fmt1 is a better match to fmt than fmt2
void gl_texture_to_screen(float xmin, float ymin, float xmax, float ymax, float umin, float vmin, float umax, float vmax)
cover the current viewport with a textured quad
bool load_texture(const cgv::data::const_data_view &data, unsigned gl_tex_format, unsigned level, unsigned cube_side, int num_array_layers, const std::vector< data_view > *palettes)
load data to a texture with the glTexImage commands and generate mipmaps if the level parameter is -1...
unsigned int create_texture(const cgv::data::const_data_view &dv, bool mipmap, const std::vector< data_view > *palettes, unsigned tex_id)
create a texture from the given data view creating a mipmap pyramid
bool complete_program_form_render_to_texture3D(cgv::render::context &ctx, cgv::render::shader_program &prog, std::string *error_message)
complete the given shader program that is assumed to have a working fragment shader.
bool replace_texture(const cgv::data::const_data_view &data, int level, int x, int y, int z, const std::vector< cgv::data::data_view > *palettes)
replace part or complete data of currently bound texture with the data in the given data view
bool ensure_glew_initialized()
initialize glew in the first call to this function and always return whether this was successful
bool cover_screen(context &ctx, shader_program *prog_ptr, bool flip_tex_v_coord, float xmin, float ymin, float xmax, float ymax, float umin, float vmin, float umax, float vmax)
cover the current viewport with a textured quad using the textured default shader program or the one ...
void gl_1D_texture_to_screen(bool vary_along_x, float xmin, float ymin, float xmax, float ymax)
cover the current viewport or a rectangle with it with a quad textured by a 1D texture
unsigned find_best_texture_format(const cgv::data::component_format &_cf, cgv::data::component_format *best_cf, const std::vector< data_view > *palettes, bool show_debug_info)
map the given component format to the best matching available gl component format
bool generate_mipmaps(unsigned int dim, bool is_cubemap, bool is_array, std::string *last_error)
generate mipmaps for the currently bound texture, which has the given texture dimension; optionally p...
unsigned get_gl_cube_map_target(unsigned side)
return one of the six cube map sides gl enums
bool render_to_texture3D(context &ctx, shader_program &prog, TextureSampling texture_sampling, texture &target_tex, texture *target_tex2, texture *target_tex3, texture *target_tex4)
Render to the given target 3D texture with the given shader program that must be completed with the f...
TextureSampling
different sampling strategies for rendering to textures that steer the computation of the tex_coord i...
@ TS_VERTEX
tex_coord ranges from [0,0,0] to [1,1,1]
@ TS_CELL
for texture resulution N x M x L the tex_coord ranges from [1/2N, 1/2M, 1/2L] to [1-1/2N,...
TypeId
ids for the different types and type constructs
cgv::math::fvec< float, 4 > vec4
declare type of 4d single precision floating point vectors (used for homogeneous coordinates)
cgv::media::color< float, cgv::media::RGB, cgv::media::OPACITY > rgba
declare rgba color type with 32 bit components
cgv::math::fvec< int32_t, 4 > ivec4
declare type of 4d 32 bit integer vectors
cgv::math::fvec< float, 2 > vec2
declare type of 2d single precision floating point vectors