OpenGL vbo和指针的问题

Trouble with OpenGL VBOs and pointers

本文关键字:问题 指针 vbo OpenGL      更新时间:2023-10-16

我正在启动OpenGL,而不是手动绑定缓冲区,我试图使一个函数为我做这件事,但我得到这2个错误。

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 <glGLU.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 <glGL.h>
#include <glGLEXT.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,它们确实返回了。

您误用了inline关键字。将它从函数定义和原型中删除,代码应该可以编译。例如:

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

BufferUtilities.hBufferUtilities.cpp

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

至于运行时错误,似乎你传递给函数的指针之一是空的。在使用指针参数时,为它们添加一些检查是一种很好的做法。例如:

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

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

我看到了至少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*, => typeof(array[0]) == GLfloat, => size为sizeof(GLfloat*) / sizeof(GLfloat),在32位x86操作系统上为1,在64位操作系统上为2 -在这两种情况下都是不正确的。