SuperBible 5th Edition Chap2-Triangles Not Working

I cannot get the source code from Chapter 2 “Triangles” to work. It renders the background, but the triangle is not rendered. It seems to have something to do with triangleBatch, because when I move the triangle assignment lines to directly above the trianglebatch.draw, everything works. Since triangleBatch is a global variable, I don’t understand why this code doesn’t work. This is the exact same source as found in the book.

I’ve attached the source below.

#include <GLTools.h>
#include <GLShaderManager.h>
#include <iostream>

#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif

using namespace std;

GLBatch triangleBatch;
GLShaderManager shaderManager;
char test[] = "TEST";

void ChangeSize(int w, int h)
{
	glViewport(0,0,w,h);
}

void SetupRC()
{
	cout << "SetupRC" << endl;
	glClearColor(0.0f,0.0f,1.0f,1.0f);
	
	shaderManager.InitializeStockShaders();

	GLfloat vVerts[] = {-0.5f,0.0f,0.0f,0.5f,0.0f,0.0f,0.0f,0.5f,0.0f};


	triangleBatch.Begin(GL_TRIANGLES, 3);
	triangleBatch.CopyVertexData3f(vVerts);
	triangleBatch.End();
	std::cout << "SetupRC....Complete" << endl;

	cout << test << endl;
}

void RenderScene(void)
{
	std::cout << "RenderScene
";
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	GLfloat vRed[] = {1.0f,0.0f,0.0f,1.0f};
	shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);

	triangleBatch.Draw();

	glutSwapBuffers();
}

int main(int argc, char* argv[])
{
	gltSetWorkingDirectory(argv[0]);
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
	glutInitWindowSize(800, 600);
	glutCreateWindow("Triangle");
	glutReshapeFunc(ChangeSize);
	glutDisplayFunc(RenderScene);


	GLenum err= glewInit();
	if(GLEW_OK != err){
		fprintf(stderr, "GLEW Error: %s
", glewGetErrorString(err));
		return 1;
	}

	SetupRC();

	glutMainLoop();
	return 0;
}

I compiled and executed your file and saw the triangle. I didnt move those 3 triangle assignment lines from SetupRC to the render function.

Maybe it helps to download gltools again.
What OS are you using?

Thanks for testing it out.

Windows 7 64-bit SP1

Visual Studio 2010

I’ll re-“git” gltools and see if it helps

I re-downloaded the latest revision of the SuperBible 5th Edition repo. Still no luck. No compiler errors or warnings either.

Edit:
I’ve even tried recompiling free-glut and gltools in Visual Studio 2010. The newer lib’s didn’t help.

Maybe it’s because of visual studio 2010 and you forgot to check some options / include some files or it’s because you’re using visual studio 2010 and not visual studio 2008 (if that makes any difference at all).

But still your error is quite weird because triangleBatch is a global variable like you mentioned already.

Other than that i have no idea what to do… im using linux, cant help you much with windows or visual studio

Hmm :stuck_out_tongue: Yeah, I can’t imagine it being a compiler setting, but I just don’t know. I tested the globals with that “std::string test” variable. It works as expected. Although it seems like triangleBatch variable is acting local when it is indeed global. Like I said, everything works like it’s suppose to, but only if triangleBatch is declared locally.

Can anyone else compile this in Visual Studio 2010? I’m guessing this may only work in 2008?

Any recommendations on a different compiler & IDE for windows/linux/mac? I’m hating Visual Studio’s “intellisense” (or lack thereof) anyway.

I think I may have found the source of the issue, but I don’t quite understand how to fix it.

Apparently, all my global variables seems to automatically be declared as constants. Is this a compiler setting?

I’ve never come across this in C++ before.

Edit:
Nevermind, I’m a noob and incorrectly assigned my test variable, causing an error that said somthing about my test array being const…turns out I was wrong.

I’m still puzzled about why this won’t work globally though. :frowning:

Executing the triangleBatch code in “SetupRC” twice seems to resolve the issue. Why would I have to be calling the code twice?


triangleBatch.Begin(GL_TRIANGLES, 3);
triangleBatch.CopyVertexData3f(vVerts);
triangleBatch.End();
triangleBatch.Begin(GL_TRIANGLES, 3);
triangleBatch.CopyVertexData3f(vVerts);
triangleBatch.End();

I just installed VS2008, ran the same code and I still have the same issue. Any ideas?

Nvm, got it. Made a typo with numbers

I have downloaded and ran you code and it works fine here. I am on Wndows 7 64bit.

I dont get any compiler errors or anything. It works fine.
One thing you can do is add an assertion in the DrawScene function.


void DrawScene() {
   GLuint error = glGetError()
   assert(error==GL_NO_ERROR);
   //... rest of the stuff
}

If you get an assertion, let us know the value returned by glGetError.

Hey sorry to resurrect an oldish thread but I’m having the same issue. It also happens on their “primitive” example in chapter 3 but I’ve noticed some odd things about it.

All the primitives work in this example except for the triangle strips. Using triangleStripBatch.CopyVertexData3f(vPoints) twice seems to get it to display.

i.e.


    triangleStripBatch.Begin(GL_TRIANGLE_STRIP, iCounter);
    triangleStripBatch.CopyVertexData3f(vPoints);
    triangleStripBatch.CopyVertexData3f(vPoints);
    triangleStripBatch.End(); 

But what is really blowing my mind is that if I call pointBatch.CopyVertexData3f(vCoast) twice in the point GLBatch it also gets the triangle strip to display.

i.e.


    pointBatch.Begin(GL_POINTS, 24);
    pointBatch.CopyVertexData3f(vCoast);
    pointBatch.CopyVertexData3f(vCoast);
    pointBatch.End();

Any ideas? I’m trying to look past these small issues because I’m sure I can learn lots from this book but it’s only the 3rd chapter and I’m concerned I’m gonna hit a wall. I could
read through just for theory but I find a little hands on approach helps me learn better.

Full code below.

Windows 7-64bit
Visual Studio 2010
4870x2 (if that matters)



void SetupRC()
	{
    // Black background
    glClearColor(0.7f, 0.7f, 0.7f, 1.0f );

	shaderManager.InitializeStockShaders();

	glEnable(GL_DEPTH_TEST);

	transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);

	cameraFrame.MoveForward(-15.0f);
    
    //////////////////////////////////////////////////////////////////////
    // Some points, more or less in the shape of Florida
    GLfloat vCoast[24][3] = {{2.80, 1.20, 0.0 }, {2.0,  1.20, 0.0 },
                            {2.0,  1.08, 0.0 },  {2.0,  1.08, 0.0 },
                            {0.0,  0.80, 0.0 },  {-.32, 0.40, 0.0 },
                            {-.48, 0.2, 0.0 },   {-.40, 0.0, 0.0 },
                            {-.60, -.40, 0.0 },  {-.80, -.80, 0.0 },
                            {-.80, -1.4, 0.0 },  {-.40, -1.60, 0.0 },
                            {0.0, -1.20, 0.0 },  { .2, -.80, 0.0 },
                            {.48, -.40, 0.0 },   {.52, -.20, 0.0 },
                            {.48,  .20, 0.0 },   {.80,  .40, 0.0 },
                            {1.20, .80, 0.0 },   {1.60, .60, 0.0 },
                            {2.0, .60, 0.0 },    {2.2, .80, 0.0 },
                            {2.40, 1.0, 0.0 },   {2.80, 1.0, 0.0 }};
    
    // Load point batch
    pointBatch.Begin(GL_POINTS, 24);
    pointBatch.CopyVertexData3f(vCoast);
    pointBatch.End();
    
    // Load as a bunch of line segments
    lineBatch.Begin(GL_LINES, 24);
    lineBatch.CopyVertexData3f(vCoast);
    lineBatch.End();
    
    // Load as a single line segment
    lineStripBatch.Begin(GL_LINE_STRIP, 24);
    lineStripBatch.CopyVertexData3f(vCoast);

    lineStripBatch.End();
    
    // Single line, connect first and last points
    lineLoopBatch.Begin(GL_LINE_LOOP, 24);
    lineLoopBatch.CopyVertexData3f(vCoast);
    lineLoopBatch.End();
    
    // For Triangles, we'll make a Pyramid
    GLfloat vPyramid[12][3] = { -2.0f, 0.0f, -2.0f, 
                                2.0f, 0.0f, -2.0f, 
                                0.0f, 4.0f, 0.0f,
                                
                                2.0f, 0.0f, -2.0f,
                                2.0f, 0.0f, 2.0f,
                                0.0f, 4.0f, 0.0f,
                                
                                2.0f, 0.0f, 2.0f,
                                -2.0f, 0.0f, 2.0f,
                                0.0f, 4.0f, 0.0f,
                                
                                -2.0f, 0.0f, 2.0f,
                                -2.0f, 0.0f, -2.0f,
                                 0.0f, 4.0f, 0.0f};
    
    triangleBatch.Begin(GL_TRIANGLES, 12);
    triangleBatch.CopyVertexData3f(vPyramid);
    triangleBatch.End();
    

    // For a Triangle fan, just a 6 sided hex. Raise the center up a bit
    GLfloat vPoints[100][3];    // Scratch array, more than we need
    int nVerts = 0;
    GLfloat r = 3.0f;
    vPoints[nVerts][0] = 0.0f;
    vPoints[nVerts][1] = 0.0f;
    vPoints[nVerts][2] = 0.0f;

    for(GLfloat angle = 0; angle < M3D_2PI; angle += M3D_2PI / 6.0f) {
        nVerts++;
        vPoints[nVerts][0] = float(cos(angle)) * r;
        vPoints[nVerts][1] = float(sin(angle)) * r;
        vPoints[nVerts][2] = -0.5f;
        }

    // Close the fan
    nVerts++;
    vPoints[nVerts][0] = r;
    vPoints[nVerts][1] = 0;
    vPoints[nVerts][2] = 0.0f;
        
    // Load it up
    triangleFanBatch.Begin(GL_TRIANGLE_FAN, 8);
    triangleFanBatch.CopyVertexData3f(vPoints);
    triangleFanBatch.End();     
        
    // For triangle strips, a little ring or cylinder segment
    int iCounter = 0;
    GLfloat radius = 3.0f;
    for(GLfloat angle = 0.0f; angle <= (2.0f*M3D_PI); angle += 0.3f)
		{
        GLfloat x = radius * sin(angle);
        GLfloat y = radius * cos(angle);
            
        // Specify the point and move the Z value up a little	
        vPoints[iCounter][0] = x;
        vPoints[iCounter][1] = y;
        vPoints[iCounter][2] = -0.5;
        iCounter++;

        vPoints[iCounter][0] = x;
        vPoints[iCounter][1] = y;
        vPoints[iCounter][2] = 0.5;
        iCounter++;            
		}

    // Close up the loop
    vPoints[iCounter][0] = vPoints[0][0];
    vPoints[iCounter][1] = vPoints[0][1];
    vPoints[iCounter][2] = -0.5;
    iCounter++;
    
    vPoints[iCounter][0] = vPoints[1][0];
    vPoints[iCounter][1] = vPoints[1][1];
    vPoints[iCounter][2] = 0.5;
    iCounter++;            
        
    // Load the triangle strip
    triangleStripBatch.Begin(GL_TRIANGLE_STRIP, iCounter);
    triangleStripBatch.CopyVertexData3f(vPoints);
    triangleStripBatch.End();    
    }



Rounder,

Same problem here. We have the same setup just about, too.

Win7 x64
VS2010
4850x2

Could it be a driver issue?

Doing the CopyVertexData3f call twice works.


triangleBatch.Vertex3f(-1.0f, 0.0f, 0.0f);
triangleBatch.Vertex3f(1.0f, 0.0f, 0.0f);
triangleBatch.Vertex3f(0.0f, 1.0f, 0.0f);

This also works fine by itself. May just continue with doing the CopyVertexData3f call twice to keep it simple.

I still haven’t been able to solve it.