スポンサーリンク
#pragma once #include <Windows.h> #include <gl/GL.h> #include <vector> #include <cstdio> #pragma warning(disable:4996)
//画像の上下を反転する void reverse_Y(const int width, const int height, unsigned char* p) { int WidthByte = width * 3; size_t HalfHEIGHT = height / 2; for (int ha = 0; ha < HalfHEIGHT; ha++) { int hb = (height - ha) - 1; unsigned char* pha = p + ha * WidthByte; unsigned char* phb = p + hb * WidthByte; if (ha != hb) { for (size_t i = 0; i < WidthByte; i++) { std::swap(pha[i], phb[i]); } } } }
//! @brief PPM(RGB各1byte,カラー,テキスト)を書き込む //! @param [in] fname ファイル名 //! @param [in] vmax 全てのRGBの中の最大値 //! @param [in] width 画像の幅 //! @param [in] height 画像の高さ //! @param [in] p 画像のメモリへのアドレス //! @details RGBRGBRGB....のメモリを渡すと、RGBテキストでファイル名fnameで書き込む void pnmP3_Write(const char* const fname, const int vmax, const int width, const int height, const unsigned char* const p) { // PPM ASCII FILE* fp = fopen(fname, "w"); fprintf(fp, "P3\n%d %d\n%d\n", width, height, vmax); size_t k = 0; for (size_t i = 0; i < (size_t)height; i++) { for (size_t j = 0; j < (size_t)width; j++) { fprintf(fp, "%d %d %d ", p[k * 3 + 0], p[k * 3 + 1], p[k * 3 + 2]); k++; } fprintf(fp, "\n"); } fclose(fp); }
//! @brief OpenGLの画面を画像に保存 //! @param [in] width 画像幅ピクセル数 //! @param [in] height 画像高さピクセル数 //! @param [in] pathname ファイル名 void saveGLtoPPM(const int width, const int height, const char* pathname) { //メモリ確保 std::vector<GLubyte> buffer; buffer.resize(width*height * 3); //画像取得 glReadBuffer(GL_FRONT); glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer.data()); //上下反転 reverse_Y(width, height, buffer.data()); pnmP3_Write( pathname, 255, width, height, buffer.data()); // PPM ASCII }
#include <iostream> #include <Windows.h> #include "prepare_shader.hpp" #include <gl/GL.h> #include <gl/GLU.h> #include <gl/freeglut.h> #include <fstream> #include "saveGLtoPPM.hpp" #pragma comment(lib,"glew32.lib") //ウィンドウの幅と高さ int Width, Height; GLuint buf_points; GLuint buf_colors; GLfloat mproj[16]; GLfloat mmodel[16]; GLuint programID; // シェーダとデータの設定 void init() { std::vector<GLfloat> colors; std::vector<GLfloat> points; GLfloat v = 0.8; push_3(colors, 0, 0, 1);//色 RGB push_3(points, 0, 0, 0);//座標 XYZ push_3(colors, 0, 1, 0); push_3(points, 0, v, 0); push_3(colors, 1, 0, 0); push_3(points, v, 0, 0); prepare_buffer(&buf_points, points.data(), points.size() * sizeof(GLfloat), GL_STATIC_DRAW); prepare_buffer(&buf_colors, colors.data(), colors.size() * sizeof(GLfloat), GL_STATIC_DRAW); GLuint vtxShader; GLuint flagShader; const char* vtxfile = "default.vert"; const char* fragfile = "default.frag"; std::string verr; std::string ferr; prepare_shader_byfile(&vtxShader, GL_VERTEX_SHADER, vtxfile, &verr); prepare_shader_byfile(&flagShader, GL_FRAGMENT_SHADER, fragfile, &ferr); std::cout << verr << std::endl; std::cout << ferr << std::endl; std::string linkerr; link_program(&programID, { vtxShader ,flagShader }, nullptr, &linkerr); loadidentity44(mproj); loadidentity44(mmodel); } //描画関数 void disp(void) { glViewport(0, 0, Width, Height); glClearColor(0.2, 0.2, 0.2, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(programID); GLuint loc_ModelViewMatrix = glGetUniformLocation(programID, "ModelViewMatrix"); GLuint loc_ProjectionMatrix = glGetUniformLocation(programID, "ProjectionMatrix"); glUniformMatrix4fv(loc_ModelViewMatrix, 1, GL_FALSE, mmodel); glUniformMatrix4fv(loc_ProjectionMatrix, 1, GL_FALSE, mproj); { auto bindbufP = EnableAndBindFArrayBuffer(0, buf_points, 3, GL_FLOAT); auto bindbufC = EnableAndBindFArrayBuffer(1, buf_colors, 3, GL_FLOAT); glDrawArrays(GL_TRIANGLES, 0, 3); } glFlush(); } //ウィンドウサイズの変化時に呼び出される void reshape(int w, int h) { Width = w; Height = h; disp(); }
// クリックでファイルに保存 void mouse(int button, int state, int x, int y) {
saveGLtoPPM( Width, Height, R"(C:\test\a.ppm)");
} //エントリポイント int main(int argc, char** argv) { glutInit(&argc, argv); glutInitWindowPosition(100, 50); glutInitWindowSize(500, 500); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutCreateWindow("sample"); glutDisplayFunc(disp); glutReshapeFunc(reshape); glutMouseFunc(mouse); glewInit(); init(); glutMainLoop(); return 0; }