ошибка C2664 и C2597 в OpenGL и DevIL в C ++ - PullRequest
0 голосов
/ 19 апреля 2011

Полагаю, это проблема, состоящая из двух частей, поэтому я не смог найти более подходящее название для поста.

Я загружаю изображение, используя 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'

Я пытался объявить texture разными способами,

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

как в моем файле .cpp, так и в моем файле .h, но ни один из них не работает.Если я попытаюсь объявить его в файле .h как static Gluint Main::texture, я получу ошибку LNK2019: unresolved external symbol__imp_ для каждой функции DevIL (дайте мне знать, если вы хотите, чтобы я также публиковал их).

Ядовольно это что-то в коде, в отличие от моих зависимостей или мои файлы .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);
}

Ответы [ 2 ]

3 голосов
/ 19 апреля 2011

Ваша ошибка появляется из-за того, что у вас нет экземпляра (объекта) типа Main, но, конечно, вам нужно Main, прежде чем вы сможете использовать что-либо из него.

Теперь у вас есть нескольковарианты, чтобы исправить это - и кажется, что вы уже пробовали несколько.Вы можете сделать текстуру переменной глобальной, либо сделав ее static в области видимости класса, либо используя «обычную» глобальную область видимости пространства имен.

Для первого случая вы должны объявить переменная как static GLuint texture; в вашем классе в вашем .h файле и вы определяете как GLuint Main::texture = 0; в вашем файле .cpp.Кажется, вы не определили переменную, когда пытались это сделать.Во втором случае вы объявляете его как extern GLuint texture; в вашем .h вне вашего класса и определяете его как GLuint texture вне какой-либо функции.

Оба решения - не очень хороший стиль, поэтомубыло бы лучше, если бы вы просто добавили GLuint texture в свой класс Main, затем создали экземпляр 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.

0 голосов
/ 19 апреля 2011

ошибка 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;
}
...