OpenGL 中的错误 C2664 和 C2597 以及 C++ 中的 DevIL;

发布于 2024-11-02 11:03:33 字数 4555 浏览 1 评论 0原文

我想这是一个由两部分组成的问题,这就是为什么我找不到更合适的帖子标题。

我正在使用 DevIL 加载图像,然后将其转换为熟悉的格式。这是我遇到问题的代码部分:

//Copy to OpenGL texture
if(!ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE))
{
    throw runtime_error(std::string("Unable to convert image") +filename +std::string(" to display friendly format"));
}
glGenTextures(1, &Main::texture);
glBindTexture(GL_TEXTURE_2D, Main::texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Use nice (linear) scaling 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Use nice (linear) scaling 
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), width, height, 0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());

现在,对于 glGenTextures() 方法,我得到了

error C2664: 'glGenTextures' : cannot convert parameter 2 from 'GLuint Main::* ' to 'GLuint *'

,对于 glBindTexure()

error C2597: illegal reference to non-static member 'Main::texture'

我尝试声明 在我的 .cpp 文件和 .h 文件中,我以多种不同的方式使用了 .texture

static Gluint Main::texture;
static Gluint texture;
Gluint texture;
Gluint Main::texture;

,但它们都不起作用。如果我尝试在 .h 文件中将其声明为 static Gluint Main::texture,我会收到每个 DevIL 函数的 LNK2019: unresolved external symbol__imp_ 错误(让我知道)如果你想让我也发布它们)。

我很高兴,这是代码中的某些内容,而不是我的依赖项或我的 .lib 或 .dll 文件不在正确的位置。那么我做错了什么?

编辑:这是我到目前为止的代码

头文件

class Main
{
private: 
    static GLuint texture;
public:
    static void Init(int argc, char ** argv);
    static void DisplayScene();
    static void Idle();
static void Resize(int w, int h);
};

void main(int argc, char ** argv)
{
    Main::Init(argc, argv);
}

.cpp 文件

#include <IL\il.h>
#include <IL\ilu.h>
#include <IL\ilut.h>

GLuint Main::texture = 0;
double xRes, yRes;

void Main::Init(int argc, char ** argv) //Initialisation method
{
    ////Window Management
    glutInit( &argc, argv); //Initialises GLUT and processes any command line arguements.
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); //Specifies whether to use an RGBA or colour-index colour model. Can also specify whether to use a single or a double buffered window.
    glutInitWindowSize(1024, 768);
    glutCreateWindow("Adventure"); //Creates a window with an OpenGL context. It returns a unique identifier for the new window. Until glutMainLoop() is called, the window is not yet displayed.
    /// Set up OpenGL for 2d rendering 
    gluOrtho2D(0.0, xRes, yRes, 0.0); //1.0 0.0
    /// Enable textures 
    glEnable(GL_TEXTURE_2D); 
    /// Enable blending 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    ilInit(); //Initialise DevIL.
    glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); //Specifies the coordinate system OpenGL assumes as it draws the final image and how the image is mapped to the screen.

    ///The Display Callback
    glutDisplayFunc(Main::DisplayScene); //Defines all the routines needed to draw the scene.
    glutIdleFunc(Main::Idle);

    ///Running The Program
    glutMainLoop(); //All windows that have been created are now shown, and rendering to those windows is now effective.
}

void Main::Idle()
{
    glutPostRedisplay();
}

void Main::DisplayScene()
{
///Declarations
int x = 0;
int y = 0;
//float alpha;
const char* filename = "back.bmp";
ILboolean ilLoadImage(const char *filename);
//GLuint texture;

///Generate DevIL image and make it current context
ILuint image;
ilGenImages(1, &image);
ilBindImage(image);

///Load the image
if (!ilLoadImage(filename))
{
    throw runtime_error(std::string("Unable to load image") +filename);
}

int width = ilGetInteger(IL_IMAGE_WIDTH);
int height = ilGetInteger(IL_IMAGE_HEIGHT);

///Copy to OpenGL texture
if(!ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE))
{
    throw runtime_error(std::string("Unable to convert image") +filename +std::string(" to display friendly format"));
}
glGenTextures(1, &Main::texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Use nice (linear) scaling 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Use nice (linear) scaling 
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), width, height, 0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData()); 

/// Free DevIL image since we have it in a texture now 
ilDeleteImages(1, &image);
}

I guess this is a two part problem, which is why I couldn't find a more suitable title for the post.

I am loading an image using DevIL and then converting it to a familiar format. Here is the part of my code I am having troubles with:

//Copy to OpenGL texture
if(!ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE))
{
    throw runtime_error(std::string("Unable to convert image") +filename +std::string(" to display friendly format"));
}
glGenTextures(1, &Main::texture);
glBindTexture(GL_TEXTURE_2D, Main::texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Use nice (linear) scaling 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Use nice (linear) scaling 
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), width, height, 0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData());

Now, for the glGenTextures() method, I get

error C2664: 'glGenTextures' : cannot convert parameter 2 from 'GLuint Main::* ' to 'GLuint *'

and for glBindTexure()

error C2597: illegal reference to non-static member 'Main::texture'

I have tried declaring texture in many different ways,

static Gluint Main::texture;
static Gluint texture;
Gluint texture;
Gluint Main::texture;

both in my .cpp file and my .h file, but none of it works. If I try to declare it in the .h file as static Gluint Main::texture, I get the LNK2019: unresolved external symbol__imp_ error for every DevIL function (let me know if you want me to post them as well).

I am pretty it is something in the code as opposed to my dependencies or my .lib or .dll files not being in the right place. So what am I doing wrong?

EDIT: This is my code so far

The header file

class Main
{
private: 
    static GLuint texture;
public:
    static void Init(int argc, char ** argv);
    static void DisplayScene();
    static void Idle();
static void Resize(int w, int h);
};

void main(int argc, char ** argv)
{
    Main::Init(argc, argv);
}

The .cpp file

#include <IL\il.h>
#include <IL\ilu.h>
#include <IL\ilut.h>

GLuint Main::texture = 0;
double xRes, yRes;

void Main::Init(int argc, char ** argv) //Initialisation method
{
    ////Window Management
    glutInit( &argc, argv); //Initialises GLUT and processes any command line arguements.
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); //Specifies whether to use an RGBA or colour-index colour model. Can also specify whether to use a single or a double buffered window.
    glutInitWindowSize(1024, 768);
    glutCreateWindow("Adventure"); //Creates a window with an OpenGL context. It returns a unique identifier for the new window. Until glutMainLoop() is called, the window is not yet displayed.
    /// Set up OpenGL for 2d rendering 
    gluOrtho2D(0.0, xRes, yRes, 0.0); //1.0 0.0
    /// Enable textures 
    glEnable(GL_TEXTURE_2D); 
    /// Enable blending 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    ilInit(); //Initialise DevIL.
    glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); //Specifies the coordinate system OpenGL assumes as it draws the final image and how the image is mapped to the screen.

    ///The Display Callback
    glutDisplayFunc(Main::DisplayScene); //Defines all the routines needed to draw the scene.
    glutIdleFunc(Main::Idle);

    ///Running The Program
    glutMainLoop(); //All windows that have been created are now shown, and rendering to those windows is now effective.
}

void Main::Idle()
{
    glutPostRedisplay();
}

void Main::DisplayScene()
{
///Declarations
int x = 0;
int y = 0;
//float alpha;
const char* filename = "back.bmp";
ILboolean ilLoadImage(const char *filename);
//GLuint texture;

///Generate DevIL image and make it current context
ILuint image;
ilGenImages(1, &image);
ilBindImage(image);

///Load the image
if (!ilLoadImage(filename))
{
    throw runtime_error(std::string("Unable to load image") +filename);
}

int width = ilGetInteger(IL_IMAGE_WIDTH);
int height = ilGetInteger(IL_IMAGE_HEIGHT);

///Copy to OpenGL texture
if(!ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE))
{
    throw runtime_error(std::string("Unable to convert image") +filename +std::string(" to display friendly format"));
}
glGenTextures(1, &Main::texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Use nice (linear) scaling 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Use nice (linear) scaling 
glTexImage2D(GL_TEXTURE_2D, 0, ilGetInteger(IL_IMAGE_BPP), width, height, 0, ilGetInteger(IL_IMAGE_FORMAT), GL_UNSIGNED_BYTE, ilGetData()); 

/// Free DevIL image since we have it in a texture now 
ilDeleteImages(1, &image);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

新一帅帅 2024-11-09 11:03:33

出现错误是因为您没有 Main 类型的实例(对象),但当然您需要一个 Main 才能使用其中的任何内容。

现在你有几个选项来解决这个问题 - 而且看起来你已经尝试了一些。您可以将纹理变量设为全局变量,方法是在类范围内将其设置为静态,或者在命名空间范围内使用“普通”全局变量。

对于第一种情况,您需要在 .h 文件的类中声明变量为static GLuinttexture;并且在 .cpp 文件中将其定义为 GLuint Main::texture = 0;。当你尝试这个时,你似乎没有定义变量。
对于第二种情况,您可以在类外部的 .h 中将其声明为 extern GLuinttexture; ,并将其定义为任何函数外部的 GLuinttexture

这两种解决方案都不是很好的风格,因此如果您只是向 Main 类添加一个 GLuint 纹理,然后创建一个 Main 实例并使用其成员变量 - 最好来自 Main 中的函数,那就更好了,因此您可以使用this

理想情况下,您应该有一个像这样的 Texture 类:

class Texture
{
  Texture() {glGenTextures(1, &id);}
  ~Texture() {glDeleteTextures(1, &id);}
  void Bind() {glBindTexture(GL_TEXTURE_2D, id);}
private:
  GLuint id;  
};

void someFunction()
{
  Texture myTexture;
  myTexture.Bind();
  // do stuff with the texture - like glTexParameteri, glTexImage
}

将更多功能转移到 Texture 类中的奖励点,但这需要更多地处理 OpenGL 愚蠢的绑定机制。

Your error appear because you don't have an instance (object) of type Main, but of course you need a Main before you can use anything from it.

Now you have several options to fix this - and it appears like you already tried a few. You can make the texture variable global, either by making it static at class-scope, or by using an "ordinary" global at namespace scope.

For the first case, you'd declare the variable as static GLuint texture; in your class in your .h file and you define it as GLuint Main::texture = 0; in your .cpp file. It seems you didn't define the variable when you tried this.
For the second case, you declare it as extern GLuint texture; in your .h outside of your class and define it as GLuint texture outside of any function.

Both solutions aren't very good style, so it would be better if you just added a GLuint texture to your Main class, then create a Main instance and used its member variable - preferably from a function within Main, so you can use this.

Ideally, you'd have something like a Texture class like this:

class Texture
{
  Texture() {glGenTextures(1, &id);}
  ~Texture() {glDeleteTextures(1, &id);}
  void Bind() {glBindTexture(GL_TEXTURE_2D, id);}
private:
  GLuint id;  
};

void someFunction()
{
  Texture myTexture;
  myTexture.Bind();
  // do stuff with the texture - like glTexParameteri, glTexImage
}

bonus points for moving more functionality into the Texture class, but that requires dealing more with OpenGLs stupid bind mechanic.

等风来 2024-11-09 11:03:33

错误 C2664:“glGenTextures”:无法将参数 2 从“GLuint Main::*”转换为“GLuint *”

&Main::texture 是我们所说的成员字段指针,而不是指针。您需要指向纹理的实际实例,因此

 Main* mymain; /* = new Main(...); somewehere in the code */
 glGenTextures(1, &mymain->texture);

额外/奖励

万一您实际上想要使用成员指针,这里是一个示例(键盘链接):

#include <stdio.h>

struct A
{
    int p,q,r;

    int getp() { return p; }
};

int main()
{
    int x;
    A a[] = {
        { 1,2,3 },
        { 4,5,6 },
        { 7,8,9 }
    };

    // ---- pointer to member functions

    int A::* member;

    member = &A::p;
    printf("member p: %i\n", a[2].*member);
    member = &A::q;
    printf("member q: %i\n", a[2].*member);
    member = &A::r;
    printf("member r: %i\n", a[2].*member);

    // ---- pointer to member functions

    int (A::*getter)();

    getter = &A::getp;

    x = (a[1].*getter)();
    printf("getter: %i\n", x);

    x = (a[2].*getter)();
    printf("getter: %i\n", x);

    return 0;
}

error C2664: 'glGenTextures' : cannot convert parameter 2 from 'GLuint Main::* ' to 'GLuint *'

&Main::texture is what we call a member field pointer, not a pointer. You'd need to point to an actual instance of a texture, so

 Main* mymain; /* = new Main(...); somewehere in the code */
 glGenTextures(1, &mymain->texture);

Extra / bonus

In the unlikely event that you actully wanted to use a member pointer, here is an example (codepad link):

#include <stdio.h>

struct A
{
    int p,q,r;

    int getp() { return p; }
};

int main()
{
    int x;
    A a[] = {
        { 1,2,3 },
        { 4,5,6 },
        { 7,8,9 }
    };

    // ---- pointer to member functions

    int A::* member;

    member = &A::p;
    printf("member p: %i\n", a[2].*member);
    member = &A::q;
    printf("member q: %i\n", a[2].*member);
    member = &A::r;
    printf("member r: %i\n", a[2].*member);

    // ---- pointer to member functions

    int (A::*getter)();

    getter = &A::getp;

    x = (a[1].*getter)();
    printf("getter: %i\n", x);

    x = (a[2].*getter)();
    printf("getter: %i\n", x);

    return 0;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文