С# SFML OpenGl Проблема с несколькими текстурами

Редактировать: Хорошо, этот код по-прежнему не позволяет мне использовать две разные текстуры в программе. Он действует так, как будто он должен работать, но когда я говорю ему использовать первую текстуру, она такая же, как и вторая текстура, которая является последней загруженной текстурой.

        private int[] iTextures = new int[3];

        public void main()
        {
            Initialize();
            LoadContent();

            float Time = 0.0F;

            // Start game loop
            while (App.IsOpened())
            {
                // Process events
                App.DispatchEvents();

                // Clear the window
                App.Clear();

                App.Draw(Background);

                Gl.glClear(Gl.GL_DEPTH_BUFFER_BIT);

                // Transformations
                Time += App.GetFrameTime();
                Gl.glMatrixMode(Gl.GL_MODELVIEW);
                Gl.glLoadIdentity();
                Gl.glTranslatef(0.0F, 0.0F, -200.0F);


                Gl.glPushMatrix();

                Gl.glScalef(10.0f, 50.0f, 10.0f);
                DrawCube(50.0f, 50.0f, 50.0f, 0);

                Gl.glPopMatrix();

                //Gl.glRotatef(Time * 50, 1.0F, 0.0F, 0.0F);
                //Gl.glRotatef(Time * 30, 0.0F, 1.0F, 0.0F);
                //Gl.glRotatef(Time * 90, 0.0F, 0.0F, 1.0F);


                /*Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, -50.0F);
                Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, -50.0F);
                Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, -50.0F);
                Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, -50.0F);

                Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, 50.0F);
                Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, 50.0F);
                Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, 50.0F);
                Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, 50.0F);

                Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, -50.0F);
                Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, -50.0F);
                Gl.glTexCoord2f(1, 1); Gl.glVertex3f(-50.0F, 50.0F, 50.0F);
                Gl.glTexCoord2f(1, 0); Gl.glVertex3f(-50.0F, -50.0F, 50.0F);

                Gl.glTexCoord2f(0, 0); Gl.glVertex3f(50.0F, -50.0F, -50.0F);
                Gl.glTexCoord2f(0, 1); Gl.glVertex3f(50.0F, 50.0F, -50.0F);
                Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, 50.0F);
                Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, 50.0F);

                Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, -50.0F, 50.0F);
                Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, -50.0F, -50.0F);
                Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, -50.0F, -50.0F);
                Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, -50.0F, 50.0F);

                Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 50.0F, 50.0F);
                Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, 50.0F, -50.0F);
                Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, 50.0F, -50.0F);
                Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 50.0F, 50.0F);


                Gl.glVertex3f(50.0f, 50.0f, 50.0f);
                Gl.glVertex3f(50.0f, 0.0f, 50.0f);
                Gl.glVertex3f(0.0f, 0.0f, 50.0f);
                Gl.glVertex3f(0.0f, 50.0f, 50.0f);

                Gl.glTexCoord2f(0, 1); Gl.glVertex3f(-50.0F, 10.0F, 50.0F);
                Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-50.0F, 10.0F, -50.0F);
                Gl.glTexCoord2f(1, 0); Gl.glVertex3f(50.0F, 10.0F, -50.0F);
                Gl.glTexCoord2f(1, 1); Gl.glVertex3f(50.0F, 10.0F, 50.0F);

                Gl.glEnd();*/



                Draw();

                // Finally, display the rendered frame on screen
                App.Display();

            }
            // Don't forget to destroy our texture
            int tex = 0;
            Gl.glDeleteTextures(1, ref tex);
        }

        public void Initialize()
        {
            // Create main window

            App.PreserveOpenGLStates(true);

            // Setup event handlers
            App.Closed += new EventHandler(OnClosed);
            App.KeyPressed += new EventHandler<KeyEventArgs>(OnKeyPressed);
            App.Resized += new EventHandler<SizeEventArgs>(OnResized);
        }

        private void LoadContent()
        {
            BackgroundImage = new Image("background.jpg");
            Background = new Sprite(BackgroundImage);

            Text = new String2D("This is a cube");
            Text.Position = new Vector2(0, 0);
            Text.Color = Color.Black;

            // Enable Z-buffer read and write
            Gl.glEnable(Gl.GL_DEPTH_TEST);
            Gl.glDepthMask(Gl.GL_TRUE);
            Gl.glClearDepth(1.0F);

            // Setup a perspective projection

            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glLoadIdentity();
            Glu.gluPerspective(90.0F, 1.0F, 1.0F, 500.0F); // I assume this is setting up the camera

            LoadTexture(new Image("texture.jpg"), 0);

            LoadTexture(new Image("Otexture.jpg"), 1);


        }

        private void Draw()
        {
            App.Draw(Text);
        }

        private void LoadTexture(Image Texture, int texNum)
        {

            using (Image TempImage = Texture)
            {

                Gl.glGenTextures(1, out iTextures[texNum]); // Texture name, which is a number

                Gl.glBindTexture(Gl.GL_TEXTURE_2D, iTextures[texNum]); // Start using the texture


                Console.WriteLine(texNum + "");
                // Texture options and filters and stuff
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR_MIPMAP_LINEAR);

                Glu.gluBuild2DMipmaps(Gl.GL_TEXTURE_2D, Gl.GL_RGBA, (int)TempImage.Width, (int)TempImage.Height, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, TempImage.Pixels);
                //Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, (int)TempImage.Width, (int)TempImage.Height, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, TempImage.Pixels);

            }
            Gl.glEnable(Gl.GL_TEXTURE_2D);
        }
        private void UseTexture(int iTexture)
        {


            // Bind our texture for use
            //Gl.glEnable(Gl.GL_TEXTURE_2D); // Start using the 2D texture
            Gl.glBindTexture(Gl.GL_TEXTURE_2D, iTexture); // Bind our texture for current use
            Gl.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); // Set color to..white, I think.
        }



        void DrawCube(float xPos, float yPos, float zPos, int texture)
        {

            Gl.glPushMatrix();

            //UseTexture(1);
            Gl.glBegin(Gl.GL_QUADS);
            UseTexture(iTextures[0]);
            //Gl.glEnable(Gl.GL_TEXTURE_2D);



            /*      This is the top face*/
            Gl.glVertex3f(0.0f, 0.0f, 0.0f);
            Gl.glVertex3f(0.0f, 0.0f, -1.0f);
            Gl.glVertex3f(-1.0f, 0.0f, -1.0f);
            Gl.glVertex3f(-1.0f, 0.0f, 0.0f);

            /*      This is the front face*/
            Gl.glTexCoord2f(0, 1); Gl.glVertex3f(0.0f, 0.0f, 0.0f);
            Gl.glTexCoord2f(0, 0); Gl.glVertex3f(-1.0f, 0.0f, 0.0f);
            Gl.glTexCoord2f(1, 0); Gl.glVertex3f(-1.0f, -1.0f, 0.0f);
            Gl.glTexCoord2f(1, 1); Gl.glVertex3f(0.0f, -1.0f, 0.0f);

            /*      This is the right face*/
            Gl.glVertex3f(0.0f, 0.0f, 0.0f);
            Gl.glVertex3f(0.0f, -1.0f, 0.0f);
            Gl.glVertex3f(0.0f, -1.0f, -1.0f);
            Gl.glVertex3f(0.0f, 0.0f, -1.0f);

            /*      This is the left face*/
            Gl.glVertex3f(-1.0f, 0.0f, 0.0f);
            Gl.glVertex3f(-1.0f, 0.0f, -1.0f);
            Gl.glVertex3f(-1.0f, -1.0f, -1.0f);
            Gl.glVertex3f(-1.0f, -1.0f, 0.0f);

            /*      This is the bottom face*/
            Gl.glVertex3f(0.0f, 0.0f, 0.0f);
            Gl.glVertex3f(0.0f, -1.0f, -1.0f);
            Gl.glVertex3f(-1.0f, -1.0f, -1.0f);
            Gl.glVertex3f(-1.0f, -1.0f, 0.0f);

            /*      This is the back face*/
            Gl.glVertex3f(0.0f, 0.0f, 0.0f);
            Gl.glVertex3f(-1.0f, 0.0f, -1.0f);
            Gl.glVertex3f(-1.0f, -1.0f, -1.0f);
            Gl.glVertex3f(0.0f, -1.0f, -1.0f);

            Gl.glEnd();
            Gl.glPopMatrix();
        }

Любая помощь будет потрясающей.


person Elec0    schedule 22.07.2011    source источник


Ответы (1)


Вы не говорите о мультитекстурировании; вы говорите об использовании нескольких текстур в одном приложении.

Ну, я вижу несколько проблем.

Gl.glGenTextures(2, out iTexture); // Texture name, which is a number

Я признаю, что я не на 100% знаком с синтаксисом C#, поэтому я предполагаю, что out работает скорее как передача указателя в C/C++. Итак, вы ожидаете, что glGenTextures запишет номер объекта текстуры в iTexture.

Здесь есть две проблемы. Во-первых, iTexture — это одно целое число. Но вы сказали glGenTextures, что в этом вызове функции вы создаете две текстуры, а не одну. Это потребует передачи массива целых чисел для записи в glGenTextures. Так ты рискуешь уничтожить... стек? Я понятия не имею, как вы упорядочиваете эти вызовы C++, но как бы вы это ни делали, glGenTextures, скорее всего, записывает в случайную память. Вам повезло, что вы не попали в аварию.

Предполагается, что каждый вызов LoadTexture создает один объект текстуры OpenGL. Поэтому не следует пытаться создать два из одного вызова LoadTexture.

Другая проблема заключается в том, что iTexture не возвращается из вашей функции LoadTexture. Вы его нигде не храните. Действительно, когда вы вызываете LoadTexture, вы даже не даете ему выходную переменную; вы даете ему числовой литерал. Опять же, я не эксперт по C#, но я почти уверен, что вам понадобится специальный синтаксис для использования аргумента в качестве вывода функции, особенно для базового типа, такого как int.

Ваша функция LoadTexture должна возвращать имена текстур OpenGL (или хранить их где-то), а соответствующие вызовы UseTexture должны получать от них эти имена.


Проблемы с новым кодом:

// Don't forget to destroy our texture
int tex = 0;
Gl.glDeleteTextures(1, ref tex);

Вы не можете удалить текстуру 0. Обычно люди не используют текстуру 0 для хранения реальных текстур; обычно это рассматривается как «текстура, которой не существует», например NULL.

Что касается вашего фактического кода рисования:

Gl.glBegin(Gl.GL_QUADS);
UseTexture(iTextures[0]);

Вы не можете вызывать glBindTexture (или большинство функций OpenGL) между вызовами glBegin/glEnd. UseTexture следует вызывать перед началом квадроцикла. Кроме того, UseTexture должен включать GL_TEXTURE_2D. Я знаю, что вы используете его где-то еще, но лучше размещать команды там, где они действительно важны. И вам нужно отключить GL_TEXTURE_2D, если вы хотите сделать нетекстурированный рендеринг.

Кроме того, что вы ожидаете, когда вы даете только координаты одной четырехугольной текстуры? Как вы ожидаете, как будут выглядеть другие квадроциклы? Потому что, если вы думаете, что эти квадроциклы будут без текстур, вы ошибаетесь.

person Nicol Bolas    schedule 22.07.2011
comment
А, это имеет смысл. Честно говоря, я думал, что OpenGl сохраняет имена при их создании, очевидно, я ошибался. Я попробую то, что вы предложили, большое спасибо. - person Elec0; 22.07.2011
comment
@ Elec0: Конечно, OpenGL сохранил имена текстур - для внутреннего управления. Но в него не встроен какой-то хрустальный шар, который не может читать ваши мысли, чтобы знать, какую текстуру вы хотели бы использовать. Вы должны указать OpenGL, какую текстуру использовать, а имя текстуры является дескриптором для этого. - person datenwolf; 22.07.2011
comment
@Nicol Bolas: Предполагая работу OpenGL-1.x, если бы Elec0 пропустил вызов glGenTextures, это действительно сработало бы, поскольку OpenGL-1 позволяет использовать неявные имена объектов, не сгенерированные явно (затем он автоматически генерирует новый объект текстуры с запрошенное имя). Имя 0 зарезервировано, поэтому параметр LoadTexture iTexture будет начинаться с 1. - person datenwolf; 22.07.2011
comment
Хорошо спасибо. Я обновил свой пост своим новым кодом, который все еще не работает. - person Elec0; 22.07.2011
comment
@ Elec0: определить не работает. Измените свой вопрос, чтобы объяснить проблему, с которой вы столкнулись сейчас. - person Nicol Bolas; 22.07.2011
comment
@Nicol Bolas: Большое спасибо, все сработало именно так, как я хотел. Сейчас я текстурирую другие квадраты, не имело особого значения, что они не были текстурированы, так как я просто пытался заставить работать несколько текстур. - person Elec0; 23.07.2011