MythTV  master
mythrender_opengl1.cpp
Go to the documentation of this file.
1 #include "mythrender_opengl1.h"
2 
3 #include <QPen>
4 #include <QBrush>
5 
6 #define LOC QString("OpenGL1: ")
7 
8 MythRenderOpenGL1::MythRenderOpenGL1(const MythRenderFormat& format, QPaintDevice* device)
9  : MythRenderOpenGL(format, device, kRenderOpenGL1)
10 {
13 }
14 
17 {
20 }
21 
23 {
24  if (!isValid())
25  return;
26  makeCurrent();
28  doneCurrent();
29 }
30 
32 {
33  glShadeModel(GL_FLAT);
34  glDisable(GL_POLYGON_SMOOTH);
35  glDisable(GL_LINE_SMOOTH);
36  glDisable(GL_POINT_SMOOTH);
37  glColor4f(0.0F, 0.0F, 0.0F, 0.0F);
39 }
40 
42 {
44  m_active_prog = 0;
45  m_color = 0x00000000;
46 }
47 
49 {
51  m_glGenProgramsARB = nullptr;
52  m_glBindProgramARB = nullptr;
53  m_glProgramStringARB = nullptr;
55  m_glDeleteProgramsARB = nullptr;
56  m_glGetProgramivARB = nullptr;
57 }
58 
60 {
62 
63  static bool fragmentprog = true;
64  static bool check = true;
65  if (check)
66  {
67  check = false;
68  fragmentprog = !getenv("OPENGL_NOFRAGPROG");
69  if (!fragmentprog)
70  LOG(VB_GENERAL, LOG_INFO, LOC + "Disabling fragment programs.");
71  }
72 
73  if (m_extensions.contains("GL_ARB_fragment_program") &&
77  fragmentprog)
78  {
80  LOG(VB_GENERAL, LOG_INFO, LOC + "Fragment program support available");
81  }
82 
84 }
85 
87 {
89 
91  GetProcAddress("glGenProgramsARB");
93  GetProcAddress("glBindProgramARB");
95  GetProcAddress("glProgramStringARB");
97  GetProcAddress("glProgramLocalParameter4fARB");
99  GetProcAddress("glDeleteProgramsARB");
101  GetProcAddress("glGetProgramivARB");
102 }
103 
104 void MythRenderOpenGL1::SetColor(int r, int g, int b, int a)
105 {
106  uint32_t tmp = (r << 24) + (g << 16) + (b << 8) + a;
107  if (tmp == m_color)
108  return;
109 
110  m_color = tmp;
111  makeCurrent();
112  glColor4f(r / 255.0, g / 255.0, b / 255.0, a / 255.0);
113  doneCurrent();
114 }
115 
116 uint MythRenderOpenGL1::CreateShaderObject(const QString &vert, const QString &frag)
117 {
118  (void)vert;
119  if (!(m_exts_used & kGLExtFragProg))
120  return 0;
121 
122  bool success = true;
123  GLint error;
124 
125  makeCurrent();
126 
127  QByteArray tmp = frag.toLatin1();
128 
129  GLuint glfp;
130  m_glGenProgramsARB(1, &glfp);
134  tmp.length(), tmp.constData());
135 
136  glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error);
137  if (error != -1)
138  {
139  LOG(VB_PLAYBACK, LOG_ERR, LOC +
140  QString("Fragment Program compile error: position %1:'%2'")
141  .arg(error).arg(frag.mid(error)));
142 
143  success = false;
144  }
147  if (error != 1)
148  {
149  LOG(VB_PLAYBACK, LOG_ERR, LOC +
150  "Fragment program exceeds hardware capabilities.");
151 
152  success = false;
153  }
154 
155  if (success)
156  {
157  LOG(VB_PLAYBACK, LOG_DEBUG, "\n" + frag + "\n");
158  m_programs.push_back(glfp);
159  }
160  else
161  m_glDeleteProgramsARB(1, &glfp);
162 
163  Flush(true);
164  doneCurrent();
165  return glfp;
166 }
167 
169 {
170  if (!m_programs.contains(fp))
171  return;
172 
173  makeCurrent();
174  QVector<GLuint>::iterator it;
175  for (it = m_programs.begin(); it != m_programs.end(); ++it)
176  {
177  if (*it == fp)
178  {
179  m_glDeleteProgramsARB(1, &(*it));
180  m_programs.erase(it);
181  break;
182  }
183  }
184  Flush(true);
185  doneCurrent();
186 }
187 
189 {
190  if ((!obj && !m_active_prog) ||
191  (obj && (obj == m_active_prog)))
192  return;
193 
194  makeCurrent();
195 
196  if (!obj && m_active_prog)
197  {
198  glDisable(GL_FRAGMENT_PROGRAM_ARB);
199  m_active_prog = 0;
200  doneCurrent();
201  return;
202  }
203 
204  if (!m_programs.contains(obj))
205  return;
206 
207  if (!m_active_prog)
208  glEnable(GL_FRAGMENT_PROGRAM_ARB);
209 
210  if (obj != m_active_prog)
211  {
213  m_active_prog = obj;
214  }
215 
216  doneCurrent();
217 }
218 
219 // The API appears to be for compatability with OpenGL2. The uniform
220 // argument is used there.
221 void MythRenderOpenGL1::SetShaderParams(uint obj, const QMatrix4x4 &m,
222  const char* /*uniform*/)
223 {
224  GLMatrix4x4 v(m);
225 
226  makeCurrent();
227 
228  EnableShaderObject(obj);
230  0, v[0], v[1], v[2], v[3]);
232  1, v[4], v[5], v[6], v[7]);
234  2, v[8], v[9], v[10], v[11]);
235 
236  doneCurrent();
237 }
238 
240 {
241  LOG(VB_GENERAL, LOG_INFO, LOC + "Deleting OpenGL Resources");
244 }
245 
247 {
248  glMatrixMode(GL_PROJECTION);
249  glLoadIdentity();
250  glOrtho(m_viewport.left(), m_viewport.left() + m_viewport.width(),
251  m_viewport.top() + m_viewport.height(), m_viewport.top(), 1, -1);
252  glMatrixMode(GL_MODELVIEW);
253  glLoadIdentity();
254 }
255 
256 void MythRenderOpenGL1::PushTransformation(const UIEffects &fx, QPointF &center)
257 {
258  makeCurrent();
259  glPushMatrix();
260  glTranslatef(center.x(), center.y(), 0.0);
261  glScalef(fx.m_hzoom, fx.m_vzoom, 1.0);
262  glRotatef(fx.m_angle, 0, 0, 1);
263  glTranslatef(-center.x(), -center.y(), 0.0);
264  doneCurrent();
265 }
266 
268 {
269  makeCurrent();
270  glPopMatrix();
271  doneCurrent();
272 }
273 
275 {
276  QVector<GLuint>::iterator it;
277  for (it = m_programs.begin(); it != m_programs.end(); ++it)
278  m_glDeleteProgramsARB(1, &(*(it)));
279  m_programs.clear();
280  Flush(true);
281 }
282 
283 void MythRenderOpenGL1::DrawBitmapPriv(uint tex, const QRect *src,
284  const QRect *dst, uint prog, int alpha,
285  int red, int green, int blue)
286 {
287  if (prog && !m_programs.contains(prog))
288  prog = 0;
289 
290  EnableShaderObject(prog);
291  SetBlend(true);
292  SetColor(red, green, blue, alpha);
293 
294  glEnableClientState(GL_VERTEX_ARRAY);
295  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
296  EnableTextures(tex);
297  glBindTexture(m_textures[tex].m_type, tex);
298  UpdateTextureVertices(tex, src, dst);
299  glVertexPointer(2, GL_FLOAT, 0, m_textures[tex].m_vertex_data);
300  glTexCoordPointer(2, GL_FLOAT, 0, m_textures[tex].m_vertex_data + TEX_OFFSET);
301  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
302  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
303  glDisableClientState(GL_VERTEX_ARRAY);
304 }
305 
306 void MythRenderOpenGL1::DrawBitmapPriv(uint *textures, uint texture_count,
307  const QRectF *src, const QRectF *dst,
308  uint prog)
309 {
310  if (prog && !m_programs.contains(prog))
311  prog = 0;
312 
313  uint first = textures[0];
314 
315  EnableShaderObject(prog);
316  SetBlend(false);
317  SetColor(255, 255, 255, 255);
318 
319  glEnableClientState(GL_VERTEX_ARRAY);
320  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
321  EnableTextures(first);
322  uint active_tex = 0;
323  for (uint i = 0; i < texture_count; i++)
324  {
325  if (m_textures.contains(textures[i]))
326  {
327  ActiveTexture(GL_TEXTURE0 + active_tex++);
328  glBindTexture(m_textures[textures[i]].m_type, textures[i]);
329  }
330  }
331 
332  UpdateTextureVertices(first, src, dst);
333  glVertexPointer(2, GL_FLOAT, 0, m_textures[first].m_vertex_data);
334  glTexCoordPointer(2, GL_FLOAT, 0, m_textures[first].m_vertex_data + TEX_OFFSET);
335  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
336 
338  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
339  glDisableClientState(GL_VERTEX_ARRAY);
340 }
341 
342 void MythRenderOpenGL1::DrawRectPriv(const QRect &area, const QBrush &fillBrush,
343  const QPen &linePen, int alpha)
344 {
345  SetBlend(true);
346  DisableTextures();
348  glEnableClientState(GL_VERTEX_ARRAY);
349 
350  int lineWidth = linePen.width();
351  QRect r(area.left() + lineWidth, area.top() + lineWidth,
352  area.width() - (lineWidth * 2), area.height() - (lineWidth * 2));
353 
354  if (fillBrush.style() != Qt::NoBrush)
355  {
356  int a = 255 * (((float)alpha / 255.0F) *
357  ((float)fillBrush.color().alpha() / 255.0F));
358  SetColor(fillBrush.color().red(), fillBrush.color().green(),
359  fillBrush.color().blue(), a);
360  GLfloat *vertices = GetCachedVertices(GL_TRIANGLE_STRIP, r);
361  glVertexPointer(2, GL_FLOAT, 0, vertices);
362  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
363  }
364 
365  if (linePen.style() != Qt::NoPen)
366  {
367  int a = 255 * (((float)alpha / 255.0F) *
368  ((float)linePen.color().alpha() / 255.0F));
369  SetColor(linePen.color().red(), linePen.color().green(),
370  linePen.color().blue(), a);
371  // glLineWidth() requires its argument to be at least 1.
372  glLineWidth(std::max(1, lineWidth));
373  GLfloat *vertices = GetCachedVertices(GL_LINE_LOOP, r);
374  glVertexPointer(2, GL_FLOAT, 0, vertices);
375  glDrawArrays(GL_LINE_LOOP, 0, 4);
376  }
377 
378  glDisableClientState(GL_VERTEX_ARRAY);
379 }
void SetMatrixView(void) override
void SetBlend(bool enable)
#define GL_PROGRAM_FORMAT_ASCII_ARB
MYTH_GLGETPROGRAMIVARBPROC m_glGetProgramivARB
void SetColor(int r, int g, int b, int a) override
static void error(const char *str,...)
Definition: vbi.c:42
void InitProcs(void) override
MYTH_GLDELETEPROGRAMSARBPROC m_glDeleteProgramsARB
#define GL_PROGRAM_ERROR_POSITION_ARB
unsigned int uint
Definition: compat.h:140
void(APIENTRY * MYTH_GLPROGRAMSTRINGARBPROC)(GLenum target, GLenum format, GLsizei len, const GLvoid *string)
static guint32 * tmp
Definition: goom_core.c:35
unsigned char r
Definition: ParseText.cpp:329
void ResetProcs(void) override
#define LOC
RenderType m_type
unsigned char b
Definition: ParseText.cpp:329
void EnableShaderObject(uint obj) override
MYTH_GLPROGRAMSTRINGARBPROC m_glProgramStringARB
void * GetProcAddress(const QString &proc) const
#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
#define GL_FRAGMENT_PROGRAM_ARB
void Flush(bool use_fence)
void doneCurrent() override
MythRenderOpenGL1(const MythRenderFormat &format, QPaintDevice *device)
#define TEX_OFFSET
uint CreateShaderObject(const QString &vert, const QString &frag) override
virtual bool InitFeatures(void)
void(APIENTRY * MYTH_GLDELETEPROGRAMSARBPROC)(GLsizei n, const GLuint *programs)
#define GL_TEXTURE0
void(APIENTRY * MYTH_GLGENPROGRAMSARBPROC)(GLsizei n, GLuint *programs)
void SetShaderParams(uint obj, const QMatrix4x4 &m, const char *uniform) override
void PushTransformation(const UIEffects &fx, QPointF &center) override
void DeleteShaders(void) override
class QGLFormat MythRenderFormat
void(APIENTRY * MYTH_GLPROGRAMLOCALPARAMETER4FARBPROC)(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
MYTH_GLGENPROGRAMSARBPROC m_glGenProgramsARB
QHash< GLuint, MythGLTexture > m_textures
void DeleteShaderObject(uint fp) override
MYTH_GLPROGRAMLOCALPARAMETER4FARBPROC m_glProgramLocalParameter4fARB
void ResetVars(void) override
void(APIENTRY * MYTH_GLBINDPROGRAMARBPROC)(GLenum target, GLuint program)
void makeCurrent() override
void(APIENTRY * MYTH_GLGETPROGRAMIVARBPROC)(GLenum target, GLenum pname, GLint *params)
#define LOG(_MASK_, _LEVEL_, _STRING_)
Definition: mythlogging.h:41
void DeleteOpenGLResources(void) override
MYTH_GLBINDPROGRAMARBPROC m_glBindProgramARB
GLfloat * GetCachedVertices(GLuint type, const QRect &area)
bool InitFeatures(void) override
void ActiveTexture(int active_tex)
QVector< GLuint > m_programs
void PopTransformation(void) override
void EnableTextures(uint tex, uint tex_type=0)
void DrawRectPriv(const QRect &area, const QBrush &fillBrush, const QPen &linePen, int alpha) override
void DrawBitmapPriv(uint tex, const QRect *src, const QRect *dst, uint prog, int alpha, int red, int green, int blue) override
virtual void ResetVars(void)
virtual void Init2DState(void)
virtual void ResetProcs(void)
GLMatrix4x4 is a helper class to convert between QT and GT 4x4 matrices.
bool UpdateTextureVertices(uint tex, const QRect *src, const QRect *dst)
void Init2DState(void) override
virtual void DeleteOpenGLResources(void)
virtual void InitProcs(void)
unsigned char g
Definition: ParseText.cpp:329