PDA

View Full Version : Overwritting Shapes



nrobi
01-23-2009, 04:19 AM
I had this very simple idea. I'm not sure if anyone has ever seen a candle stick chart but essentially it's a 1px line from the high to low and a (1*n)px line from open to close in whatever time period. I'm building a program to test different trading systems and wanted to use these candlestick charts in the app.

This is something probably really simple (but its many years since I tinkered with OGL). My problem is this I had 1 loop. I set the line width to a certain level and draw the line from open to close.. then set the width to 1px and draw another from high to low.

The result is one set of lines... from high to low.

Then I put it in two loops... 1 for GL_LINES and one for GL_QUADS. Same result, only 1px lines from high to low. If I comment out the code to draw the lines from high to low I see the wider lines from open to close "underneath."

I changed z-depth, enabled depth testing, etc... no difference

What am I doing wrong? I'd like to use GL_LINES to write everything and not use QUADS if possible. My code is as follows (kinda simple as I'm just testing things atm):


void COpenGLWnd::OnPaint()
{
//CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
int iSize = theApp.ts.data.size();
int iZoom = 1;
int width = (1 << iZoom) + 1;
int unit = width + iZoom;
int i,offset = 0;

this->GetClientRect(&rect);

int nCandles = rect.right/unit;
float top = ::hilo(theApp.ts.data,nCandles,nCandles,HL_HIGH),
bottom = ::hilo(theApp.ts.data,nCandles,nCandles,HL_LOW);

this->EnableOpenGL();

::glClearColor(0.0f,0.0f,0.0f,0.0f);
::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
::glEnable(GL_DEPTH_TEST);

::glMatrixMode(GL_PROJECTION);
::glLoadIdentity();
::glOrtho(0,rect.right,bottom,top,0,1);

::glMatrixMode(GL_MODELVIEW);
::glLoadIdentity();

glBegin(GL_LINES);
for(i=0;i<nCandles;++i) {
if(theApp.ts.data[i].fPrice[OPEN] < theApp.ts.data[i].fPrice[CLOSE])
glColor3f(0.0f,0.0f,1.0f);
else if(theApp.ts.data[i].fPrice[OPEN] > theApp.ts.data[i].fPrice[CLOSE])
glColor3f(1.0f,0.0f,0.0f);
else
glColor3f(0.0f,1.0f,1.0f);

offset += unit; //(unit-1) >> 1;

/* glLineWidth((float)width);
glVertex3f(offset,theApp.ts.data[i].fPrice[OPEN],0.0f);
glVertex3f(offset,theApp.ts.data[i].fPrice[CLOSE],0.0f);
*/
glLineWidth(1.0f);
glVertex3f(offset,theApp.ts.data[i].fPrice[HIGH],0.0f);
glVertex3f(offset,theApp.ts.data[i].fPrice[LOW],0.0f);
}
glEnd();

glBegin(GL_QUADS);
for(i=0;i<nCandles;++i) {
if(theApp.ts.data[i].fPrice[OPEN] < theApp.ts.data[i].fPrice[CLOSE])
glColor3f(0.0f,0.0f,1.0f);
else if(theApp.ts.data[i].fPrice[OPEN] > theApp.ts.data[i].fPrice[CLOSE])
glColor3f(1.0f,0.0f,0.0f);
else
glColor3f(0.0f,1.0f,1.0f);

offset += unit; //(unit-1) >> 1;

glVertex3f(offset-iZoom,theApp.ts.data[i].fPrice[OPEN],0.1f);
glVertex3f(offset+iZoom,theApp.ts.data[i].fPrice[OPEN],0.1f);
glVertex3f(offset+iZoom,theApp.ts.data[i].fPrice[CLOSE],0.1f);
glVertex3f(offset-iZoom,theApp.ts.data[i].fPrice[CLOSE],0.1f);
}
glEnd();

::SwapBuffers(hDC);

this->DisableOpenGL();

// Do not call CWnd::OnPaint() for painting messages
}

Rosario Leonardi
01-23-2009, 04:53 AM
You can simply disable the depth test and draw the thin line and then the wide one.

ps: use the tag CODE to post your code, this tag will preserve indentation.

nrobi
01-23-2009, 11:59 AM
Logic bug as usual.... I always seem to find myself using faulty logic. (I never reset offset back to zero for second loop.) I can draw it with GL_LINES and GL_QUADS. Is there some way to do it just with GL_LINES and switch line widths? That is definitely not working and I'm not sure why. Basically whats happening is nothing until I enable GL_LINE_SMOOTH and then it seems I can either draw wide lines or thin lines but not both.

I did a little testing and no matter what I set the line width to w/ line smooth disabled it's 1px and enabled it's 2 px. My original intention was to use the different width settings to create something like this:

http://imgcash1.imageshack.us/Himg214/scaled.php?server=214&filename=20080326euui8.gif&xsize=640&ysize=480

Please forgive me if these are real noob questions I'm not working with any book :(. Internet searches haven't helped out too much yet.

Rosario Leonardi
01-23-2009, 01:43 PM
Sorry if I didn't notice your error earlyer...

From glLineWidth documentation:

GL_INVALID_OPERATION is generated if glLineWidth is executed between the execution of glBegin and the corresponding execution of glEnd.

You can't switch the width inside the glBegin/glEnd block. You should do something like this:

glLineWidth(1.0);
glBegin(GL_LINES)
draw all the thin lines
glEnd();
glLineWidth(3.0);
glBegin(GL_LINES)
draw all the fat lines
glEnd();
P.S. As far as I remember glLineWidth with width > 1 is deprecated in openGL 3.0.

nrobi
01-23-2009, 07:22 PM
Thanks Rosario. I feel kinda like Homer Simpson at this moment as I read my MSDN 97 documentation more carefully. (I usually skip anything below the return value. Errors are usually last on the page. I'll have to be more diligent in reading.) I think I'm working with OGL 1.1 on my machine. I'm a little behind the times :)

After reading your comments, if I remember correctly no state can be changed within glBegin/End blocks correct?

Thanks again Rosario.

ZbuffeR
01-24-2009, 01:20 AM
you can change normal, color, texcoord though.