在尝试渲染一些纹理时,我遇到了一些非常奇怪的行为 . 我'm using a custom Texture warper based on Lazy Foo'的教程(http://lazyfoo.net/tutorials/SDL/43_render_to_texture/index.php)名为Texture, Build 在SDL 's texture class SDL_Texture. Usually when I create a texture using my default constructor 1119151 , and then try to render it to the screen, everything works as intended. However on 3 separate occasions now I'之上,得到了非常奇怪的行为 . 在问题的情况下,它经常从一个不同的对象中绘制一个纹理并且它变得扭曲,有时候它很简单,如果我将对象设置为指针并使用_1119152实例化它,一切都完全正常 .

幸运的是,我已经找到了使用指针解决问题的方法,但我可以想象只有三个方面中的一个导致这个问题:SDL2库中存在一个错误(不太可能),我的Texture类中有一个错误,或者我遗漏了关于如何在C中处理对象的一些非常基本的概念 . 在任何一种情况下,如果我试图忽略它,它会回来咬我 .

我正在开发Linux(Ubuntu 16.04)并使用G编译 .

我将在下面的一个问题实例中包含一些代码 . 在这种情况下,我创建了一个“HistoryEntry”类,它可以获取一些属性并将其自身绘制为任意的X和Y.除了timeText之外的所有HistoryEntry属性Texture对象都搞砸了,当它们绘制时它们似乎绘制了一个扭曲的版本timeText的纹理 . 它几乎看起来像他们保持自己的宽度和高度值,但当我加载timeText时,他们的纹理已被覆盖 . 但是,根据我的理解,构造函数将始终生成一个全新的对象,如果只复制其中的某些属性,则会特别奇怪 . 如果我将所有属性Texture对象更改为指向所述Texture对象的指针,则一切都会顺利运行 .

纹理构造函数和加载函数:

Texture::Texture()
{
    //Initialize
    mTexture = NULL;
    mWidth = 0;
    mHeight = 0;
}

bool Texture::loadText( std::string textureText, SDL_Color textColor, TTF_Font* gFont)
{
    //Get rid of preexisting texture
    free();

    //Render text surface
    SDL_Surface* textSurface = TTF_RenderText_Blended( gFont, textureText.c_str(), textColor ); 
    if( textSurface == NULL )
    {
        printf( "Unable to render text surface! SDL_ttf Error: %s\n", TTF_GetError() );
    }
    else
    {
        //Create texture from surface pixels
        mTexture = SDL_CreateTextureFromSurface( getRenderer(), textSurface );
        if( mTexture == NULL )
        {
            printf( "Unable to create texture from rendered text! SDL Error: %s\n", SDL_GetError() );
        }
        else
        {
            //Get image dimensions
            mWidth = textSurface->w;
            mHeight = textSurface->h;
        }

        //Get rid of old surface
        SDL_FreeSurface( textSurface );
    }

    //Return success
    return mTexture != NULL;
}

纹理渲染方法:

void Texture::render( int x, int y, int anchor, SDL_Rect* clip )
{
    SDL_Rect renderQuad;
    //Set rendering space and render to screen
    if(anchor == MIDDLE_CENTER){
        renderQuad = { x - mWidth/2, y - mHeight/2, mWidth, mHeight };
    }else if(anchor == MIDDLE_LEFT){
        renderQuad = { x, y - mHeight/2, mWidth, mHeight };
    }else if(anchor == MIDDLE_RIGHT){
        renderQuad = { x - mWidth, y - mHeight/2, mWidth, mHeight };
    }else{
        renderQuad = { x, y, mWidth, mHeight };
    }

    //Set clip rendering dimensions
    if( clip != NULL )
    {
        renderQuad.w = clip->w;
        renderQuad.h = clip->h;
    }

    //Render to screen
    SDL_RenderCopy( getRenderer(), mTexture, clip, &renderQuad );
}

HistoryEntry类:

#include <SDL.h>
#include <SDL_image.h>
#include <string>
#include "auxx.h"
#include "texture.h"
#include "history_entry.h"

HistoryEntry::HistoryEntry(){

}

// Constructor for notifications
HistoryEntry::HistoryEntry(int t, std::string n, std::string v)
{
    //Atributes
    type = t;
    eventTime = GetTimer();
    name = Texture();
    name.loadText(n, defaultColor, defaultFont);
    value = Texture();
    value.loadText(v, defaultColor, defaultFont);
    //code = Texture();
    //code.loadText(c, defaultColor, defaultFontSmall);
    //icon = i;
    timeText = Texture();

}

// Constuctor for error and warnings
HistoryEntry::HistoryEntry(int t, std::string n, std::string c, Texture i)
{
    //Atributes
    type = t;
    eventTime = GetTimer();
    name = Texture();
    name.loadText(n, defaultColor, defaultFont);
    //value = Texture();
    //value.loadText(v, defaultColor, defaultFont);
    code = Texture();
    code.loadText(c, defaultColor, defaultFontSmall);
    icon = i;
    timeText = Texture();

}

void HistoryEntry::draw(SDL_Renderer* renderer, int x, int y){

    if(type == NOTIFICATION_ENTRY){
        name.render(x + 7, y + 15);
        value.render(x + 620, y + 15);

        // Set up time text
        // Seconds
        if(timeSince() < 60){
            timeBuff = std::to_string(timeSince()) + " sec ago";
            timeText.loadText(timeBuff , defaultColor, defaultFont);
        }
        // Minutes
        else{
            timeBuff = std::to_string(timeSince()/60) + " min ago";
            timeText.loadText(timeBuff , defaultColor, defaultFont);
        }

        timeText.render(x + 440, y + 15);
    }else{
        icon.render(x + 3, y + 13);
        name.render(x + 44, y + 15);
        code.render(x + 44, y + 45);
        //value.render(x + 620, y + 15);

        // Set up time text
        // Seconds
        if(timeSince() < 60){
            timeBuff = std::to_string(timeSince()) + " sec ago";
            timeText.loadText(timeBuff , defaultColor, defaultFont);
        }
        // Minutes
        else{
            timeBuff = std::to_string(timeSince()/60) + " min ago";
            timeText.loadText(timeBuff , defaultColor, defaultFont);
        }

        timeText.render(x + 440, y + 15);
    }
}

int HistoryEntry::getHeight(){
    if(type = NOTIFICATION_ENTRY){
        return 63;
    }else{
        return 89;
    }
}

int HistoryEntry::timeSince(){
    return GetTimePassedSeconds(eventTime);
}

调用绘图的部分显示功能:

void DrawGraphics()
{
    SDL_Renderer *renderer = getRenderer();

    //Clear screen
    SDL_SetRenderDrawColor( renderer, 0xFF, 0xFF, 0xFF, 0xFF );
    SDL_RenderClear( renderer );

    ...

    // Draw history if it is active
    if(history_active){
        historyBackground.render(480, 79);
    }

    // Y position of first history entry
    int rowY = 134;
    // Draw history entries
    if(history_active){
        // Set color for history lines
        SDL_SetRenderDrawColor(renderer, 52, 64, 79, 0);

        for(int i = 0; i < history.size(); i++){
            history[i].draw(renderer, 495, rowY);
            // Increment the y value based on entry size
            if(history[i].type == NOTIFICATION_ENTRY){
                rowY += 63;
            }else{
                rowY += 89;
            }
            // Draw lines
            SDL_RenderDrawLine(renderer, 495, rowY - 1, 1287, rowY - 1);
        }
    }

    //Update screen
    SDL_RenderPresent( renderer );

}