Ошибка C2664 и C2597 в OpenGL и DevIL в C++
Я думаю, что это проблема из двух частей, поэтому я не смог найти более подходящее название для поста.
Я загружаю изображение, используя 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 ответа
Ваша ошибка появляется, потому что у вас нет экземпляра (объекта) типа 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.
ошибка 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;
}