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

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

新規登録して質問してみよう
ただいま回答率
87.20%
OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

解決済

C++ openGL BMP描画について

nia_1001
nia_1001

総合スコア13

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

2回答

0評価

0クリップ

2539閲覧

投稿2019/07/18 05:07

編集2019/07/18 05:15

前提・実現したいこと

24BitのBMP描画はできました...

しかしRGBの配置が変なので変更したのですが色が白黒になってしまいます

配列を変える前はこの画像は青のキャラではなくオレンジで描画されてました

これを下の画像のように正しい色で描画したいです

あと画像が反転してるのでそれも直したいです

イメージ説明

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

C++

#include <stdio.h> #include <Windows.h> #include "glut.h" #include "Tex.h" int TexFromBMP(const char * _fileName) { FILE *pFile; fopen_s(&pFile, _fileName, "rb");//ファイルの読み込み if (pFile == nullptr) { printf("%s open failed\n", _fileName); return 1; } printf("%s open\n", _fileName); BITMAPFILEHEADER bf;//ヘッダーのデータを格納する fread(&bf, sizeof BITMAPFILEHEADER, 1, pFile); printf("bf size:%d\n", bf.bfSize);//ファイルサイズ BITMAPINFOHEADER bi; fread(&bi, sizeof BITMAPINFOHEADER, 1, pFile); printf("biWidth:%d biHHeight:%d\n", bi.biWidth, bi.biHeight); printf("biBitCount:%d\n",bi.biBitCount); typedef struct { unsigned char r, g, b;//24Bitなので }RGB; RGB *bits = (RGB*)malloc(sizeof RGB * bi.biWidth * bi.biHeight);//ピクセルデータを確保する fread(bits, sizeof RGB, bi.biWidth * bi.biHeight, pFile);//ピクセルデータを読み込んだ //RGBのRとBを入れ替えた for(int y=0; y<bi.biHeight; y++) for (int x = 0; x < bi.biWidth; x++) { RGB *pBit = &bits[y * bi.biWidth + x]; unsigned char temp = pBit->r; pBit->r = pBit->b; pBit->b = temp; } /*for (int y = 0; y < bi.biHeight; y++) for (int x = 0; x < bi.biWidth; x++) { RGB *pBit0 = &bits[y*bi.biWidth+x]; RGB *pBit1 = &bits[(bi.biHeight - 1 - y)*bi.biWidth + x]; RGB temp = *pBit0; *pBit0 = *pBit1; *pBit1 = temp; }*/ //2次元テクスチャを描画 glTexImage2D( GL_TEXTURE_2D, //GLenum target, 0,//GLint level, GL_RGB, //GLint internalformat, bi.biWidth, //GLsizei width, bi.biHeight, //GLsizei height, 0,//GLint border, GL_RGB,//GLenum format, GL_UNSIGNED_BYTE,//GLenum type, bits);//const GLvoid *pixels //フィルタリング glTexParameteri( GL_TEXTURE_2D,//GLenum target, GL_TEXTURE_MAG_FILTER,//GLenum pname, GL_NEAREST//GLint param ); glTexParameteri( GL_TEXTURE_2D,//GLenum target, GL_TEXTURE_MIN_FILTER,//GLenum pname, GL_NEAREST//GLint param ); free(bits); fclose(pFile); return 0; } ```C++ main ```C++ 四角を描画 #include <stdio.h> #include <time.h> #include "Font.h" #include "glm/glm.hpp" #include "glut.h" #include "Rect.h" #include "Ball.h" #include "Tex.h" using namespace glm; #define BALL_MAX 256 ivec2 WindowSize = { 600,420 }; //Windowのサイズ 縦,横 bool Keys[256];//押されているかのフラグ Ball balls[BALL_MAX]; Rect rect1 = Rect(vec2(100, 100), vec2(100, 200)); Rect rect2 = Rect(vec2(WindowSize.x/2, WindowSize.y/2), vec2(200, 100)); void display(void) { glClear(GL_COLOR_BUFFER_BIT); //GLbitfield mask 画面の情報をリセット //2D glMatrixMode(GL_PROJECTION);//GLenum mode glLoadIdentity(); gluOrtho2D( 0,//GLdouble left, WindowSize.x,//GLdouble right, WindowSize.y,//GLdouble bottom, 0//GLdouble top ); glMatrixMode(GL_MODELVIEW); //GLenum mode モード設定 glLoadIdentity();//リセットしている /*if (rect1.Intersect(rect2)) glColor3ub(0xff, 0x00, 0x00); else glColor3ub(0x00, 0x00, 0xff); rect1.Draw(); glColor3ub(0x00, 0xff, 0x00); rect2.Draw();*/ //unsigned char pixels[] = { // 0xff,0x00,0x00,//赤 // 0x00,0xff,0x00,//緑 // 0x00,0x00,0xff,//青 // 0xff,0xff,0x00//黄 //}; //glPixelStorei( // GL_UNPACK_ALIGNMENT,//GLenum pname // 1//GLint param //); glEnable(GL_TEXTURE_2D);//2次元テクスチャを有効 Rect(vec2(0,0),vec2(150,150)).Draw(); //*for (int i = 0; i < BALL_MAX; i++) //{ // balls[1].Draw(); //} //float y=0;*/ FontBegin(); /*FontSetPosition(0, y);*/ //FontDraw("min:%f max:%f", FontGetWeightMin(), FontGetWeightMax()); FontEnd(); glutSwapBuffers();//命令 } void Idle(void) { float f = 0.5; if (Keys['w'])rect1.m_position.y -= f; if (Keys['s'])rect1.m_position.y += f; if (Keys['a'])rect1.m_position.x -= f; if (Keys['d'])rect1.m_position.x += f; for (int i = 0; i < BALL_MAX; i++) { balls[i].Update(); //跳ね返り if (balls[i].m_position.x >= WindowSize.x)//右壁 { balls[i].m_position = balls[i].m_LastPosition; balls[i].m_speed.x = -fabs(balls[i].m_speed.x); } if (balls[i].m_position.x < 0)//左壁 { balls[i].m_position = balls[i].m_LastPosition; balls[i].m_speed.x = fabs(balls[i].m_speed.x); } if (balls[i].m_position.y < 0)//上壁 { balls[i].m_position = balls[i].m_LastPosition; balls[i].m_speed.y = fabs(balls[i].m_speed.y); } if (balls[i].m_position.y >= WindowSize.y)//下壁 { balls[i].m_position = balls[i].m_LastPosition; balls[i].m_speed.y = -fabs(balls[i].m_speed.y); } } glutPostRedisplay(); } //再描画命令 void Timer(int value) { glutPostRedisplay();//再度描画命令 glutTimerFunc( 1000/60,//unsigned int millis 〇秒後に開始 60FPSにしてる Timer,//void (GLUTCALLBACK *func)(int value) 関数起動 0); //int value 渡す数値 必要ないので0 } void Reshape(int width, int height) { printf("reshape: width:%d height:%d\n", width, height);//確認のため //更新するのでwindowサイズが変わっても大丈夫 glViewport( 0, 0,//(GLint x,y, 座標 width, height//GLsizei width,height) 幅高さ ); //windowサイズ更新 WindowSize = ivec2(width, height); } void (Keyboard)(unsigned char key, int x, int y)//intはマウス { if (key == 0x1b) { exit(0); } printf("Keyboard:\'%c\'(%#x)\n",key,key); Keys[key] = true; } void (KeyboardUp)(unsigned char key, int x, int y) { printf("KeyboardUp:\'%c\'(%#x)\n", key, key); Keys[key] = false; } int main(int argc, char *argv[]) { srand(time(NULL)); for (int i = 0; i < BALL_MAX; i++) { balls[i].m_speed = normalize( vec2((float)rand()/RAND_MAX, (float)rand()/RAND_MAX)); } glutInit( &argc, //int *argcp, argv); //char **argv); glutInitDisplayMode(GL_DOUBLE);//unsigned int mode ダブルバッファを使うようにする glutInitWindowSize(WindowSize.x, WindowSize.y); //int width, int height glutCreateWindow("title");//const char *title TexFromBMP("Megaman01.bmp"); glutDisplayFunc(display);//void (GLUTCALLBACK *func)(void) glutIdleFunc(Idle);//void (GLUTCALLBACK *func)(void) Idle状態のときに呼ばれる //垂直同期がとれないためTimerでやる glutTimerFunc( 0,//unsigned int millis 〇秒後に開始 Timer,//void (GLUTCALLBACK *func)(int value) 関数起動 0); //int value 渡す数値 必要ないので0 //windowのサイズが変わったときのコールバック関数定義 glutReshapeFunc(Reshape);//void (GLUTCALLBACK *func)(int width, int height) //Keyboardを取得 glutKeyboardFunc(Keyboard);//void (GLUTCALLBACK *func)(unsigned char key, int x, int y) //keyrepeatを無効にする glutIgnoreKeyRepeat(GL_TRUE);//int ignore //keyboardが離されたときの処理 glutKeyboardUpFunc(KeyboardUp);//void (GLUTCALLBACK *func)(unsigned char key, int x, int y) glutMainLoop();//MainLoop }
### 試したこと 配列を変えた感じです ### 補足情報(FW/ツールのバージョンなど) ここにより詳細な情報を記載してください。

良い質問の評価を上げる

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

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

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

気になる質問をクリップする

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

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

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

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

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

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

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

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。