質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.48%

SDL_RenderCopyができない (SDL_SetRenderTarget がうまく動作しない為だと思われる)

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 865

score 12

SDLを自分風に使いやすくするための補助プログラムを作成しているのですが、
SDL_RenderCopyがうまく動作しません。

抜粋コード (main.cppより)

SDL_SetRenderTarget(renderer,NULL);

SDL_SetRenderDrawColor(renderer,255,255,255,255);
SDL_RenderClear(renderer);

//---

SDL_SetRenderTarget(renderer,texture);

if(SDL_GetRenderTarget(renderer)!=texture)cout<<"NOT WORKING..."<<endl;

SDL_SetRenderDrawColor(renderer,255,255,255,255);
SDL_RenderClear(renderer);

renderer.drawPrmLine(10,10,100,200,tRGB_red); // 赤い線を描画
SDL_RenderCopy(renderer,texture,NULL,NULL);

//---

SDL_RenderPresent(renderer);

出力

NOT WORKING...
NOT WORKING...
NOT WORKING...
NOT WORKING...
NOT WORKING...
.
.
.


赤い線が表示されず、windowは真っ白です。
個人的にはSDL_SetRenderTargetがうまく作動していない可能性を疑っていますが、初心者なので根本から間違っている可能性も否めません。
どのようにすべきでしょうか?

以下全文

tG_base.h

#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

class tG_POINT{
public:
     double x,y;
     tG_POINT(double nx=0, double ny=0){
          x=nx;
          y=ny;
     }
     friend ostream & operator<<(ostream & opt,tG_POINT nxy){ return opt<<'['<<nxy.x<<':'<<nxy.y<<']'; }

};

double clampt(double tar,double mx=1.0,double mn=0.0){ return max(mn,min(mx,tar)); }

struct tRGB {

     double r,g,b,a;
     tRGB(double nr=0.0,double ng=0.0,double nb=0.0,double na=1.0){ r=nr;g=ng;b=nb;a=na; }

     //Uint32    toRGB   (SDL_Surface * sur){ return SDL_MapRGB(sur->format,clampt(r)*255,clampt(g)*255,clampt(b)*255); }
     SDL_Color toSDLRGB()                 { return {Uint8(clampt(r)*255),Uint8(clampt(g)*255),Uint8(clampt(b)*255),Uint8(clampt(a)*255)}; }

     tRGB operator+ (tRGB nrgb) { return tRGB(r+nrgb.r,g+nrgb.g,b+nrgb.b,a+nrgb.a); }
     tRGB operator- (tRGB nrgb) { return tRGB(r-nrgb.r,g-nrgb.g,b-nrgb.b,a-nrgb.a); }
     tRGB operator* (tRGB nrgb) { return tRGB(r*nrgb.r,g*nrgb.g,b*nrgb.b,a*nrgb.a); }
     tRGB operator/ (tRGB nrgb) { return tRGB(r/nrgb.r,g/nrgb.g,b/nrgb.b,a/nrgb.a); }

     tRGB operator* (double n)  { return tRGB(r*n,g*n,b*n,a*n); }
     void operator*=(double n)  { r*=n; g*=n; b*=n; a*=n; }

     friend ostream & operator<<(ostream & opt,tRGB nrgb){ return opt<<'['<<nrgb.r<<':'<<nrgb.g<<':'<<nrgb.b<<':'<<nrgb.a<<']'; }

};



#define tRGB_null   tRGB(0,0,0,0)
#define tRGB_black  tRGB(0,0,0,1)
#define tRGB_red    tRGB(1,0,0,1)
#define tRGB_green  tRGB(0,1,0,1)
#define tRGB_blue   tRGB(0,0,1,1)
#define tRGB_yellow tRGB(1,1,0,1)
#define tRGB_sky    tRGB(0,1,1,1)
#define tRGB_pink   tRGB(1,0,1,1)
#define tRGB_white  tRGB(1,1,1,1)

#define tRGB_A(N)  tRGB(1,1,1,N)

#define t_default_font "/etc/alternatives/fonts-japanese-gothic.ttf"

tG_renderer.h

#include "tG_base.h"

struct tG_RENDERER{

     SDL_Renderer * renderer;
     tG_POINT scwh,rdwh;

     tG_RENDERER(SDL_Window * nwindow=NULL, double nw=0, double nh=0){
          renderer= SDL_CreateRenderer(nwindow,-1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
          rdwh=tG_POINT(nw,nh);
     }

     void setBlendMode(SDL_BlendMode nbm=SDL_BLENDMODE_BLEND){
          SDL_SetRenderDrawBlendMode(renderer,nbm);
     }

     void registerin(tG_POINT nscwh){
          scwh=nscwh;
     }

     void updateRenderer(){
          SDL_RenderPresent(renderer);
     }

     void setColor(tRGB col){
          col*=255.0;
          SDL_SetRenderDrawColor(renderer, col.r, col.g, col.b, col.a);
     }

     void clearRenderer(tRGB col=tRGB_white){
          setColor(col);
          SDL_RenderClear(renderer);
     }

     void drawPrmRect(int x, int y, int w, int h, tRGB col=tRGB_black){
          setColor(col);
          SDL_Rect rect={x, y, w, h};
          SDL_RenderFillRect(renderer, &rect);
     }

     void drawPrmPoint(SDL_Renderer * rd, int x, int y, tRGB col=tRGB_black){
          setColor(col);
          SDL_RenderDrawPoint(renderer, x, y);
     }

     void drawPrmLine(int sx, int sy, int ex, int ey, tRGB col=tRGB_black){
          setColor(col);
          SDL_RenderDrawLine(renderer, sx, sy, ex, ey);
     }

};

struct tG_TEXTURE{
     SDL_Texture * texture;
     tG_TEXTURE(tG_RENDERER renderer=NULL, int nw=0, int nh=0){
          texture=SDL_CreateTexture(renderer.renderer, SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET, nw, nh);
     }

};

tG_screen.h

#include "tG_renderer.h"

void tG_INIT(){
     SDL_Init(SDL_INIT_EVERYTHING);
}
void tG_QUIT(){
     SDL_Quit();
}

struct tG_SCREEN{

     SDL_Window * window;
     tG_RENDERER renderer;
     tG_TEXTURE background;
     tG_POINT wh;

     tG_SCREEN(double nw=0, double nh=0, int layerSize=1, const char * title = "", int nx=SDL_WINDOWPOS_CENTERED, int ny=SDL_WINDOWPOS_CENTERED){
          window = SDL_CreateWindow(title,nx,ny,nw,nh,0);
          wh=tG_POINT(nw,nh);

          renderer=tG_RENDERER(window,nw,nh);
          renderer.setBlendMode(SDL_BLENDMODE_BLEND);
          background=tG_TEXTURE(renderer,nw,nh);

     }

     ~tG_SCREEN(){
          SDL_DestroyRenderer(renderer.renderer);
          SDL_DestroyTexture(background.texture);
          SDL_DestroyWindow(window);
     }

     void run(void(* tG_MAINLOOP)(tG_RENDERER &,tG_TEXTURE &),int delay=16){

          bool looping=true;
          SDL_Event ev;
          while(looping){
               while(SDL_PollEvent(&ev)){
                    switch(ev.type){
                         case SDL_QUIT:
                              looping=false;
                              break;
                         case SDL_KEYDOWN:
                              //if(keyEvent[ev.key.keysym.sym]  != NULL)keyEvent[ev.key.keysym.sym]();
                              break;
                         case SDL_MOUSEBUTTONDOWN:
                              //if(mouseEvent[ev.button.button] != NULL)mouseEvent[ev.button.button]();
                              break;
                    }

               }
               tG_MAINLOOP(renderer,background);
               SDL_Delay(delay);
          }
     }


};

main.cpp

#include "tG_screen.h"

void tG_MAINLOOP(tG_RENDERER & renderer,tG_TEXTURE & background){

     SDL_SetRenderTarget(renderer.renderer,NULL);
     renderer.clearRenderer(tRGB_white);

     SDL_SetRenderTarget(renderer.renderer,background.texture);

     if(SDL_GetRenderTarget(renderer.renderer)!=background.texture)cout<<"NOT WORKING..."<<endl;

     renderer.clearRenderer(tRGB_white);
     renderer.drawPrmLine(10,10,100,200,tRGB_red);
     SDL_RenderCopy(renderer.renderer,background.texture,NULL,NULL);

     renderer.updateRenderer();
}


int main(){
     tG_INIT();
     tG_SCREEN mainSC(600,400,2);
     mainSC.run(tG_MAINLOOP);
     tG_QUIT();
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • iwanote

    2019/07/06 15:24

    SDL_SetRenderTargetの戻り値を確認してみては?

    キャンセル

  • Yohso

    2019/07/06 21:26 編集

    0でした。おそらく正常に動いています。

    (ご意見ありがとうございました。他の関数の戻り値も確認してみます。)

    キャンセル

回答 1

check解決した方法

0

これで動きました。
(検証できてないけど一応貼っておく)

SDL_SetRenderTarget(renderer,texture);


SDL_SetRenderDrawColor(renderer,255,255,255,255);
SDL_RenderClear(renderer);

renderer.drawPrmLine(10,10,100,200,tRGB_red); // 赤い線を描画

//---

SDL_SetRenderTarget(renderer,NULL);

SDL_RenderCopy(renderer,texture,NULL,NULL); // この関数自体描画と同じ扱い

//---

SDL_RenderPresent(renderer);

どうやらSetRenderTargetのしわざではなく、ただただ関数を実行するタイミングを間違えていたようです。
(質問のコードだと、RenderTargetがbackground.textureになったままRenderCopyをしてしまったので、NULLの方では何も処理されていなかったというわけ)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る