Skip to main content
gamedev.net
🔒 Locked

Render Interface Problem

Started by Tactive Nov 5, 2004 at 4:33 PM 2 replies 400+ views
Original Post
Tactive
Tactive
Hello, since a few days I'm going deeper into 3D game programming. Now I'm working on a primitive OpenGL graphics api. But I got a problem with my interfaces for it. Here is the render method that crashes in the second loop:

//
// Renders the objects in this scene.
//
long Scene::renderSceneObjects()
{
    long objectsRendered = 0;
    std::list<IRenderObject*>::iterator itObject = renderObjects.begin();
    
    for (; itObject != renderObjects.end(); itObject++) {
        IRenderObject* renderObject = (*itObject);

        long verticesCount = 0;
        IComplexVertex* vertices = renderObject->getVertices(&verticesCount);
        if ((vertices) && (verticesCount > 0)) {
            glBegin(renderObject->getRenderType());
            for (long i = 0; i < verticesCount; i++) {
                glVertex3f(vertices.getX(), 
                           vertices.getY(), 
                           vertices.getZ());
            }
            glEnd();
        }
    }
    return 1;
}
The problem happens when adding the second vertex to the render process. In the debugger I see that the method calls are going weird. And this is the method that creates the vertex array:

//
// Returns an array with all vertices in this object.
//
IComplexVertex* RenderObject::getVertices(long* count)
{
    // Get number of vertices defined in this object
    const long vertexCount = getVertexCount();

    // Allocate memory
    ComplexVertex* cv = NULL;
    try {
        if ((cv = new ComplexVertex[vertexCount]) == NULL)
            throw std::bad_alloc();
    }
    catch (...) {
        //! @TODO Add error to logfile !!
        return NULL;
    }

    // Iterate vertex positions
    long index = 0;
    list<IComplexVertex*>::iterator it;

    for (it = vertices.begin(); it != vertices.end(); it++) {
        IComplexVertex* cvertex = (*it);
        cv[index++].setPos(cvertex);
    }

    // Update count variable to match vertices count
    if (count) {
        (*count) = vertexCount;
    }

    return cv;    
}
Can anyone tell me how I can fix this ?? I've tried several things, but nothing helps.
Zakwayda
Zakwayda
From quickly looking at your code it looks like you're creating a new vertex array with 'new' each frame and passing it back to renderSceneObject()? And never deleting it?

I don't want to give any annoyingly obvious advice without being sure what you're doing (you could be doing something complicated or subtle that I'm not grasping), so I won't comment on the code at this point. But perhaps you could clarify a little what you're doing.

Also, I'm pretty sure new throws bad_alloc by default, so I don't think you need the conditional. Could be wrong about that, though.
Tactive
Tactive
Hi,

the main problem at this point is that all pointers get's weird. As I can trust the debugger (VC6), there are some things that makes me confused.

The RenderObject is related to a scene (a scene can have several objects), and it has an method to add vertices.
To add vertices I must create an ComplexVertex object. This object consists of two other objects (Vertex & VertexColour).

So the interface of the ComplexVertex looks like this:

class IComplexVertex : public IVertex,                       public IVertexColor{public:    //! Changes the position of the vertex.    virtual void setPos(IComplexVertex* vertex) = 0;};


The interface IVertex has methods to get the X/Y/Z positions which I use in ComplexVertex::setPos():

//// Changes the position of the vertex.//void ComplexVertex::setPos(IComplexVertex* vertex){    float pos[3];    vertex->getPos(&pos[0], &pos[1], &pos[2]);    xPos = pos[0];    yPos = pos[1];    zPos = pos[2];}


That works all fine. In the getVertices() method I get the right values back from the list. I've added a few lines after my iteration to check the values:

    for (int x = 0; x < vertexCount; x++) {        IComplexVertex* cvp = &cv[x];        char szBuffer[4096];        memset(szBuffer, 0, 4096);        sprintf(szBuffer, "Vertex Pass %d\nX: %f\nY: %f\nZ: %f\n", x, cvp->getX(), cvp->getY(), cvp->getZ());        ::MessageBox(NULL, szBuffer, "TES", MB_OK);    }


They're all correct. Now after passing the array to renderSceneObjects() it becomes it weirdness.

The pointer returned from getVertices() is pointing to the last (??) entry in my array ??
Tactive
Tactive
To get more acknowledge about my problematic I wrote a tiny test project with simple code:

#include "stdafx.h"#include <stdio.h>#include <iostream>using namespace std;/*    Interface for TestClass*/class ITestClass{public:    virtual void setValue(int value) = 0;    virtual int getValue() = 0;};/*    TestClass derived from ITestClass*/class TestClass : public ITestClass{public:    TestClass()      {         valueA = 0;     }    ~TestClass()     {     }    void setValue(int value)    {        valueA = value;    }    int getValue()    {           return valueA;    }private:    int valueA;};/*    Method that creates objects    and fills them with values.*/ITestClass* getObjects(int* count){    int nums=3;        // Create class objects    TestClass* testClass = new TestClass[nums];    // Fill classes with values    for (int x = 0; x < nums; x++) {        cout << "Setting value for class: " << (x + 1) << endl;        testClass[x].setValue((x + 1) * 1);    }    if (count)        (*count) = nums;    return testClass;}/*    Main method (cool, eh ? :)*/int main(int argc, char* argv[]){    int nums = 0;    ITestClass* testClass = getObjects(&nums);        // Display inserted values    for (int i = 0; i < nums; i++) {        cout << i+1 << ". Value: " << testClass.getValue() << endl;    }	return 0;}


That's the same situation like in my other code but even more simplified.

It seems for me that the pointer to the Interface-Array gets corrupt. So I would like to know how it is possible to create and return a Interface-Array, or is this just impossible ?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.