OpenGL VBO和指针的问题

时间:2014-07-02 02:48:14

标签: c++ pointers opengl

我开始使用OpenGL而不是手动绑定缓冲区,我尝试为我做一个函数,但是我得到了这两个错误。

error LNK2019: unresolved external symbol "void __cdecl createArrayBuffer(float *,unsigned int *,unsigned int)" (?createArrayBuffer@@YAXPAMPAII@Z) referenced in function "public: bool __thiscall Example::init(void)" (?init@Example@@QAE_NXZ)
error LNK2019: unresolved external symbol "void __cdecl bindAndPoint(unsigned int *,int)" (?bindAndPoint@@YAXPAIH@Z) referenced in function "public: void __thiscall Example::render(void)" (?render@Example@@QAEXXZ)

我认为这与指针有点让我感到困惑。这是代码。

BufferUtilities.cpp:

#define WIN32_LEAN_AND_MEAN
#define WIN32_EXTRA_LEAN

#include <windows.h>

#include "BufferUtilities.h"
#include <iostream>
#include <gl\GLU.h>

#define BUFFER_OFFSET(i) ((char *)NULL+(i))

bool start()
{
    glGenBuffers = (PFNGLGENBUFFERSARBPROC)wglGetProcAddress("glGenBuffers");
    glBindBuffer = (PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer");
    glBufferData = (PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData");

    if (!glGenBuffers || !glBindBuffer || !glBufferData)
    {
        std::cerr << "Vertex buffer objects are not supported by your graphics card." << std::endl;
        return false;
    }

    return true;
}

inline void createArrayBuffer(GLfloat *array, GLuint *buffer, GLenum usage)
{
    glGenBuffers(1, buffer);
    glBindBuffer(GL_ARRAY_BUFFER, *buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (sizeof(array)/sizeof(array[0])), &array[0], usage);
}

inline void bindAndPoint(GLuint *buffer, int size)
{
    glBindBuffer(GL_ARRAY_BUFFER, *buffer);
    glColorPointer(size, GL_FLOAT, 0, BUFFER_OFFSET(0));
}

BufferUtilities.h

#pragma once

#include <gl\GL.h>
#include <gl\GLEXT.h>

static PFNGLGENBUFFERSARBPROC glGenBuffers = NULL;
static PFNGLBINDBUFFERPROC glBindBuffer = NULL;
static PFNGLBUFFERDATAPROC glBufferData = NULL;

bool start();

inline void createArrayBuffer(GLfloat *array, GLuint *buffer, GLenum usage);

inline void bindAndPoint(GLuint *buffer, int size);

使用上述功能的两个功能

void Example::render()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    bindAndPoint(&colorBuffer, 3);

    bindAndPoint(&vertexBuffer, 3);

    //Translates the zPosition before rendering
    glTranslatef(0.0f, 0.0f, zPosition);

    //Draws the square as a triangle strip
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
bool Example::init()
{
    if (!start())
    {
        return false;
    }

    glEnable(GL_DEPTH_TEST);
    glClearColor(0.5f, 0.5f, 0.5f, 0.5f);

    GLfloat verticies[] = {
        -2.0f, -2.0f, -2.0f,
        2.0f, -2.0f, -2.0f,
        -2.0f, -2.0f, 2.0f,
        2.0f, -2.0f, 2.0f,
    };

    GLfloat colors[] = {
        1.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 1.0f,
        1.0f, 1.0f, 0.0f,
    };

    createArrayBuffer(verticies, &vertexBuffer, GL_STATIC_DRAW);
    createArrayBuffer(colors, &colorBuffer, GL_STATIC_DRAW);

    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);

    //Return success
    return true;
}

从两个函数中删除内联都可以编译,但在运行时glDrawArrays(GL_TRIANGLE_STRIP,0,4)会出现一个新错误。它是

Unhandled exception at 0x697655D5 (nvoglv32.dll) in Chapter 2.exe: 0xC0000005: Access violation reading location 0x00000000.

我检查了所有指针是否为NULL,并且它们不是。我还检查了init()和start()是否返回true,并且确实如此。

2 个答案:

答案 0 :(得分:2)

您滥用inline关键字。从函数定义和原型中删除它,代码应该编译。 E.g:

void createArrayBuffer(GLfloat *array, GLuint *buffer, GLenum usage);
void bindAndPoint(GLuint *buffer, int size);

BufferUtilities.hBufferUtilities.cpp

当您将函数声明为inline时,必须将声明和定义放在同一个文件中。通常是头文件。通过阅读thisthis链接,进一步了解该概念。

至于运行时错误,看起来你传递给函数的指针之一是null。 在使用指针参数时,最好为指针参数添加一些检查。 E.g:

#include <assert.h>

void createArrayBuffer(GLfloat *array, GLuint *buffer, GLenum usage)
{
    assert(array != NULL);
    assert(buffer != NULL);
    ...
}

如果其中一个指针为空,assert将帮助您通过暂停程序执行并调用调试器来查明错误。

答案 1 :(得分:2)

我发现至少有3个问题:

    显然是
  1. inline。已经陈述和解释。下一步。
  2. 0xC0000005很可能意味着您正在使用NULL地址调用函数。检查您的startEngine::init函数是否返回true
  3. glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (sizeof(array)/sizeof(array[0])), &array[0], usage);又是什么尺寸?.. typeof(array) == GLfloat*,=&gt; typeof(array[0]) == GLfloat,=&gt;大小为sizeof(GLfloat*) / sizeof(GLfloat),在32位x86操作系统上为1,在64位上为2 - 在这两种情况下都不正确。