Commit 8be9b7a5 authored by Burlen Loring's avatar Burlen Loring Committed by Code Review
Browse files

Merge topic 'opengl-error-hunt' into master

a6fa3e37 OpenGL error hunt
parents 5e3e2043 a6fa3e37
......@@ -27,6 +27,7 @@
#include "vtkPistonScalarsColors.h"
#include "vtkScalarsToColors.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkOpenGLError.h"
#include <limits>
......@@ -52,12 +53,14 @@ namespace vtkpiston {
{
PistonGLRAII(GLbitfield mask)
{
vtkOpenGLClearErrorMacro();
glPushAttrib(mask);
}
~PistonGLRAII()
{
glPopAttrib();
vtkOpenGLCheckErrorMacro("failed after ~PistonGLRAII");
}
};
}
......@@ -136,6 +139,8 @@ vtkPistonMapper::~vtkPistonMapper()
//-----------------------------------------------------------------------------
void vtkPistonMapper::PrepareDirectRenderBuffers(int nPoints)
{
vtkOpenGLClearErrorMacro();
if (nPoints==this->Internal->BufferSize)
{
return;
......@@ -144,6 +149,7 @@ void vtkPistonMapper::PrepareDirectRenderBuffers(int nPoints)
{
// Release old buffer
vtkgl::DeleteBuffers(3, this->Internal->vboBuffers);
vtkOpenGLCheckErrorMacro("failed at glDeleteBuffers");
}
this->Internal->BufferSize = nPoints;
......@@ -170,6 +176,8 @@ void vtkPistonMapper::PrepareDirectRenderBuffers(int nPoints)
this->Internal->BufferSize*3*sizeof(float), 0,
vtkgl::DYNAMIC_DRAW);
vtkOpenGLCheckErrorMacro("failed after allocate shared memory");
vtkpiston::CudaRegisterBuffer(&this->Internal->vboResources[0],
this->Internal->vboBuffers[0]);
vtkpiston::CudaRegisterBuffer(&this->Internal->vboResources[1],
......@@ -214,6 +222,8 @@ int vtkPistonMapper::FillInputPortInformation(
//-----------------------------------------------------------------------------
void vtkPistonMapper::RenderOnCPU()
{
vtkOpenGLClearErrorMacro();
vtkpiston::PistonGLRAII(GL_LIGHTING_BIT);
vtkScalarsToColors *lut = this->GetLookupTable();
......@@ -389,11 +399,15 @@ void vtkPistonMapper::RenderOnCPU()
glEnd();
}
od->Delete();
vtkOpenGLCheckErrorMacro("failed after RenderOnCPU");
}
//-----------------------------------------------------------------------------
void vtkPistonMapper::RenderOnGPU()
{
vtkOpenGLClearErrorMacro();
vtkPistonDataObject *id = this->GetPistonDataObjectInput(0);
int nPoints = vtkpiston::QueryNumVerts(id);
......@@ -443,11 +457,15 @@ void vtkPistonMapper::RenderOnGPU()
glDisableClientState(GL_VERTEX_ARRAY);
if (hasNormals) glDisableClientState(GL_NORMAL_ARRAY);
if (hasColors) glDisableClientState(GL_COLOR_ARRAY);
vtkOpenGLCheckErrorMacro("failed after RenderOnGPU");
}
//-----------------------------------------------------------------------------
void vtkPistonMapper::RenderImageDataOutline()
{
vtkOpenGLClearErrorMacro();
vtkpiston::PistonGLRAII(GL_LIGHTING_BIT);
glDisable(GL_LIGHTING);
......@@ -508,6 +526,8 @@ void vtkPistonMapper::RenderImageDataOutline()
glVertex3dv(nextpt[3]);
glVertex3dv(nextpt[7]);
glEnd();
vtkOpenGLCheckErrorMacro("failed after RenderImageDataOutline");
}
//----------------------------------------------------------------------------
......
......@@ -28,6 +28,7 @@
#include "vtkGenericOpenGLRenderWindow.h"
#include "vtkEventQtSlotConnect.h"
#include "vtkgl.h"
#include "vtkOpenGLError.h"
QVTKGraphicsItem::QVTKGraphicsItem(QGLContext* ctx, QGraphicsItem* p)
: QGraphicsWidget(p), mContext(ctx)
......@@ -183,6 +184,8 @@ void QVTKGraphicsItem::paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget
if(!mWin)
return;
vtkOpenGLClearErrorMacro();
#if QT_VERSION >= 0x040600
// tell Qt we're doing our own GL calls
// if necessary, it'll put us in an OpenGL 1.x compatible state.
......@@ -239,6 +242,8 @@ void QVTKGraphicsItem::paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget
#if QT_VERSION >= 0x040600
painter->endNativePainting();
#endif
vtkOpenGLCheckErrorMacro("failed after paint");
}
void QVTKGraphicsItem::keyPressEvent(QKeyEvent* e)
......
......@@ -35,11 +35,11 @@
#include "vtkMatrix4x4.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkOpenGLRenderWindow.h"
#include "vtkPath.h"
#include "vtkPointData.h"
#include "vtkProp.h"
#include "vtkProp3DCollection.h"
#include "vtkOpenGLRenderWindow.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkRendererCollection.h"
......@@ -56,6 +56,7 @@
#include "vtkVolumeCollection.h"
#include "vtkWindowToImageFilter.h"
#include "vtk_gl2ps.h"
#include "vtkOpenGLError.h"
#include <vector>
......@@ -115,6 +116,8 @@ void vtkGL2PSExporter::WriteData()
return;
}
vtkOpenGLClearErrorMacro();
// Get the renderers. We'll be walking through them a lot later.
vtkRendererCollection *renCol = this->RenderWindow->GetRenderers();
......@@ -296,6 +299,7 @@ void vtkGL2PSExporter::WriteData()
// Cleanup memory
delete[] fName;
vtkOpenGLCheckErrorMacro("failed after WriteData");
vtkDebugMacro(<<"Finished writing file using GL2PS");
vtkGL2PSUtilities::FinishExport();
}
......@@ -626,6 +630,8 @@ void vtkGL2PSExporter::SetPropVisibilities(vtkPropCollection *col, int vis)
void vtkGL2PSExporter::DrawSpecialProps(vtkCollection *specialPropCol,
vtkRendererCollection *renCol)
{
vtkOpenGLClearErrorMacro();
// Iterate through the renderers and the prop collections together:
assert("renderers and special prop collections match" &&
renCol->GetNumberOfItems() == specialPropCol->GetNumberOfItems());
......@@ -654,6 +660,8 @@ void vtkGL2PSExporter::DrawSpecialProps(vtkCollection *specialPropCol,
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
vtkOpenGLCheckErrorMacro("failed after DrawSpecialProps");
}
void vtkGL2PSExporter::HandleSpecialProp(vtkProp *prop, vtkRenderer *ren)
......@@ -790,6 +798,8 @@ void vtkGL2PSExporter::DrawViewportTextOverlay(const char *string,
vtkCoordinate *coord,
vtkRenderer *ren)
{
vtkOpenGLClearErrorMacro();
// Figure out the viewport information
int *winsize = this->RenderWindow->GetSize();
double *viewport = ren->GetViewport();
......@@ -825,6 +835,8 @@ void vtkGL2PSExporter::DrawViewportTextOverlay(const char *string,
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
vtkOpenGLCheckErrorMacro("failed after DrawViewportTextOverlay");
}
......@@ -835,6 +847,9 @@ void vtkGL2PSExporter::CopyPixels(int copyRect[4], vtkRenderer *ren)
vtkErrorMacro(<<"Raster image is not correctly formatted.")
return;
}
vtkOpenGLClearErrorMacro();
// Figure out the viewport information
int *winsize = this->RenderWindow->GetSize();
double *viewport = ren->GetViewport();
......@@ -893,6 +908,8 @@ void vtkGL2PSExporter::CopyPixels(int copyRect[4], vtkRenderer *ren)
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
vtkOpenGLCheckErrorMacro("failed after CopyPixels");
}
void vtkGL2PSExporter::DrawContextActors(vtkPropCollection *contextActs,
......
......@@ -36,6 +36,7 @@
#include "vtkWindow.h"
#include "vtkXMLDataElement.h"
#include "vtkXMLShader.h"
#include "vtkOpenGLError.h"
#include <Cg/cg.h>
#include <Cg/cgGL.h>
......@@ -469,6 +470,8 @@ void vtkCgShader::SetSamplerParameter(const char* name, vtkTexture* texture,int)
//-----------------------------------------------------------------------------
void vtkCgShader::PassShaderVariables(vtkActor* actor, vtkRenderer* renderer)
{
vtkOpenGLClearErrorMacro();
bool push_transform = (actor->GetIsIdentity() == 0);
if (push_transform)
{
......@@ -502,6 +505,8 @@ void vtkCgShader::PassShaderVariables(vtkActor* actor, vtkRenderer* renderer)
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
vtkOpenGLCheckErrorMacro("failed after PassShaderVariables");
}
//-----------------------------------------------------------------------------
......
......@@ -19,6 +19,7 @@
#include <cassert>
#include "vtkObjectFactory.h"
#include "vtkgl.h"
#include "vtkOpenGLError.h"
vtkStandardNewMacro(vtkContextBufferId);
......@@ -71,6 +72,8 @@ void vtkContextBufferId::SetValues(int srcXmin,
{
assert("pre: is_allocated" && this->IsAllocated());
vtkOpenGLClearErrorMacro();
GLint savedReadBuffer;
glGetIntegerv(GL_READ_BUFFER,&savedReadBuffer);
......@@ -110,6 +113,8 @@ void vtkContextBufferId::SetValues(int srcXmin,
}
delete[] rgb;
vtkOpenGLCheckErrorMacro("failed after SetValues");
}
// ----------------------------------------------------------------------------
......
......@@ -40,6 +40,7 @@
#include "vtkOpenGLExtensionManager.h"
#include "vtkShaderProgram2.h"
#include "vtkgl.h"
#include "vtkOpenGLError.h"
#include "vtkObjectFactory.h"
......@@ -96,6 +97,7 @@ void vtkOpenGL2ContextDevice2D::DrawPointSprites(vtkImageData *sprite,
unsigned char *colors,
int nc_comps)
{
vtkOpenGLClearErrorMacro();
if (points && n > 0)
{
this->SetPointSize(this->Pen->GetWidth());
......@@ -132,12 +134,14 @@ void vtkOpenGL2ContextDevice2D::DrawPointSprites(vtkImageData *sprite,
{
vtkWarningMacro(<< "Points supplied without a valid image or pointer.");
}
vtkOpenGLCheckErrorMacro("failed after DrawPointSprites");
}
//-----------------------------------------------------------------------------
void vtkOpenGL2ContextDevice2D::DrawImage(float p[2], float scale,
vtkImageData *image)
{
vtkOpenGLClearErrorMacro();
this->SetTexture(image);
this->Storage->Texture->Render(this->Renderer);
int *extent = image->GetExtent();
......@@ -162,12 +166,14 @@ void vtkOpenGL2ContextDevice2D::DrawImage(float p[2], float scale,
this->Storage->Texture->PostRender(this->Renderer);
glDisable(GL_TEXTURE_2D);
vtkOpenGLCheckErrorMacro("failed after DrawImage");
}
//-----------------------------------------------------------------------------
void vtkOpenGL2ContextDevice2D::DrawImage(const vtkRectf& pos,
vtkImageData *image)
{
vtkOpenGLClearErrorMacro();
GLuint index = this->Storage->TextureFromImage(image);
// this->SetTexture(image);
// this->Storage->Texture->Render(this->Renderer);
......@@ -193,6 +199,7 @@ void vtkOpenGL2ContextDevice2D::DrawImage(const vtkRectf& pos,
// this->Storage->Texture->PostRender(this->Renderer);
glDisable(GL_TEXTURE_2D);
glDeleteTextures(1, &index);
vtkOpenGLCheckErrorMacro("failed after DrawImage");
}
//----------------------------------------------------------------------------
......
......@@ -22,6 +22,7 @@
#include "vtkTextureObject.h"
#include "vtkgl.h"
#include "vtkOpenGLRenderWindow.h"
#include "vtkOpenGLError.h"
vtkStandardNewMacro(vtkOpenGLContextBufferId);
......@@ -118,6 +119,8 @@ vtkIdType vtkOpenGLContextBufferId::GetPickedItem(int x, int y)
{
assert("pre: is_allocated" && this->IsAllocated());
vtkOpenGLClearErrorMacro();
vtkIdType result=-1;
if(x<0 || x>=this->Width)
{
......@@ -220,6 +223,9 @@ vtkIdType vtkOpenGLContextBufferId::GetPickedItem(int x, int y)
}
assert("post: valid_result" && result>=-1 );
vtkOpenGLCheckErrorMacro("failed after GetPickedItem");
return result;
}
......
......@@ -43,6 +43,7 @@
#include "vtkOpenGLExtensionManager.h"
#include "vtkShaderProgram2.h"
#include "vtkgl.h"
#include "vtkOpenGLError.h"
#include "vtkObjectFactory.h"
#include "vtkContextBufferId.h"
......@@ -82,6 +83,7 @@ vtkOpenGLContextDevice2D::~vtkOpenGLContextDevice2D()
//-----------------------------------------------------------------------------
void vtkOpenGLContextDevice2D::Begin(vtkViewport* viewport)
{
vtkOpenGLClearErrorMacro();
// Need the actual pixel size of the viewport - ask OpenGL.
GLint vp[4];
glGetIntegerv(GL_VIEWPORT, vp);
......@@ -139,6 +141,7 @@ void vtkOpenGLContextDevice2D::Begin(vtkViewport* viewport)
glBindTexture(GL_TEXTURE_2D, 0);
this->InRender = true;
vtkOpenGLCheckErrorMacro("failed after Begin");
}
//-----------------------------------------------------------------------------
......@@ -149,6 +152,8 @@ void vtkOpenGLContextDevice2D::End()
return;
}
vtkOpenGLClearErrorMacro();
// push a 2D matrix on the stack
glMatrixMode(GL_PROJECTION);
glPopMatrix();
......@@ -168,6 +173,8 @@ void vtkOpenGLContextDevice2D::End()
this->RenderWindow = NULL;
this->InRender = false;
vtkOpenGLCheckErrorMacro("failed after End");
}
// ----------------------------------------------------------------------------
......@@ -177,6 +184,8 @@ void vtkOpenGLContextDevice2D::BufferIdModeBegin(
assert("pre: not_yet" && !this->GetBufferIdMode());
assert("pre: bufferId_exists" && bufferId!=0);
vtkOpenGLClearErrorMacro();
this->BufferId=bufferId;
// Save OpenGL state.
......@@ -205,6 +214,8 @@ void vtkOpenGLContextDevice2D::BufferIdModeBegin(
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
vtkOpenGLCheckErrorMacro("failed after BufferIdModeBegin");
assert("post: started" && this->GetBufferIdMode());
}
......@@ -213,6 +224,8 @@ void vtkOpenGLContextDevice2D::BufferIdModeEnd()
{
assert("pre: started" && this->GetBufferIdMode());
vtkOpenGLClearErrorMacro();
// Assume the renderer has been set previously during rendering (sse Begin())
int lowerLeft[2];
int usize, vsize;
......@@ -229,6 +242,9 @@ void vtkOpenGLContextDevice2D::BufferIdModeEnd()
this->Storage->RestoreGLState(true);
this->BufferId=0;
vtkOpenGLCheckErrorMacro("failed after BufferIdModeEnd");
assert("post: done" && !this->GetBufferIdMode());
}
......@@ -239,6 +255,8 @@ void vtkOpenGLContextDevice2D::DrawPoly(float *f, int n, unsigned char *colors,
assert("f must be non-null" && f != NULL);
assert("n must be greater than 0" && n > 0);
vtkOpenGLClearErrorMacro();
this->SetLineType(this->Pen->GetLineType());
this->SetLineWidth(this->Pen->GetWidth());
......@@ -263,12 +281,16 @@ void vtkOpenGLContextDevice2D::DrawPoly(float *f, int n, unsigned char *colors,
// Restore line type and width.
this->SetLineType(vtkPen::SOLID_LINE);
this->SetLineWidth(1.0f);
vtkOpenGLCheckErrorMacro("failed after DrawPoly");
}
//-----------------------------------------------------------------------------
void vtkOpenGLContextDevice2D::DrawPoints(float *f, int n, unsigned char *c,
int nc)
{
vtkOpenGLClearErrorMacro();
if (f && n > 0)
{
this->SetPointSize(this->Pen->GetWidth());
......@@ -294,6 +316,8 @@ void vtkOpenGLContextDevice2D::DrawPoints(float *f, int n, unsigned char *c,
{
vtkWarningMacro(<< "Points supplied that were not of type float.");
}
vtkOpenGLCheckErrorMacro("failed after DrawPoints");
}
//-----------------------------------------------------------------------------
......@@ -302,6 +326,7 @@ void vtkOpenGLContextDevice2D::DrawPointSprites(vtkImageData *sprite,
unsigned char *colors,
int nc_comps)
{
vtkOpenGLClearErrorMacro();
if (points && n > 0)
{
this->SetPointSize(this->Pen->GetWidth());
......@@ -386,6 +411,7 @@ void vtkOpenGLContextDevice2D::DrawPointSprites(vtkImageData *sprite,
{
vtkWarningMacro(<< "Points supplied without a valid image or pointer.");
}
vtkOpenGLCheckErrorMacro("failed after DrawPointSprites");
}
//-----------------------------------------------------------------------------
......@@ -402,6 +428,7 @@ void vtkOpenGLContextDevice2D::DrawMarkers(int shape, bool highlight,
//-----------------------------------------------------------------------------
void vtkOpenGLContextDevice2D::DrawQuad(float *f, int n)
{
vtkOpenGLClearErrorMacro();
if (!f || n <= 0)
{
vtkWarningMacro(<< "Points supplied that were not of type float.");
......@@ -429,11 +456,13 @@ void vtkOpenGLContextDevice2D::DrawQuad(float *f, int n)
glDisable(GL_TEXTURE_2D);
delete [] texCoord;
}
vtkOpenGLCheckErrorMacro("failed after DrawQuad");
}
//-----------------------------------------------------------------------------
void vtkOpenGLContextDevice2D::DrawQuadStrip(float *f, int n)
{
vtkOpenGLClearErrorMacro();
if (!f || n <= 0)
{
vtkWarningMacro(<< "Points supplied that were not of type float.");
......@@ -461,10 +490,12 @@ void vtkOpenGLContextDevice2D::DrawQuadStrip(float *f, int n)
glDisable(GL_TEXTURE_2D);
delete [] texCoord;
}
vtkOpenGLCheckErrorMacro("failed after DrawQuadStrip");
}
//-----------------------------------------------------------------------------
void vtkOpenGLContextDevice2D::DrawPolygon(float *f, int n)
{
vtkOpenGLClearErrorMacro();
if (!f || n <= 0)
{
vtkWarningMacro(<< "Points supplied that were not of type float.");
......@@ -492,6 +523,7 @@ void vtkOpenGLContextDevice2D::DrawPolygon(float *f, int n)
glDisable(GL_TEXTURE_2D);
delete [] texCoord;
}
vtkOpenGLCheckErrorMacro("failed after DrawPolygon");
}
//-----------------------------------------------------------------------------
......@@ -514,6 +546,8 @@ void vtkOpenGLContextDevice2D::DrawEllipseWedge(float x, float y, float outRx,
return;
}
vtkOpenGLClearErrorMacro();
int iterations=this->GetNumberOfArcIterations(outRx,outRy,startAngle,
stopAngle);
......@@ -556,6 +590,8 @@ void vtkOpenGLContextDevice2D::DrawEllipseWedge(float x, float y, float outRx,
glDisableClientState(GL_VERTEX_ARRAY);
delete[] p;
vtkOpenGLCheckErrorMacro("failed after DrawEllipseWedge");
}
// ----------------------------------------------------------------------------
......@@ -571,6 +607,9 @@ void vtkOpenGLContextDevice2D::DrawEllipticArc(float x, float y, float rX,
// we make sure maxRadius will never be null.
return;
}
vtkOpenGLClearErrorMacro();
int iterations = this->GetNumberOfArcIterations(rX, rY, startAngle, stopAngle);
float *p = new float[2*(iterations+1)];
......@@ -605,6 +644,8 @@ void vtkOpenGLContextDevice2D::DrawEllipticArc(float x, float y, float rX,
this->SetLineWidth(1.0f);
delete[] p;
vtkOpenGLCheckErrorMacro("failed after DrawEllipseArc");
}
// ----------------------------------------------------------------------------
......@@ -758,6 +799,8 @@ void vtkOpenGLContextDevice2D::AlignText(double orientation, float width,
void vtkOpenGLContextDevice2D::DrawString(float *point,
const vtkStdString &string)
{
vtkOpenGLClearErrorMacro();
GLfloat mv[16];
glGetFloatv(GL_MODELVIEW_MATRIX, mv);
float xScale = mv[0];
......@@ -817,6 +860,8 @@ void vtkOpenGLContextDevice2D::DrawString(float *point,
texture->PostRender(this->Renderer);
glDisable(GL_TEXTURE_2D);
vtkOpenGLCheckErrorMacro("failed after DrawString");
}
//-----------------------------------------------------------------------------
......@@ -898,6 +943,8 @@ void vtkOpenGLContextDevice2D::DrawMathTextString(float point[2],
return;
}
vtkOpenGLClearErrorMacro();
float p[] = { std::floor(point[0]), std::floor(point[1]) };
// Cache rendered text strings
......@@ -957,12 +1004,16 @@ void vtkOpenGLContextDevice2D::DrawMathTextString(float point[2],
texture->PostRender(this->Renderer);
glDisable(GL_TEXTURE_2D);
vtkOpenGLCheckErrorMacro("failed after DrawMathTexString");
}
//-----------------------------------------------------------------------------
void vtkOpenGLContextDevice2D::DrawImage(float p[2], float scale,
vtkImageData *image)
{
vtkOpenGLClearErrorMacro();
this->SetTexture(image);
this->Storage->Texture->Render(this->Renderer);
int *extent = image->GetExtent();
......@@ -987,12 +1038,16 @@ void vtkOpenGLContextDevice2D::DrawImage(float p[2], float scale,
this->Storage->Texture->PostRender(this->Renderer);
glDisable(GL_TEXTURE_2D);
vtkOpenGLCheckErrorMacro("failed after DrawImage");
}
//-----------------------------------------------------------------------------
void vtkOpenGLContextDevice2D::DrawImage(const vtkRectf& pos,
vtkImageData *image)
{
vtkOpenGLClearErrorMacro();
vtkVector2f tex(1.0, 1.0);
GLuint index = 0;
if (this->Storage->PowerOfTwoTextures)
......@@ -1027,6 +1082,8 @@ void vtkOpenGLContextDevice2D::DrawImage(const vtkRectf& pos,
// this->Storage->Texture->PostRender(this->Renderer);
glDisable(GL_TEXTURE_2D);
glDeleteTextures(1, &index);
vtkOpenGLCheckErrorMacro("failed after DrawImage");
}
//-----------------------------------------------------------------------------
......@@ -1199,15 +1256,19 @@ void vtkOpenGLContextDevice2D::GetMatrix(vtkMatrix3x3 *m)
//-----------------------------------------------------------------------------
void vtkOpenGLContextDevice2D::PushMatrix()
{
vtkOpenGLClearErrorMacro();
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
vtkOpenGLCheckErrorMacro("failed after PushMatrix");
}
//-----------------------------------------------------------------------------
void vtkOpenGLContextDevice2D::PopMatrix()
{
vtkOpenGLClearErrorMacro();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
vtkOpenGLCheckErrorMacro("failed after PopMatrix");
}
//-----------------------------------------------------------------------------
......
......@@ -20,9 +20,9 @@
#include "vtkMatrix4x4.h"
#include "vtkOpenGLRenderer.h"
#include "vtkOpenGLRenderWindow.h"
#include "vtkOpenGLExtensionManager.h"
#include "vtkgl.h"
#include "vtkOpenGLError.h"