]> git.vomp.tv Git - vompclient.git/blob - glmocoshader.cc
Add moco shader object, initial data uploading
[vompclient.git] / glmocoshader.cc
1 /*\r
2     Copyright 2012 Marten Richter\r
3 \r
4     This file is part of VOMP.\r
5 \r
6     VOMP is free software; you can redistribute it and/or modify\r
7     it under the terms of the GNU General Public License as published by\r
8     the Free Software Foundation; either version 2 of the License, or\r
9     (at your option) any later version.\r
10 \r
11     VOMP is distributed in the hope that it will be useful,\r
12     but WITHOUT ANY WARRANTY; without even the implied warranty of\r
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
14     GNU General Public License for more details.\r
15 \r
16     You should have received a copy of the GNU General Public License\r
17     along with VOMP; if not, write to the Free Software\r
18     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
19 */\r
20 #include "glmocoshader.h"\r
21 #include "videovpeogl.h"\r
22 \r
23 const GLchar moco_vertex_shader[] =\r
24                 "attribute vec4 vec_pos;\n"\r
25                 "attribute vec2 tex_coord;\n"\r
26                 "varying vec2 out_texCoord;\n"\r
27                 "void main()\n"\r
28                 "{\n"\r
29                 " gl_Position=vec_pos;\n"\r
30                 " out_texCoord=tex_coord;\n"\r
31                 "}\n";\r
32 \r
33 const GLchar moco_frag_shader[] =\r
34                 "precision mediump float;\n"\r
35                 "uniform sampler2D textureU;\n"\r
36                 "uniform sampler2D textureV;\n"\r
37                 "uniform sampler2D textureY;\n"\r
38                 "const float uv_corr=0.5;\n"\r
39                 "const float y_corr=0.0625;\n"\r
40                 "const mat3 yuvtransform= mat3( 1.164 ,0.0  ,1.596   ,\n"\r
41                 "                               1.164 ,-0.391,-0.813   ,\n"\r
42                 "                               1.164,2.018  , 0.0 );\n"\r
43 //              "const mat3 yuvtransform= mat3( 1. ,1.  ,1.   ,\n"\r
44 //              "                               0.0 ,-0.3960,2.029   ,\n"\r
45 //              "                               1.140,-0.581  , 0.0 );\n"\r
46 //              "const mat3 yuvtransform= mat3( 1. ,0  ,0.   ,\n"\r
47 //              "                               0.0 ,1.,0.   ,\n"\r
48 //              "                               0.,0.  , 1.0 );\n"\r
49 //              "const mat3 yuvtransform= mat3( 1. ,1.  ,1.   ,\n"\r
50 //              "                               0.0 ,-0.03960,0.2029   ,\n"\r
51 //              "                               0.1140,-0.0581  , 0.0 );\n"\r
52                 "varying vec2 out_texCoord;\n"\r
53                 "void main()\n"\r
54                 "{\n"\r
55                 " vec3 help;\n"\r
56                 "help.x=texture2D(textureY,out_texCoord).r-y_corr;\n"\r
57                 "help.y=texture2D(textureU,out_texCoord).r-uv_corr;\n"\r
58                 "help.z=texture2D(textureV,out_texCoord).r-uv_corr;\n" //-uv_corr;\n"\r
59                 "  gl_FragColor.rgb=help*yuvtransform;\n"\r
60                 " gl_FragColor.a=1.;\n"\r
61                 "}\n";\r
62 \r
63 GLMocoShader::GLMocoShader(): GLShader("GLYuv400Shader")\r
64 {\r
65 \r
66         frame_buf=0;\r
67 }\r
68 \r
69 GLMocoShader::~GLMocoShader()\r
70 {\r
71         //parent does everything\r
72 }\r
73 \r
74 int GLMocoShader::init() {\r
75         if (!initShaders(moco_vertex_shader, moco_frag_shader)) {\r
76                 return 0;\r
77         }\r
78 //      frame_sampler_locY = glGetUniformLocation(shad_program, "textureY");\r
79         // Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",frame_sampler_locY,glGetError());\r
80 //      frame_sampler_locU = glGetUniformLocation(shad_program, "textureU");\r
81         //Log::getInstance()->log("OSD", Log::WARN, "uniform location %x %x",frame_sampler_locU,glGetError());\r
82 //      frame_sampler_locV = glGetUniformLocation(shad_program, "textureV");\r
83         glGenFramebuffers(1, &frame_buf);\r
84         glGenTextures(1, &data_blocks);\r
85         glBindTexture(GL_TEXTURE_2D, data_blocks);\r
86         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 1024, 1024, 0, GL_LUMINANCE_ALPHA,\r
87                                 GL_UNSIGNED_BYTE, NULL);\r
88 \r
89         glGenBuffers(1,&macro_block);\r
90         glBindBuffer(GL_ARRAY_BUFFER,macro_block);\r
91         glBufferData(GL_ARRAY_BUFFER,4096*4*sizeof(XvMCMacroBlock),NULL,GL_DYNAMIC_DRAW);\r
92         valid_macro_blocks=0;\r
93 \r
94 \r
95         glGenBuffers(1,&triangles);\r
96         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,triangles);\r
97         GLushort *tri_indices=(GLushort *)malloc(sizeof(GLushort)*4096*6);\r
98         if (!tri_indices) {\r
99                 Log::getInstance()->log("GLMocoShader", Log::WARN, "allocating triindices failed");\r
100                 return 0;\r
101         }\r
102         GLushort *tri_indices_run=tri_indices;\r
103         for (int i=0;i<4096;i++) {\r
104                 *tri_indices_run=i+2*4096;  //strip\r
105                 tri_indices_run++;\r
106                 *tri_indices_run=i+0*4096;  //strip\r
107                 tri_indices_run++;\r
108                 *tri_indices_run=i+3*4096;  //strip\r
109                 tri_indices_run++;\r
110                 *tri_indices_run=i+1*4096;  //strip\r
111                 tri_indices_run++;\r
112                 *tri_indices_run=i+1*4096;  //strip\r
113                 tri_indices_run++;\r
114                 *tri_indices_run=i+1+2*4096;  //strip\r
115                 tri_indices_run++;\r
116         }\r
117         glBufferData(GL_ELEMENT_ARRAY_BUFFER,4096*6*sizeof(GLushort),tri_indices,GL_STREAM_DRAW);\r
118         free(tri_indices);\r
119 \r
120         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);\r
121         glBindBuffer(GL_ARRAY_BUFFER,0);\r
122 \r
123 \r
124 \r
125         return 1;\r
126 \r
127 }\r
128 \r
129 int GLMocoShader::deinit()\r
130 {\r
131         glDeleteFramebuffers(1, &frame_buf);\r
132         glDeleteTextures(1, &frame_buf);\r
133         return deinitShaders();\r
134 }\r
135 \r
136 int GLMocoShader::uploadDataBlocks(short* blocks,unsigned int num_blocks, XvMCMacroBlock *m_blocks,unsigned int num_m_blocks)\r
137 {\r
138         unsigned int height=(num_blocks+127)/128;\r
139 \r
140         glBindTexture(GL_TEXTURE_2D, data_blocks);\r
141         glPixelStorei(GL_UNPACK_ALIGNMENT,1);\r
142 \r
143         glTexSubImage2D(GL_TEXTURE_2D,0,0,0,\r
144                 1024,height,\r
145                 GL_LUMINANCE,GL_UNSIGNED_BYTE,\r
146                 blocks);\r
147         //Log::getInstance()->log("GLMocoShader", Log::WARN, "uploadDataBlocks mark2 glerror %x",glGetError());\r
148 \r
149         valid_macro_blocks=num_m_blocks;\r
150         glBindBuffer(GL_ARRAY_BUFFER,macro_block);\r
151         XvMCMacroBlock *m_blocks_run=m_blocks;\r
152         XvMCMacroBlock *m_blocks_end=m_blocks+num_m_blocks;\r
153         while (m_blocks_run!=m_blocks_end) {\r
154                 m_blocks_run->pad0=0x0000;\r
155                 m_blocks_run++;\r
156         }\r
157         glBufferSubData(GL_ARRAY_BUFFER, 0, num_m_blocks * sizeof(XvMCMacroBlock),\r
158                         m_blocks);\r
159 \r
160         m_blocks_run = m_blocks;\r
161         m_blocks_end = m_blocks + num_m_blocks;\r
162         while (m_blocks_run != m_blocks_end) {\r
163                 m_blocks_run->pad0 = 0x00FF;\r
164                 m_blocks_run++;\r
165         }\r
166         glBufferSubData(GL_ARRAY_BUFFER, 4096, num_m_blocks * sizeof(XvMCMacroBlock),\r
167                         m_blocks);\r
168 \r
169         m_blocks_run = m_blocks;\r
170         m_blocks_end = m_blocks + num_m_blocks;\r
171         while (m_blocks_run != m_blocks_end) {\r
172                 m_blocks_run->pad0 = 0xFF00;\r
173                 m_blocks_run++;\r
174         }\r
175         glBufferSubData(GL_ARRAY_BUFFER, 2 * 4096,\r
176                         num_m_blocks * sizeof(XvMCMacroBlock), m_blocks);\r
177 \r
178         m_blocks_run = m_blocks;\r
179         m_blocks_end = m_blocks + num_m_blocks;\r
180         while (m_blocks_run != m_blocks_end) {\r
181                 m_blocks_run->pad0 = 0xFFFF;\r
182                 m_blocks_run++;\r
183         }\r
184         glBufferSubData(GL_ARRAY_BUFFER, 3 * 4096,\r
185                         num_m_blocks * sizeof(XvMCMacroBlock), m_blocks);\r
186 \r
187 \r
188         glBindBuffer(GL_ARRAY_BUFFER,0);\r
189 \r
190         return 1;\r
191 \r
192 \r
193 \r
194 }\r
195 \r
196 int GLMocoShader::doMoCo(VPEOGLFrame *target, VPE_FrameBuf* source)\r
197 {\r
198 \r
199         glBindFramebuffer(GL_FRAMEBUFFER, frame_buf);\r
200         Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark1 glerror %x",glGetError());\r
201         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,\r
202                         GL_TEXTURE_2D, target->textures[0], 0);\r
203         Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark2 glerror %x",glGetError());\r
204 \r
205         int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);\r
206         if (status == GL_FRAMEBUFFER_COMPLETE) {\r
207                 glUseProgram(shad_program);\r
208                 Log::getInstance()->log("GLMocoShader", Log::WARN, "doMoCo mark3 glerror %x",glGetError());\r
209 \r
210 \r
211                 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);\r
212                 glBindBuffer(GL_ARRAY_BUFFER,0);\r
213                 glBindFramebuffer(GL_FRAMEBUFFER, 0);\r
214         } else {\r
215                 glBindFramebuffer(GL_FRAMEBUFFER, 0);\r
216                 Log::getInstance()->log("GLMocoShader", Log::WARN, "framebuffer not complete");\r
217                 return -1;\r
218         }\r
219         return 0;\r
220 \r
221 \r
222 \r
223 }\r
224 \r
225 /*\r
226 \r
227 int GLMocoShader::PrepareRendering(GLuint y_tex, GLuint u_tex, GLuint v_tex) { // This Function setups the rendering pipeline according to the shaders standards\r
228 \r
229         //Log::getInstance()->log("OSD", Log::WARN, "mark1 glerror %x",glGetError());\r
230 \r
231 \r
232         //Log::getInstance()->log("OSD", Log::WARN, "mark2 glerror %x",glGetError());\r
233 \r
234 \r
235         glActiveTexture( GL_TEXTURE2);\r
236         glBindTexture(GL_TEXTURE_2D, v_tex);\r
237         glUniform1i(frame_sampler_locV, 2);\r
238         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
239         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
240 \r
241         glActiveTexture( GL_TEXTURE1);\r
242         glBindTexture(GL_TEXTURE_2D, u_tex);\r
243         glUniform1i(frame_sampler_locU, 1);\r
244         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
245         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
246 \r
247         glActiveTexture( GL_TEXTURE0);\r
248         glBindTexture(GL_TEXTURE_2D, y_tex);\r
249         glUniform1i(frame_sampler_locY, 0);\r
250         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);\r
251         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);\r
252         return 1;\r
253 \r
254 }*/\r
255 \r
256 int GLMocoShader::BindAttributes()\r
257 {\r
258         glBindAttribLocation(shad_program,0,"vec_pos");\r
259         glBindAttribLocation(shad_program,1,"tex_coord");\r
260         return 1;\r
261 }\r