OpenGL: stipple support added to basic GLSL shader
[blender.git] / source / blender / gpu / intern / gpu_basic_shader.c
index c441a44c17b600722e93668c9c42bdce7311cd7c..c01d5321fe3ee511c71cec10c01ea2b466bc6218 100644 (file)
@@ -63,6 +63,210 @@ static struct {
        int lights_directional;
 } GPU_MATERIAL_STATE;
 
+
+/* Stipple patterns */
+/* ******************************************** */
+const GLubyte stipple_halftone[128] = {
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
+       0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55};
+
+const GLubyte stipple_quarttone[128] = {
+       136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
+       136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
+       136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
+       136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
+       136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
+       136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
+       136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0,
+       136, 136, 136, 136, 0, 0, 0, 0, 34, 34, 34, 34, 0, 0, 0, 0};
+
+const GLubyte stipple_diag_stripes_pos[128] = {
+       0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x01, 0xfe,
+       0x03, 0xfc, 0x03, 0xfc, 0x07, 0xf8, 0x07, 0xf8,
+       0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0,
+       0x3f, 0xc0, 0x3f, 0xc0, 0x7f, 0x80, 0x7f, 0x80,
+       0xff, 0x00, 0xff, 0x00, 0xfe, 0x01, 0xfe, 0x01,
+       0xfc, 0x03, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x07,
+       0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x1f, 0xe0, 0x1f,
+       0xc0, 0x3f, 0xc0, 0x3f, 0x80, 0x7f, 0x80, 0x7f,
+       0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x01, 0xfe,
+       0x03, 0xfc, 0x03, 0xfc, 0x07, 0xf8, 0x07, 0xf8,
+       0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0,
+       0x3f, 0xc0, 0x3f, 0xc0, 0x7f, 0x80, 0x7f, 0x80,
+       0xff, 0x00, 0xff, 0x00, 0xfe, 0x01, 0xfe, 0x01,
+       0xfc, 0x03, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x07,
+       0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x1f, 0xe0, 0x1f,
+       0xc0, 0x3f, 0xc0, 0x3f, 0x80, 0x7f, 0x80, 0x7f};
+
+const GLubyte stipple_diag_stripes_neg[128] = {
+       0xff, 0x00, 0xff, 0x00, 0xfe, 0x01, 0xfe, 0x01,
+       0xfc, 0x03, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x07,
+       0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x1f, 0xe0, 0x1f,
+       0xc0, 0x3f, 0xc0, 0x3f, 0x80, 0x7f, 0x80, 0x7f,
+       0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x01, 0xfe,
+       0x03, 0xfc, 0x03, 0xfc, 0x07, 0xf8, 0x07, 0xf8,
+       0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0,
+       0x3f, 0xc0, 0x3f, 0xc0, 0x7f, 0x80, 0x7f, 0x80,
+       0xff, 0x00, 0xff, 0x00, 0xfe, 0x01, 0xfe, 0x01,
+       0xfc, 0x03, 0xfc, 0x03, 0xf8, 0x07, 0xf8, 0x07,
+       0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x1f, 0xe0, 0x1f,
+       0xc0, 0x3f, 0xc0, 0x3f, 0x80, 0x7f, 0x80, 0x7f,
+       0x00, 0xff, 0x00, 0xff, 0x01, 0xfe, 0x01, 0xfe,
+       0x03, 0xfc, 0x03, 0xfc, 0x07, 0xf8, 0x07, 0xf8,
+       0x0f, 0xf0, 0x0f, 0xf0, 0x1f, 0xe0, 0x1f, 0xe0,
+       0x3f, 0xc0, 0x3f, 0xc0, 0x7f, 0x80, 0x7f, 0x80};
+
+const GLubyte stipple_checker_8px[128] = {
+       255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
+       255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
+       0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
+       0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
+       255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
+       255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0,
+       0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255,
+       0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255, 0, 255};
+
+const GLubyte stipple_interlace_row[128] = {
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00};
+
+const GLubyte stipple_interlace_row_swap[128] = {
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+       0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff};
+
+const GLubyte stipple_interlace_column[128] = {
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+       0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55};
+
+const GLubyte stipple_interlace_column_swap[128] = {
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
+       0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
+
+const GLubyte stipple_interlace_checker[128] = {
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa,
+       0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa};
+
+const GLubyte stipple_interlace_checker_swap[128] = {
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55,
+       0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55};
+
+const GLubyte stipple_hexagon[128] = {
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
+       0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
+       0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22};
+/* ********************************************* */
+
 /* Init / exit */
 
 void GPU_basic_shaders_init(void)
@@ -141,6 +345,8 @@ static GPUShader *gpu_basic_shader(int options)
                        strcat(defines, "#define USE_TWO_SIDED\n");
                if (options & GPU_SHADER_TEXTURE_2D)
                        strcat(defines, "#define USE_TEXTURE\n");
+               if (options & GPU_SHADER_STIPPLE)
+                       strcat(defines, "#define USE_STIPPLE\n");
 
                if (options & GPU_SHADER_SOLID_LIGHTING)
                        strcat(defines, "#define USE_SOLID_LIGHTING\n");
@@ -214,6 +420,11 @@ void GPU_basic_shader_bind(int options)
                        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
                        glDisable(GL_TEXTURE_2D);
                }
+
+               if (options & GPU_SHADER_STIPPLE)
+                       glEnable(GL_POLYGON_STIPPLE);
+               else if (bound_options & GPU_SHADER_STIPPLE)
+                       glDisable(GL_POLYGON_STIPPLE);
        }
 
        GPU_MATERIAL_STATE.bound_options = options;
@@ -329,3 +540,52 @@ void GPU_basic_shader_light_set_viewer(bool local)
        glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, (local)? GL_TRUE: GL_FALSE);
 }
 
+void GPU_basic_shader_stipple(GPUBasicShaderStipple stipple_id)
+{
+       if (USE_GLSL) {
+               glUniform1i(GPU_shader_get_uniform(gpu_basic_shader(GPU_MATERIAL_STATE.bound_options), "stipple_id"), stipple_id);
+       }
+       else {
+               switch(stipple_id) {
+               case GPU_SHADER_STIPPLE_HALFTONE:
+                       glPolygonStipple(stipple_halftone);
+                       return;
+               case GPU_SHADER_STIPPLE_QUARTTONE:
+                       glPolygonStipple(stipple_quarttone);
+                       return;
+               case GPU_SHADER_STIPPLE_CHECKER_8PX:
+                       glPolygonStipple(stipple_checker_8px);
+                       return;
+               case GPU_SHADER_STIPPLE_HEXAGON:
+                       glPolygonStipple(stipple_hexagon);
+                       return;
+               case GPU_SHADER_STIPPLE_DIAG_STRIPES_SWAP:
+                       glPolygonStipple(stipple_diag_stripes_neg);
+                       return;
+               case GPU_SHADER_STIPPLE_DIAG_STRIPES:
+                       glPolygonStipple(stipple_diag_stripes_pos);
+                       return;
+               case GPU_SHADER_STIPPLE_S3D_INTERLACE_ROW:
+                       glPolygonStipple(stipple_interlace_row);
+                       return;
+               case GPU_SHADER_STIPPLE_S3D_INTERLACE_ROW_SWAP:
+                       glPolygonStipple(stipple_interlace_row_swap);
+                       return;
+               case GPU_SHADER_STIPPLE_S3D_INTERLACE_COLUMN:
+                       glPolygonStipple(stipple_interlace_column);
+                       return;
+               case GPU_SHADER_STIPPLE_S3D_INTERLACE_COLUMN_SWAP:
+                       glPolygonStipple(stipple_interlace_column_swap);
+                       return;
+               case GPU_SHADER_STIPPLE_S3D_INTERLACE_CHECKER:
+                       glPolygonStipple(stipple_interlace_checker);
+                       return;
+               case GPU_SHADER_STIPPLE_S3D_INTERLACE_CHECKER_SWAP:
+                       glPolygonStipple(stipple_interlace_checker_swap);
+                       return;
+               default:
+                       glPolygonStipple(stipple_hexagon);
+                       return;
+               }
+       }
+}