2 / 2 / 0
Регистрация: 23.03.2016
Сообщений: 39
1

Копирование объекта в вектор

09.05.2016, 09:01. Показов 1537. Ответов 14
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Пишу граф. движок, но проблема скорее всего не с opengl. Возникла проблема с анимированной текстурой, вернее с её копией. Оригинал работает как надо, а вот копия не анимируется. Копирую, просто добавляя оригинал в конец вектора, без собственного конструктора, копирования. В дебаггере, все поля смотрел - значения в копии правильные, однако есть большая странность: анимация в копии происходит, НО! Исключительно при пошаговом прохождении в отладчике, в реальном же времени отображается только стартовый кадр (прошу обратить на это самое пристальное внимание! работает, но только пошагово!). Может дело в компиляторе? Ubuntu + Code::Blocks + GNU GCC Compiler. Или всё же нельзя так объекты копировать? В чём подвох?
Код уже большой, даже не знаю что привести, вот функция, которая обновляет счетчик кадров (в оригинале стабильно, а в скопированном объекте, только если непосредственно её саму прогонять в дебаггере):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
void Texture::updateAnim(GLuint deltaT)
{
    bool b = false;
    if (animate)
    {
        timeCount += deltaT;
        if (timeCount >= delay)
        {
            timeCount -= delay;
            if (timeCount > delay) timeCount = 0;
            if (currFrame == 0 && frameStep == -1)
            {
                b = true;
            }
            if (!b) currFrame += frameStep;
            if (currFrame > endFrame)
            {
                if (!pingPong)
                {
                    if(repeat)
                    {
                        currFrame = startFrame;
                    }
                    else
                    {
                        animate = false;
                        currFrame = endFrame;
                    }
                }
                else
                {
                    currFrame = endFrame - 1;
                    frameStep = -1;
                }
            }
            if (currFrame < startFrame || b == true)
            {
                if(repeat)
                {
                    currFrame = startFrame + 1;
                    frameStep = 1;
                }
                else
                {
                    animate = false;
                    currFrame = startFrame;
                    frameStep = 1;
                }
            }
        }
    }
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.05.2016, 09:01
Ответы с готовыми решениями:

Копирование Массив в Вектор
Читаю пример Википедии, там приведен пример, в котором элементы массива копируются в вектор. Для...

Копирование из временного объекта
1) Собственно, как работает такой конструктор? Хотелось бы какой-нибудь пример. 2) Сильно ли...

Копирование объекта в поток
&quot;Переданный объект-функция копируется в память, принадлежащую только что созданному потоку...

Копирование объекта из бинарного файла
Привет всем. Вот код мэйн: int _tmain(int argc, _TCHAR* argv) { Matrix obj1; Matrix obj2;...

14
Заблокирован
09.05.2016, 09:19 2
без собственного конструктора, копирования.
- этом вся и проблема, особенно если там поинтеры в качестве полей.
0
2 / 2 / 0
Регистрация: 23.03.2016
Сообщений: 39
09.05.2016, 09:25  [ТС] 3
а в чем конкретно проблема? Список кадров - указатель, который указывает на тот же адрес памяти, что и в оригинале. Тем более, что в пошаговом режиме работает, и если явно указать номер кадра, то отображается он, как и положено.
0
Заблокирован
09.05.2016, 09:34 4
Как какая проблема - простая, когда добвляем в вектор, внутри него получаем дубликат который проинициализирован копией всего того что есть в исходном классе, НО если не предусмотерн конструктор копирования то поинтер внутри вектора примет значение поинтера который снаружи, тогда при разрушении поинтера снаружи, поинтер внутри элемента вектора будет ссылаться на невалидную область. Друг это как отче наш - юзаешь вектор сразу пиши конструктор копирования.
0
2 / 2 / 0
Регистрация: 23.03.2016
Сообщений: 39
09.05.2016, 09:39  [ТС] 5
это понятно, но в данной конкретной ситуации, данные на которые указывает поинтер на месте, оригинал не удалялся
0
Заблокирован
09.05.2016, 09:57 6
это понятно, но в данной конкретной ситуации, данные на которые указывает поинтер на месте, оригинал не удалялся
- конкретно убийство данных происходит при ресайзе вектора(коим и пушбэк является), ниже пример и для этого случая
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <vector>
#include <iostream>
using namespace std;
 
class cExample{
    char * ptr;
    size_t len;
    public:
    cExample(){
        ptr= 0;
        len = 0;
    }
    ~cExample(){
        delete ptr;
    }
    char * data(){
        return ptr;
    }
    size_t size(){
        return len;
    }
    bool init(const char * str){
        bool flag = false;
        delete ptr;
        ptr = 0;
        len = 0;
        if( str ){
            len = strlen(str);
            ptr = new char[1 + len];
            if( strcpy(ptr, str) )
            {
                flag = true;
                ptr[len] = 0;
            }
        }
        return flag;
    }
    /*cExample(const cExample &ex){
        ptr = new char[1 + ex.len];
        if( (len = ex.len) != 0 )
            strcpy(ptr, ex.ptr);
        ptr[len] = 0;
        
    }*/
};
 
int main(){
    vector< cExample > vec;
    cExample ex;
    if( ex.init("test") )
    {
        vec.push_back(ex);
        vec.push_back(ex);
        cout<<"OK"<<vec[0].data()<<endl;
    }
    return 0;
}
http://codepad.org/7JoIRh3l
стоит вернуть КК и всё заработает верно
0
2 / 2 / 0
Регистрация: 23.03.2016
Сообщений: 39
09.05.2016, 10:46  [ТС] 7
для успокоения души написал конструктор копирования - но результат тот же...
как я и писал, если дебажить код пошагово, входя в приведенную мной функцию, то currFrame прибавляется как надо, но если внутрь этой функции не входить, то currFrame = 0, а в оригинальном объекте всё прибавляется как надо...
на всякий случай вот КК, мож чё неправильно?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Texture::Texture(const Texture& tex)
{
    texSample = tex.texSample;
    imgWidth = tex.imgWidth;
    imgHeight = tex.imgHeight;
    imgBPP = tex.imgBPP;
    imgFormat = tex.imgFormat;
    numFrames = tex.numFrames;
    img = new GLubyte* [numFrames];
    glTexID = new GLuint [numFrames];
    memcpy(glTexID, tex.glTexID, numFrames * sizeof(GLuint));
    GLuint s = imgWidth * imgHeight * imgBPP/8;
    for (GLuint i = 0; i < numFrames; i++)
    {
        img[i] = new GLubyte [s];
        memcpy(img[i], tex.img[i], s * sizeof(GLubyte));
    }
    texID = tex.texID;
    currFrame = tex.currFrame;
    delay = tex.delay;
    startFrame = tex.startFrame;
    frameStep = tex.frameStep;
    endFrame = tex.endFrame;
    animate = tex.animate;
    pingPong = tex.pingPong;
    repeat = tex.repeat;
    timeCount = 0;
}
Добавлено через 57 секунд
Вот сам класс:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class Texture
{
private:
    GLuint texSample;
    GLuint imgWidth;
    GLuint imgHeight;
    GLuint imgBPP;
    GLuint imgFormat;
    GLuint numFrames;
    GLuint currFrame;
    GLuint* glTexID;
    GLuint timeCount;
    GLuint startFrame;
    GLuint endFrame;
    GLbyte frameStep;
    bool   repeat;
    bool   pingPong;
    bool   animate;
    GLuint delay;
public:
    GLuint texID;
    GLubyte** img;
    Texture();
    Texture(const Texture& tex);
    ~Texture();
    void fillTextureData();
    void freeTextureData();
    void freeImageBuffer();
    void getImgSize(GLuint* width, GLuint* height);
    GLuint getGlTexID() { return glTexID[currFrame]; }
    GLuint getImgFormat() { return imgFormat; }
    void proceduralNoise(GLbyte noiseSize, GLubyte r, GLubyte g, GLubyte b);
    void create(GLuint ID, GLuint format, GLuint width, GLuint height);
    bool loadTGA(const char* fileName);
    bool isCreated();
    void textureToAnim(GLuint widthFrame, GLuint heightFrame);
    void updateAnim(GLuint deltaT);
    void startAnim(GLuint StartFrame, GLuint EndFrame, GLuint millisecs, bool Repeat, bool PingPong);
    void startAnim(GLuint StartFrame, GLuint EndFrame);
    void stopAnim(GLuint Frame);
    void setAnimParam(GLuint delayMS, bool Repeat, bool PingPong);
    GLuint getCurrentFrame() { return currFrame; }
};
Добавлено через 5 минут
кстати сейчас проверил - не обновляется счетчик времени, в отличии от оригинала...
0
Заблокирован
09.05.2016, 10:52 8
Цитата Сообщение от Manofrus Посмотреть сообщение
GLuint s = imgWidth * imgHeight * imgBPP/8;
* * for (GLuint i = 0; i < numFrames; i++)
* * {
* * * * img[i] = new GLubyte [s];
* * * * memcpy(img[i], tex.img[i], s * sizeof(GLubyte));
* * }
- мне вот это не нравится канешн, но для начала предлагаю записать вот так :
C++
1
2
3
4
5
6
GLuint s = (imgWidth * imgHeight * imgBPP)/8;
    for (GLuint i = 0; i < numFrames; i++)
    {
        img[i] = new GLubyte [s];
        memcpy(img[i], tex.img[i], s * sizeof(GLubyte));
    }
Добавлено через 1 минуту
Цитата Сообщение от Manofrus Посмотреть сообщение
не обновляется счетчик времени, в отличии от оригинала...
- он же в ноль у тебя стоит
Цитата Сообщение от Manofrus Посмотреть сообщение
repeat = tex.repeat;
* * timeCount = 0;
почему не
C++
1
timeCount = tex.timeCount;
?
0
2 / 2 / 0
Регистрация: 23.03.2016
Сообщений: 39
09.05.2016, 11:00  [ТС] 9
у каждого объекта свой счетчик, обновляемый в главном цикле, после копирования он и должен быть нулевым. Но у меня появляется идея, что работает не так, пока не уверен, но дело, кажется, в deltaTime, там так коряво сделано, что после вызова "оригинальной" анимации, при повторном вызове он ничтожно мал, сейчас покопаюсь в этом направлении...
0
Заблокирован
09.05.2016, 11:02 10
Manofrus, покажи лучше как добавляешь в вектор.
0
2 / 2 / 0
Регистрация: 23.03.2016
Сообщений: 39
09.05.2016, 11:07  [ТС] 11
C++
1
2
3
4
5
6
7
void Golem::textureCopy(GLuint* newTexID, GLuint oldTexID)
{
    *newTexID = texCount;
    texture.push_back(texture[oldTexID]);
    texture[*newTexID].texID = *newTexID;
    texCount++;
}
Но дело действительно оказалось в deltaTime. В цикле, где вызывается функция обновления кадров анимации, он обновлялся при каждом проходе, по-этому нормально работал только первый проход а при последующих он равнялся почти нулю, теперь обновляю дельту один раз перед циклом и всё нормально работает)))
спасибо за отклик
0
Заблокирован
09.05.2016, 11:13 12
texture (
Цитата Сообщение от Manofrus Посмотреть сообщение
texture.push_back
) что такое - vector< Texture > - ?
0
2 / 2 / 0
Регистрация: 23.03.2016
Сообщений: 39
09.05.2016, 11:18  [ТС] 13
в каком смысле?
Texture - класс
texture(с маленькой t) = vector<Texture>
0
Заблокирован
09.05.2016, 11:20 14
Лучший ответ Сообщение было отмечено Manofrus как решение

Решение

Цитата Сообщение от Manofrus Посмотреть сообщение
texture(с маленькой t) = vector<Texture>
- я это и спрашивал, внешне всё выглядит нормально, думаю...
0
2 / 2 / 0
Регистрация: 23.03.2016
Сообщений: 39
09.05.2016, 11:27  [ТС] 15
спасибо!
0
09.05.2016, 11:27
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.05.2016, 11:27
Помогаю со студенческими работами здесь

Добавление в вектор объекта класса в конструкторе
Почему у меня не получается сделать вот так? vector &lt;C&gt; Vec; class C { public:

Как лучше запретить копирование объекта?
Есть класс, надо запретить копирование его экземпляров. Можно как то сделать, чтоб в интерфейсе...

Копирование части вектора в другой вектор по условию, функцией copy_if
Добрый день. Есть вектор структуры. Нужно сделать копию вектора по условию. Можно конечно в...

Ошибка при добавлении в вектор объекта типа thread
функцию запускаю void Sorted_Char( char *Memory_Damp, int i_find, int size_arr, std::vector &lt;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru