Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: OpenGL 3.1 stack overflow

  1. #1
    Intern Contributor
    Join Date
    Jun 2012
    Posts
    71

    OpenGL 3.1 stack overflow

    I recently made my own vertex class, vertexColored, to hold position and color data. I changed from passing a std::vector of glm::vec3 to my VBO, to passing a std::vector of vectorColored. The class is defined like this:
    Code :
    //vertexTypes.h
    #ifndef VERTEXTYPES_H
    #define VERTEXTYPES_H
    #include <glm\glm.hpp>
    class vertexColored
    {
    public:
    	vertexColored();
    	~vertexColored();
    	glm::vec3 vertexPos;
    	glm::vec4 vertexColor;
    };
    #endif // VERTEXTYPES_H
    Code :
    //vertexTypes.cpp
    #include "vertexTypes.h"
    vertexColored::vertexColored()
    {
    	this->vertexPos = glm::vec3(0.0f, 0.0f, 0.0f);
    	this->vertexColor = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
    }
    vertexColored::~vertexColored()
    {
    }
    And I have also brush.h:
    Code :
    //brush.h
    #ifndef BRUSH_H
    #define BRUSH_H
    #include <GL/glew.h>
    #include <glm/glm.hpp>
    #include <vector>
    #include "vertexTypes.h"
    class brush
    {
    public:
        brush();
        ~brush();
        void updateVertices();
        void render();
        void makeBuffers();
        //other stuff...
     
    private:
        GLuint vboId, iboId;
        std::vector<vertexColored> brushVecs;
        std::vector<GLuint> brushIndices;
        //other stuff...
    };
    #endif // BRUSH_H
    And inside brush.cpp:
    Code :
    #include "brush.h"
    brush::brush()
    {
    	this->size = 2;
    	this->brushVecs.reserve(0);
    	this->brushIndices.reserve(0);
    }
    brush::~brush()
    {
    	glDeleteBuffers(1, &(this->vboId));
    	glDeleteBuffers(1, &(this->iboId));
    }
     
    void brush::updateVertices(){
        int numPoints = ((2 * this->size) + 1) * ((2 * this->size) + 1);
    	if (this->brushVecs.capacity() < numPoints)
    	{
    		this->brushVecs.reserve(numPoints);
    	}
    	vertexColored baseVertex;
    	this->brushVecs.resize(numPoints, baseVertex);
        int curX = this->pos.x - this->size;
        int index = 0;
        while (curX <= this->pos.x + this->size){
            int curZ = this->pos.z - this->size;
            while (curZ <= this->pos.z + this->size){
                this->brushVecs[index].vertexPos = glm::vec3((float)curX, 0.0f, (float)curZ);
    			this->brushVecs[index].vertexColor = glm::vec4(0.0f, 0.7f, 0.5f, 1.0f);
                index++;
                curZ++;
            }
            curX++;
        }
     
    	if (this->brushIndices.capacity() < numPoints)
    	{
    		this->brushIndices.reserve(numPoints);
    	}
    	this->brushIndices.resize(numPoints, 0);
        index = 0;
        while (index < numPoints){
            this->brushIndices[index] = index;
            index++;
        }
    }
     
    void brush::makeBuffers(){
        glGenBuffers(1, &(this->vboId));
        glBindBuffer(GL_ARRAY_BUFFER, this->vboId);
        glBufferData(GL_ARRAY_BUFFER, this->brushVecs.size()*sizeof(vertexColored), &this->brushVecs[0], GL_DYNAMIC_DRAW);
     
        glGenBuffers(1, &(this->iboId));
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->iboId);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->brushIndices.size()*sizeof(GLuint), &this->brushIndices[0], GL_DYNAMIC_DRAW);
    }
     
    void brush::render(){
        glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
        glUseProgram(this->progId);
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->iboId);
        glBindBuffer(GL_ARRAY_BUFFER, this->vboId);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertexColored), (GLvoid*)0); 
        glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(vertexColored), (GLvoid*)sizeof(glm::vec3));
     
        glDrawElements(GL_POINTS, this->getNumPoints(), GL_UNSIGNED_INT, (GLvoid*)0);
     
        glDisableVertexAttribArray(1);
        glDisableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glUseProgram(0);
        glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
    }
    All this renders correctly - I don't detect any problems while the program's running. However, when I close the window (I'm using Qt for windowing), my IDE (Visual Studio 2010) stays in debugging mode for a few seconds. Then a popup shows up, saying:
    Windows has triggered a breakpoint in qt_integration_test.exe.
    This may be due to a corruption of the heap, which indicates a bug in qt_integration_test.exe or any of the DLLs it has loaded.
    This may also be due to the user pressing F12 while qt_integration_test.exe has focus.
    The output window may have more diagnostic information.
    The output window contains multiple copies of the same message, all preceded by something like:
    HEAP[qt_integration_test.exe]: Invalid address specified to RtlFreeHeap( 005F0000, 03CDF180 )
    Or:
    First-chance exception at 0x76f71bee in qt_integration_test.exe: 0xC0000005: Access violation reading location 0x07440018.
    First-chance exception at 0x76f71bee in qt_integration_test.exe: 0xC0000005: Access violation reading location 0x07440018.
    HEAP[qt_integration_test.exe]: HEAP: Free Heap block 745f840 modified at 745f854 after it was freed
    I have no idea why these errors are arising. I googled heap corruption and found it could be a buffer overflow somewhere, but my buffers were fine back when I was passing a plain old vector of glm::vec3's - and I'm pretty sure I set the stride and everything right for my own custom class. And if it is the VBO or IBO overflowing, why didn't I get an error while running the program? Why only after I close it?

    I tried defining a struct instead of a class in vertexTypes.h and got the same errors. At this point I'm lost. I'm not sure what could possibly be trying to access things in memory after the window closes. Has anyone experienced something similar, or have any idea why this is happening?

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,106
    The error is probably being generated on a destructor call. This will be the first time the debugger can probably tell some correuption occured.
    The usual cause is over running a buffer - typically an array of some sort - I would look hard at the code in updateVertices

  3. #3
    Intern Contributor
    Join Date
    Jun 2012
    Posts
    71
    I scrutinized my updateVertices code more closely but couldn't see anything that would be a problem - I reserve memory and resize the vectors properly, and the loop never iterates beyond the vector's capacity.

    Then, on a hunch, I commented out the call to brush.render() in the actual OpenGL draw() loop. The brush doesn't render - naturally - but after I close the window, the IDE goes straight out of debugging mode, and no popup shows.

    From that I conclude that there's something wrong with my rendering code, or maybe the makeBuffers() code. Trouble now is, I can't see what. It all looks valid to me. Maybe something's wrong with the glEnable- and glDisableVertexAttribArray calls? The code for getNumPoints, referenced in glDrawElements, is:
    Code :
    //brush.cpp
    int brush::getNumPoints(){
        return this->brushVecs.size();
    }
    which always worked for me before I used a custom class.

  4. #4
    Intern Contributor
    Join Date
    Jun 2012
    Posts
    71
    I've run a few more tests, and I've found this:
    I get a heap corruption error on application closing even when I don't use a custom struct or class to represent a single vertex.

    The problem only seems to arise when I'm passing a color as well as a position to the shader programs. So, for instance, if I just pass vertex position data, and in the fragment shader just set the color of every fragment to some constant, I get no error. But if I pass vertex position and color data, everything renders as it should - the vertices are the appropriate colors - but I get that heap corruption error when closing the window.

    Is this thread in the right forum? I'm not sure if this is a beginner-level issue.

  5. #5
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,106
    Is this thread in the right forum? I'm not sure if this is a beginner-level issue.
    This forum is fine - your code is not "advanced" as far as OpenGL goes; also the OpenGL gurus tend to read both forums anyhow.

    This looks more like a standard coding error - just a bit difficult to spot .
    You could put some gGetlError calls in - they are always a good idea. Also post your shader in case it has something strange in there.

  6. #6
    Intern Contributor
    Join Date
    Jun 2012
    Posts
    71
    Here's the vertex shader:
    Code :
    #version 130
     
    in vec4 in_Position;
    in vec4 in_Color;
    out vec4 ex_Color;
     
    uniform mat4 MVPMatrix;
     
    void main(void)
    {
    ex_Color = in_Color;
    gl_PointSize = 8;
    gl_Position = MVPMatrix * in_Position;
    }
    and the fragment shader:
    Code :
    #version 130
     
    in vec4 ex_Color;
    out vec4 out_Color;
     
    void main(void)
    {
    out_Color = ex_Color;
    }
    Both pretty much as basic as it gets. And here's the code that actually loads the shaders:
    Code :
    //in brush.cpp:
    void brush::loadShaders(const char * vertFile, const char * fragFile){
        GLuint vsId = glCreateShader(GL_VERTEX_SHADER);
        GLuint fsId = glCreateShader(GL_FRAGMENT_SHADER);
     
        std::string vsCode;
        std::ifstream vsCodeStream(vertFile, std::ios::in);
        if (vsCodeStream.is_open())
        {
            std::string line = "";
            while(std::getline(vsCodeStream, line))
                vsCode += "\n" + line;
            vsCodeStream.close();
        }
     
        std::string fsCode;
        std::ifstream fsCodeStream(fragFile, std::ios::in);
        if (fsCodeStream.is_open())
        {
            std::string line = "";
            while(std::getline(fsCodeStream, line))
                fsCode += "\n" + line;
            fsCodeStream.close();
        }
     
        char const * vsSourcePtr = vsCode.c_str();
        glShaderSource(vsId, 1, &vsSourcePtr, NULL);
        glCompileShader(vsId);
     
        char const * fsSourcePtr = fsCode.c_str();
        glShaderSource(fsId, 1, &fsSourcePtr, NULL);
        glCompileShader(fsId);
     
        GLuint programId = glCreateProgram();
        glAttachShader(programId, vsId);
        glAttachShader(programId, fsId);
        glBindAttribLocation(programId, 0, "in_Position");
    	glBindAttribLocation(programId, 1, "in_Color");
     
        glLinkProgram(programId);
     
        glDeleteShader(vsId);
        glDeleteShader(fsId);
     
        this->progId = programId;
    }
    As I mentioned, it works fine when I'm only passing vertex position data to the shader programs. When I pass vertex color data also (even using just float arrays, not any fancy custom structs or whatever) then everything renders correctly but I get that heap corruption when I close the window.

  7. #7
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,106
    your in for position is

    in vec4 in_Position;
    but the size in the vertex structure is vec3 - this can't be good

  8. #8
    Super Moderator OpenGL Guru
    Join Date
    Feb 2000
    Location
    Montreal, Canada
    Posts
    4,264
    Quote Originally Posted by tonyo_au View Post
    your in for position is

    in vec4 in_Position;
    but the size in the vertex structure is vec3 - this can't be good
    It is good.
    The W component is set to 1 automatically.
    ------------------------------
    Sig: http://glhlib.sourceforge.net
    an open source GLU replacement library. Much more modern than GLU.
    float matrix[16], inverse_matrix[16];
    glhLoadIdentityf2(matrix);
    glhTranslatef2(matrix, 0.0, 0.0, 5.0);
    glhRotateAboutXf2(matrix, angleInRadians);
    glhScalef2(matrix, 1.0, 1.0, -1.0);
    glhQuickInvertMatrixf2(matrix, inverse_matrix);
    glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
    glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

  9. #9
    Member Regular Contributor
    Join Date
    Aug 2008
    Posts
    433
    Having OpenGL calls in a destructor:
    Code :
    brush::~brush()
    {
    	glDeleteBuffers(1, &(this->vboId));
    	glDeleteBuffers(1, &(this->iboId));
    }
    can sometimes cause problems depending on when the object is destroyed. The context could potentially have been destroyed already, there could be no context current, or a different context could be current to the one you expected. It may be better to have a brush::deleteBuffers() instead.

  10. #10
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,106
    The W component is set to 1 automatically.
    Is this true for any vec3 input?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •