#161 Line clipping bug

Rasterization
open
Defect (99)
7
2005-10-05
2005-10-04
rob__
No

There seems to be a line clipping bug when drawing
GL_LINES, GL_LINE_STRIP or GL_LINE_LOOP.

It looks like only one end of the line is incorrectly
clipped (the line is positioned at the edge of the screen,
but the position along the edge is warped). The lines
that are clipped incorrectly are also drawn in black,
regardless of what color I set using glColor4x() (the
nonclipped lines have the correct color).

I am using GL_SHORT when setting the glVertexPointer
(), and use glDrawArrays() to draw the lines.

I am using ogl-es-bin-0.84a

Here is some code that should reproduce this issue:

.h file

class CRendableGrid
{
public:
CRendableGrid(int iGridCount = 10, int
iGridSize = 10);
virtual void Draw();
virtual ~CRendableGrid();

GLshort* m_pVertexArrayGrid;
int m_iNumElementsGrid;
GLshort* m_pVertexArrayCenterLines;
int m_iNumElementsCenterLines;
};

// note this is a mfc dialog ...remove the mfc things if
you use it without mfc
class CViewDlg : public CDialog
{
// Construction
public:
CViewDlg(CWnd* pParent = NULL);
// standard constructor

// Dialog Data
//{{AFX_DATA(CViewDlg)
enum { IDD = IDD_VIEW_DIALOG };
CButton m_ButtonPerspective;
//}}AFX_DATA

// ClassWizard generated virtual function
overrides
//{{AFX_VIRTUAL(CViewDlg)
protected:
virtual void DoDataExchange
(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL

enum EViewMode
{
Perspective = 0,
Top,
Left,
Front
};

EViewMode GetViewMode() { return
m_ViewMode; }
void SetViewMode(EViewMode viewMode);

// Implementation
protected:
HICON m_hIcon;

// Generated message map functions
//{{AFX_MSG(CViewDlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg void OnDestroy();
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnLButtonDown(UINT nFlags,
CPoint point);
afx_msg void OnLButtonUp(UINT nFlags,
CPoint point);
afx_msg void OnMouseMove(UINT nFlags,
CPoint point);
afx_msg void OnButtonPerspective();
afx_msg void OnButtonRotate();
afx_msg void OnButtonMove();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()

bool InitEGL(); // Initialize
native window system for OpenGL ES rendering into an
EGL surface
void InitGL(); // Initialize
OpenGL ES settings for rendering
void RenderGL(); // Do the rendering
using OpenGL ES
void CloseEGL(); // De-initialize EGL

// gluPerspective-like helper function
void gluPerspective(GLfloat fovy, GLfloat
aspect, GLfloat znear, GLfloat zfar);

// Update the opengl projection matrix
according to the current settings (aspect ratio, view type
(top, front, side, or perspective))
void UpdateProjectionMatrix();

CDC* m_pCDC; // WinGDI Device
Context

// EGL variables
EGLDisplay m_GLESDisplay; // EGL
display
EGLSurface m_GLESSurface; // EGL
rendering surface
EGLContext m_GLESContext; // EGL
rendering context

// Currently selected view mode
EViewMode m_ViewMode;

// Current aspect ratio of our view
float m_fAspectRatio;
};

.cpp file

// Initialize EGL
bool CViewDlg::InitEGL()
{
EGLConfig configs[10];
EGLint matchingConfigs;

const EGLint configAttribs[] =
{
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE,
EGL_DONT_CARE,
EGL_DEPTH_SIZE, 16,
EGL_STENCIL_SIZE,
EGL_DONT_CARE,
EGL_SURFACE_TYPE,
EGL_WINDOW_BIT,
EGL_NONE, EGL_NONE
};

HDC hDC = m_pCDC->GetSafeHdc();
m_GLESDisplay = eglGetDisplay(hDC);

if(!eglInitialize(m_GLESDisplay, NULL,
NULL))
return false;

if (!eglChooseConfig(m_GLESDisplay,
configAttribs, &configs[0], 10, &matchingConfigs))
return false;

if (matchingConfigs < 1) return false;

m_GLESSurface = eglCreateWindowSurface
(m_GLESDisplay, configs[0], this->m_hWnd,
configAttribs);
if (!m_GLESSurface) return false;

m_GLESContext = eglCreateContext
(m_GLESDisplay, configs[0], 0, configAttribs);
if (!m_GLESContext) return false;

// Activate the context for rendering (move to
rendering loop?)
eglMakeCurrent(m_GLESDisplay,
m_GLESSurface, m_GLESSurface, m_GLESContext);
return true;
}

void CViewDlg::InitGL()
{
// Set background clear color to typical-3d-
editor-gray
glClearColor(0.69f, 0.69f, 0.69f, 0.0f);

// Set Z-Buffer clear value
glClearDepthf(1.0f);

// Enable Z-Buffer
glEnable(GL_DEPTH_TEST);

// Smooth shading
glShadeModel(GL_SMOOTH);

// Setup face culling
glCullFace(GL_BACK); // cull back facing
polygons (default)
glFrontFace(GL_CCW); // front facing
polygons are ccw (default)
glEnable(GL_CULL_FACE); // Enable
face culling

// Set a viewport that fits entirely our window
RECT rect;
GetWindowRect(&rect);
glViewport(rect.left, rect.top, rect.right -
rect.left, rect.bottom - rect.top);

int cx = rect.right - rect.left;
int cy = rect.bottom - rect.top;
if (cy!=0)
{
m_fAspectRatio = (float)cx / (float)
cy;
}

// Setup of the projection matrix.
m_ViewMode = EViewMode::Perspective;
UpdateProjectionMatrix();

// Load identity matrix into our opengl model
view matrix
glLoadIdentity();
}

// gluPerspective-like helper function
void CViewDlg::gluPerspective(GLfloat fovy, GLfloat
aspect, GLfloat znear, GLfloat zfar)
{
GLfloat xmin, xmax, ymin, ymax;
ymax = znear * tan(fovy * M_PI / 360.0f);
ymin = -ymax;

xmin = ymin * aspect;
xmax = ymax * aspect;

glFrustumx(
(GLfixed)(xmin*(float)(1 << 16)),
(GLfixed)(xmax*(float)(1 << 16)),
(GLfixed)(ymin*(float)(1 << 16)),
(GLfixed)(ymax*(float)(1 << 16)),
(GLfixed)(znear*(float)(1 << 16)),
(GLfixed)(zfar*(float)(1 << 16)));
}

// Update the opengl projection matrix according to the
current settings (aspect ratio, view type (top, front, side,
or perspective))
void CViewDlg::UpdateProjectionMatrix()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

switch (m_ViewMode)
{
case EViewMode::Perspective:
gluPerspective(80.0,
m_fAspectRatio, 8.0f, 2000.0f); // 8.0f for the low z-buf
resolution
break;
case EViewMode::Top:
case EViewMode::Left:
case EViewMode::Front:
glOrthox(-50 << 16, 50 << 16, -50
<< 16, 50 << 16, -1000 << 16, 1000 << 16);
break;
}
glMatrixMode(GL_MODELVIEW);
}

void CViewDlg::SetViewMode(EViewMode viewMode)
{
m_ViewMode = viewMode;
UpdateProjectionMatrix();
}

// Do the rendering using OpenGL ES
void CViewDlg::RenderGL()
{
static int rotation = 0;

glClear(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT);

glLoadIdentity();

// Position the view according to the view
mode
switch (m_ViewMode)
{
case EViewMode::Perspective:
glTranslatef(0.0f, 0.0f, -200.0f);
glRotatef(-75.0f, 1.0f, 0.0f, 0.0f);

break;
case EViewMode::Top:
break;
case EViewMode::Left:
glRotatef(90.0f, 0.0f, 1.0f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
break;
case EViewMode::Front:
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
break;
}

// Render geometry...
glTranslatex(0, 0, -10 << 16);
glRotatex((rotation++) >> 16, 0, 0, 1 >> 16);

CRendableGrid rg;
rg.Draw();
}

CRendableGrid::CRendableGrid(int iGridCount, int
iGridSize)
{
m_iNumElementsGrid = (iGridCount * 2) * 2
* 2;
m_pVertexArrayGrid = (GLshort*)malloc
(sizeof(GLshort) * 3 * m_iNumElementsGrid);

m_iNumElementsCenterLines = 2 * 2;
m_pVertexArrayCenterLines = (GLshort*)
malloc(sizeof(GLshort) * 3 *
m_iNumElementsCenterLines);

int ii = 0;
// Generate Grid
for (int i = -iGridCount; i <= iGridCount; i++)
{
// Skip center line
if (i == 0) continue;

m_pVertexArrayGrid[ii++] = i *
iGridSize;
m_pVertexArrayGrid[ii++] = -
iGridCount * iGridSize;
m_pVertexArrayGrid[ii++] = 0;

m_pVertexArrayGrid[ii++] = i *
iGridSize;
m_pVertexArrayGrid[ii++] =
iGridCount * iGridSize;
m_pVertexArrayGrid[ii++] = 0;
}

for (i = -iGridCount; i <= iGridCount; i++)
{
// Skip center line
if (i == 0) continue;

m_pVertexArrayGrid[ii++] = -
iGridCount * iGridSize;
m_pVertexArrayGrid[ii++] = i *
iGridSize;
m_pVertexArrayGrid[ii++] = 0;

m_pVertexArrayGrid[ii++] =
iGridCount * iGridSize;
m_pVertexArrayGrid[ii++] = i *
iGridSize;
m_pVertexArrayGrid[ii++] = 0;
}

// Generate Center Lines
m_pVertexArrayCenterLines[0] = 0;
m_pVertexArrayCenterLines[1] = -iGridCount
* iGridSize;
m_pVertexArrayCenterLines[2] = 0;

m_pVertexArrayCenterLines[3] = 0;
m_pVertexArrayCenterLines[4] = iGridCount
* iGridSize;
m_pVertexArrayCenterLines[5] = 0;

m_pVertexArrayCenterLines[6] = -iGridCount
* iGridSize;
m_pVertexArrayCenterLines[7] = 0;
m_pVertexArrayCenterLines[8] = 0;

m_pVertexArrayCenterLines[9] = iGridCount
* iGridSize;
m_pVertexArrayCenterLines[10] = 0;
m_pVertexArrayCenterLines[11] = 0;
}

CRendableGrid::~CRendableGrid()
{
free(m_pVertexArrayCenterLines);
free(m_pVertexArrayGrid);
}

void CRendableGrid::Draw()
{
//Enable the vertices array
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_SHORT, 0,
m_pVertexArrayGrid); // 3 = XYZ coordinates,
GL_SHORT = data type, 0 = 0 stride bytes

// Set a single color for the whole grid
glColor4x(128 << 8, 128 << 8, 128 << 8, 0);

// Set shademodel
glShadeModel(GL_FLAT);

// Draw lines, 0 = first element
glDrawArrays(GL_LINES, 0,
m_iNumElementsGrid);

// Draw center lines with a wider line
glLineWidthx(2);

// Set a darker color for the center lines
glColor4x(90 << 8, 90 << 8, 90 << 8, 0);

// Draw center lines, 0 = first element
glVertexPointer(3, GL_SHORT, 0,
m_pVertexArrayCenterLines); // 3 = XYZ
coordinates, GL_SHORT = data type, 0 = 0 stride bytes
glDrawArrays(GL_LINES, 0,
m_iNumElementsCenterLines);

// Go back to default line width
glLineWidthx(1);

// Go back to orig shademodel
glShadeModel(GL_SMOOTH);

glDisableClientState(GL_VERTEX_ARRAY);
}

Discussion

    • milestone: --> Rasterization
    • priority: 5 --> 7
    • assigned_to: nobody --> hmwill
     
  • Logged In: YES
    user_id=618887

    Is this still an issue? I rewrote the clipping code for 1.0.

    - HM

     
  • rob__
    rob__
    2006-07-07

    eMVC4 project and executable for reproducing the bug

     
    Attachments
  • rob__
    rob__
    2006-07-07

    Logged In: YES
    user_id=1349364

    Yes, I have checked with the new xscale release dll.
    But now the lines disappear instead of turning black.

    I have attached an eMVC4 project and executable for
    reproducing this (on a Windows Mobile 2003 PDA).