๋ณผํ 3์ฐจ์ ์ ํ ์นดํ๋ก๊ทธ ์ ์
YouTube ๋ฐํ์์ |
---|
- ํ๋ก์ ํธ ๋ฐํ์๋ฃ: report.pdf
- ์๊ฐํ๊ธฐ: ๊ทธ๋ํฝ์ค๋ ์ํ์ ์ข์ํ๋ค - ์ธํ๋ํ๊ต ์ธํธ์์ด
- ๋ณผํ 3์ฐจ์ ์ ํ ์นดํ๋ก๊ทธ ์ ์
- OpenGL๊ณผ ๋ง์ฐ์ค, ํค๋ณด๋๋ฅผ ์ด์ฉํ interactive ํ๋ก์ ํธ ์์ฑ
- Blender ๋ชจ๋ธ๋ง๋ณด๋ค๋ OpenGL์ ํ์ฉํ ๋์ ์ธ ๊ธฐ๋ฅ ๊ตฌํ์ ์ค์ ์ ๋ ๊ฒ
- ๋ณผํ์ ์ค์ํ์์ ๊ฐ์ฅ ์ฝ๊ฒ ์ ํ ์ ์๋ ๋ฌผ์ฒด์.
- ๋๋ต์ ์ธ ํํ๋ฅผ ๋ชจ๋ธ๋งํ๋ ๊ฒ์ ์ฝ์ง๋ง, ๊ทธ๋ฆฝ๊ฐ์ ์ํ ๋ณผํ ๋ชธํต์ ๊ณก์ ์ ์ฌ์ธํ๊ฒ ๊ตฌํํ๊ธฐ ์ํด์๋ ๋ง์ ๋ ธ๋ ฅ์ด ํ์ํจ.
- ์ฌ๋๋ค์ด ๋ณผํ์ ๊ฐ์ง๊ณ ํ๋ interactiveํ ๋์(๋ณผํ ๋ธ๊น๊ฑฐ๋ฆฌ๊ธฐ, ์ด์ ์์ด ๋ณผํ ๋ถํดํ๊ธฐ)์ OpenGL ํ๋ก๊ทธ๋จ์ผ๋ก ๊ตฌํํด ๋ณผ ๊ฒ์.
- ๋์๊ฐ ๋ณผํ์ผ๋ก ์ข ์ด์ ๊ทธ๋ฆผ์ ๊ทธ๋ฆฌ๋ ๊ธฐ๋ฅ๊น์ง ๊ตฌํํ๋ฉฐ bmp ํ ์ค์ฒ์ ์นด๋ฉ๋ผ ์ด๋์ ๊น๊ฒ ํ์ตํจ.
- Blender๋ฅผ ์ด์ฉํด ๋ณผํ์ ๋ชจ๋ธ๋งํ๊ณ OpenGL ํ๋ก๊ทธ๋จ์ ์ด์ฉํด ๋ณด์ฌ์ค๋ค.
space
๋ฅผ ๋๋ฅด๋ฉด ๋ณผํ์ด์ ๊บผ๋ผ ์ ์๋ค. - ๋ง์ฐ์ค์
w
,a
,s
,d
,z
,x
๋ฅผ ์ด์ฉํด ์นด๋ฉ๋ผ์ ์์ ๊ณผ ์์น๋ฅผ ์ด๋ํ ์ ์๋ค.1
๋ฅผ ๋๋ฅด๋ฉด ๊ทธ๋ฆฌ๊ธฐ ๋ชจ๋๋ก ์ด๋ํ๋ค. - ๋ง์ฐ์ค๋ฅผ ์ด์ฉํด ๋ณผํ ์์ ๋ฐ๊ฟ ์ ์๋ค. ๋ณผํ ์์ด ๋ฐ๋๋ฉด ๋ณผํ ๋ชจ๋ธ์ ์๋ ๋ฐ๋๋ค.
- ๋์งํธ ์นด๋ฉ๋ผ๋ฅผ ์ด์ฉํด ๋ณผํ์ ํ ์ค์ฒ๋ฅผ ์ถ์ถํ๊ณ ๋งคํํ๋ค.
- ํ ์ค์ฒ๋ฅผ ์ฌ์ฌ์ฉํ๋ ๋ฑ์ ๋ฆฌ์์ค๋ฅผ ํจ์จ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋๋ก ๊ตฌํํ๋ค.
- ํจ๊ณผ์๊ณผ ์ ๋๋ฉ์ด์ ์ ์ด์ฉํด ์์ฐ์ค๋ฌ์ด ์ฐ์ถ์ ๊ตฌํํ๋ค.
- ๋ณผํ์ด ๊ฐ๊ฐ์ ํํธ๋ก ๋ถํด๋ ์ ์๋๋ก, ๋ณผํ ๋ชธํต, ๋ณผํ ์ฌ(์ด), ๋ณผํ ๋๊ป, ๋ณผํ ๋ฒํผ, ์คํ๋ง์ผ๋ก ๋๋์ด ๊ฐ๊ฐ ๋ชจ๋ธ๋ง ๋๋ค.
- ๋ณผํ์ด ์์ง์ผ ๋ ๋ชจ๋ ํํธ๊ฐ ๋์์ ์์ง์ฌ์ผ ํ๋ค. (๊ฒฐํฉ ์ํ)
- ๊ทธ๋ฆฌ๊ธฐ ๋ชจ๋์์๋ ๋ณผํ ์ด์ด ์ข ์ด์ ๋ง๋ฟ์ ์๋ค. ๋ณผํ ์ด์ด ๊บผ๋ด์ ธ ์์ง ์์ ์ํ์์๋ ๊ทธ๋ฆผ์ด ๊ทธ๋ ค์ง์ง ์๋๋ค.
- ๊ทธ๋ฆฌ๊ธฐ ๋ชจ๋์์๋ ์ข ์ด๊ฐ ํ ๋์ ๋ณด์ด๊ฒ๋ ์์ ์ด ์ฌ๋ผ๊ฐ๋ค.
- ๊ด์ฐฐ ๋ชจ๋์ ๋ถํด ๋ชจ๋๋ ๋ณผํ์ด ์ ๋ณด์ด๋๋ก ์์ ์ด ํ๋๋๋ค. ๋ถํด ๋ชจ๋๋ ๋ถํด ์ ๋๋ฉ์ด์ ์ ์ ๊ณตํ๋ค.
- ๊ทธ๋ฆผํ์ผ ์ ์ฅ์ ํ๋ฆฐํฐ๊ฐ ์ข ์ด๋ฅผ ์ถ๋ ฅํ๋ ๋ฏํ ์ ๋๋ฉ์ด์ ์ ๋ณด์ฌ์ค๋ค.
- ์ ์ฒดํ๋ฉด ์ํ์์ F11์ ํ ๋ฒ ๋ ๋๋ฅด๋ฉด ์๋ ํฌ๊ธฐ๋ก ๋์์จ๋ค.
- ๊ทธ๋ฆฌ๊ธฐ ๋ชจ๋์์๋ ์นด๋ฉ๋ผ ์์ ์ ๊ณ ์ ๋๊ณ ๋ณผํ์ด ๋ง์ฐ์ค์ ์์ง์์ ๋ฐ๋ผํ๋ค.
- ๋ง์ฐ์ค์ ์์ง์์ ๋ณผํ๊ณผ ํจ๊ป ๋ชจ๋ธ๋ง ๋๋ ์ข ์ด์ ํ์ ํํ๋ก ๊ทธ๋ ค์ง๋ค.
- ๋ณผํ ์์ ๊ฒ์ , ๋นจ๊ฐ, ํ๋ 3์ข ๋ฅ๊ฐ ์๋ค.
- ๋ณผํ ์ด๋ฏธ์ง๋ฅผ Blender์ ์ฌ๋ ค ๋๊ณ Cylinder์ ์ด์ฉํด ๋ชจ์์ ๋ง๋ฆ
- ๋ณผํ์ ๊ฐ ๋ถํ ๋ณ๋ก ๋ฐ๋ก ๋ชจ๋ธ๋งํ์ฌ OpenGL ํ๋ก๊ทธ๋จ ์์์ ๊ฐ๋ณ์ ์ผ๋ก ์กฐ์ ๊ฐ๋ฅํ๊ฒ ํจ
- ์ค๋งํธํฐ ์นด๋ฉ๋ผ๋ก ๋ณผํ์ ์ดฌ์ํ๊ณ ๋ก๊ณ ๋ถ๋ถ์ ํ ์ค์ฒ๋ฅผ ๋งคํ
- ๋ก๊ณ ๊ฐ ์ ๋ช ํ๊ฒ ๋ณด์ด๊ฒ ํ๊ธฐ ์ํด UV ๋งต์์ ๋ก๊ณ ๋ถ๋ถ๋ง ํ๋ํ์ฌ ์๋์ ์ผ๋ก ๋์ ํด์๋์ ํ ์ค์ฒ๊ฐ ๋ค์ด๊ฐ๊ฒ ํจ
๊ฐ๊ฐ์ .obj
ํ์ผ์ ๋ถ๋ฌ์ ๊ฐ๋ณ์ ์ผ๋ก ์์ ์
ํ ํ
์ค์ฒ๋ ๋ณผํ ๋ชธํต๋ง ์ ์ฉ
struct Vec2f {
float x;
float y;
};
struct Vec3f {
float x;
float y;
float z;
};
class Object {
public:
Object(const std::string& filename);
~Object() = default;
void render() const;
private:
std::string name;
std::vector<Vec3f> vertices; // v
std::vector<Vec2f> textures; // vt
std::vector<Vec3f> normals; // vn
std::vector<std::size_t> vertex_indices; // f
std::vector<std::size_t> texture_indices; // f
std::vector<std::size_t> normal_indices; // f
};
void Object::render() const {
glBegin(GL_TRIANGLES);
for (std::size_t n = 0; n < vertex_indices.size(); n += 3) {
glTexCoord2f(textures[texture_indices[n] - 1].x, textures[texture_indices[n] -1].y);
glNormal3f(normals[normal_indices[n] - 1].x, normals[normal_indices[n] - 1].y, normals[normal_indices[n] - 1].z);
glVertex3f(vertices[vertex_indices[n] - 1].x, vertices[vertex_indices[n] - 1].y, vertices[vertex_indices[n] - 1].z);
glTexCoord2f(textures[texture_indices[n + 1] - 1].x, textures[texture_indices[n + 1] - 1].y);
glNormal3f(normals[normal_indices[n + 1] - 1].x, normals[normal_indices[n + 1] - 1].y, normals[normal_indices[n + 1] - 1].z);
glVertex3f(vertices[vertex_indices[n + 1] - 1].x, vertices[vertex_indices[n + 1] - 1].y, vertices[vertex_indices[n + 1] - 1].z);
glTexCoord2f(textures[texture_indices[n + 2] - 1].x, textures[texture_indices[n + 2] - 1].y);
glNormal3f(normals[normal_indices[n + 2] - 1].x, normals[normal_indices[n + 2] - 1].y, normals[normal_indices[n + 2] - 1].z);
glVertex3f(vertices[vertex_indices[n + 2] - 1].x, vertices[vertex_indices[n + 2] - 1].y, vertices[vertex_indices[n + 2] - 1].z);
}
glEnd();
}
์ค์ต์๊ฐ์ ์ ๊ณต๋ฐ์ ObjParser.h
์ฝ๋๋ฅผ ์ฐธ๊ณ ํด ๊ฐ์ฒด์งํฅ์ ์ธ Object Parser์ Drawer๋ฅผ ์ฝ๋๋ฅผ ์์ฑ
class Bitmap {
public:
Bitmap() = delete;
Bitmap(int width, int height);
Bitmap(const std::string& filename);
~Bitmap();
void fill_pixel(int x, int y, const Color& color);
int get_channels() const;
int get_width() const;
int get_height() const;
unsigned char* get_pixels() const;
void save(const std::string& out_filename, const
std::string& ref_filename) const;
private:
int width;
int height;
int channels;
unsigned char* pixels;
};
Bitmap::Bitmap(const std::string& filename) {
FILE* fp = fopen(filename.c_str(), "rb");
if (!fp) {
perror("File opening failed\n");
}
unsigned char header[54]; // bitmap header
if (fread(header, sizeof(unsigned char), 54, fp) != 54 || header[0] != 'B' || header[1] != 'M') {
perror("Invalid BMP file\n");
fclose(fp);
}
unsigned int offset = *(unsigned int*) &(header[0x0A]);
width = *(int*) &(header[0x12]);
height = *(int*) &(header[0x16]);
unsigned int size = *(unsigned int*) &(header[0x22]); // image size
if (size == width * height) {
channels = 1;
} else {
channels = 3;
}
size = width * height * channels;
if (offset == 0) {
offset = 54; // The BMP header is done that way
}
pixels = new unsigned char[size]; // image pixel data
fread(pixels, sizeof(unsigned char), size, fp);
fclose(fp);
if (channels == 3) { // BGR order -> RGB order
reverse_each_pixel(width, height, pixels);
}
}
์ค์ต์๊ฐ์ ์ ๊ณต๋ฐ์ bmpfunc.cpp
์ฝ๋๋ฅผ ์ฐธ๊ณ ํด ๊ฐ์ฒด์งํฅ์ ์ธ Bitmap Parser๋ฅผ ์ฝ๋๋ฅผ ์์ฑํจ
Bitmap::Bitmap(int width, int height)
: width(width), height(height), channels(3) {
int size = width * height * 3;
pixels = new unsigned char[size]; // image pixel data
std::fill(pixels, pixels + size, 0xff);
}
ํฐ ์ ์ข
์ด ํ
์ค์ฒ๋ฅผ ์ํ Bitmap(int width, int height)
class MyPen {
public:
MyPen() = default;
~MyPen() = default;
const Color& get_line_color() const;
bool is_clicked() const;
bool is_drawing_mode() const;
void move(float x, float y);
void disable_drawing_mode();
void enable_drawing_mode();
void perform_click();
void perform_draw_line(Paper* paper, int x1,
int y1, int x2, int y2);
void render(float disassembled = 0.0f) const;
void set_line_color(const Color& color);
private:
// ...
float x = 0.0f;
float y = 0.0f;
bool clicked = false;
bool drawing = false;
Color line_color = { 0.0f, 0.0f, 0.0f };
};
void MyPen::render(float animated) const {
if (drawing) {
glTranslatef(x, 1.89f, y);
glRotatef(-90.0f, 0.0f, 0.0f, 1.0f);
} else {
glTranslatef(x, 0.5f, y);
}
glTranslatef(-1.5f * animated, 0.0f, 0.0f);
pen_barrel.render();
pen_clip.render();
pen_grip.render();
if (!clicked) {
glTranslatef(-0.1f, 0.0f, 0.0f);
}
glPushMatrix();
glTranslatef(-0.5f * animated, 0.0f, 0.0f);
pen_cap.render();
glPopMatrix();
glTranslatef(1.0f * animated, 0.0f, 0.0f);
pen_reservoir.render();
pen_socket.render();
glTranslatef(0.75f * animated, 0.0f, 0.0f);
pen_spring.render();
glColor3f(line_color.red, line_color.green, line_color.blue);
glPushMatrix();
glTranslatef(1.88f, 0.0f, 0.0f);
glutSolidSphere(0.004, 10, 10); // ball
glPopMatrix();
if (!clicked) {
glTranslatef(0.1f, 0.0f, 0.0f);
}
glTranslatef(0.75f * animated, 0.0f, 0.0f);
pen_tip.render();
}
float disassembled
๋ ๋ณผํ ๋ถํด ์ ๋๋ฉ์ด์
์ ๋ณด์ฌ์ค ๋ ์ฌ์ฉํ๋ ๊ณ์
์กฐ๋ฆฝ ์ํ์ผ ๋๋ disassembled=-1.0
๋ณผํ ์์ ๋ฐ๋ผ ๋ณผํ ์ด ๋์ ์์ด ๋ฌ๋ผ์ง๋๋ก glColor3f
์ glutSolidSphere
์ผ๋ก ๊ตฌํ
- ์นด๋ฉ๋ผ 1์ ๋๋ฅด๋ฉด ์นด๋ฉ๋ผ ์์ ์ด ์ฌ๋ผ๊ฐ๋ฉด์ ์ข ์ด๊ฐ ํ ๋์ ๋ณด์
- ํค๋ณด๋ ์คํ์ด์ค๋ฐ๋ฅผ ๋๋ฅด๋ฉด ํจ๊ณผ์๊ณผ ํจ๊ป ํ์ด์ด ํ์ด๋์ค๋ฉด์ ๋ง์ฐ์ค๋ฅผ ๋๋๊ทธ ํ๋๋๋ก ์ ์ด ๊ทธ๋ ค์ง (Bresenham ์๊ณ ๋ฆฌ์ฆ ์ด์ฉ)
- ์ฐ์ธก ์๋จ์ ์์ ํด๋ฆญํ๋ฉด ๋ณผํ ์์ด ๋ฐ๋
- ๋ง์ฐ์ค ์ฐํด๋ฆญ > Clear๋ก ๊ทธ๋ฆผ์ ์ง์ธ ์ ์์
void motion_cb(int x, int y) {
float pen_x = (x * paper->get_width() / window_width) - (paper->get_width() / 2);
float pen_y = (y * paper->get_height() / window_height) - (paper->get_height() / 2);
mypen->move(pen_x, pen_y);
int paper_x = x * paper->get_image_width() / window_width;
int paper_y = paper->get_image_height() - (y * paper->get_image_height() /
window_height);
if (prev_paper_x >= 0 && prev_paper_y >= 0 && mypen->is_clicked() && mypen->is_drawing_mode()) {
mypen->perform_draw_line(paper, paper_x, paper_y, prev_paper_x, prev_paper_y);
paper->update_texture();
}
prev_paper_x = paper_x;
prev_paper_y = paper_y;
}
void Bitmap::fill_pixel(int x, int y, const Color& color) {
pixels[channels * (y * width + x)] = color.red * 255;
pixels[channels * (y * width + x) + 1] = color.green * 255;
pixels[channels * (y * width + x) + 2] = color.blue * 255;
}
void Paper::update_texture() const {
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, 3, image->get_width(), image->get_height(), 0,
GL_RGB, GL_UNSIGNED_BYTE, image->get_pixels());
}
void pick(int x, int y) {
int viewport_width = 160;
int viewport_height = 60;
unsigned int select_buf[256];
glSelectBuffer(256, select_buf);
int viewport[4] = { window_width - viewport_width, 0, viewport_width, viewport_height }; // (x, y, width, height)
glRenderMode(GL_SELECT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix(x, y, 0.1, 0.1, viewport);
glOrtho(-viewport_width / 2, viewport_width / 2, -viewport_height / 2, viewport_height / 2, -50.0, 50.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
draw_color_spheres();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glFlush();
int hits = glRenderMode(GL_RENDER);
if (hits >= 1) {
unsigned int idx = 0;
unsigned int selected_z = -1; // max value of unsigned int(overflow)
sphere_selected = -1;
for (int i = 1; i <= hits; i += 1) {
unsigned int name_count = select_buf[idx]; // always 1
unsigned int z_min = select_buf[idx + 1];
unsigned int z_max = select_buf[idx + 2];
unsigned int name = select_buf[idx + 3];
idx += name_count + 3;
if (selected_z > z_max) {
selected_z = z_max;
sphere_selected = name;
}
}
}
}
// mini viewport
int viewport_width = 160;
int viewport_height = 60;
glViewport(window_width - viewport_width,
window_height - viewport_height, viewport_width,
viewport_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-viewport_width / 2, viewport_width / 2, -viewport_height / 2, viewport_height / 2, -50.0, 50.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_LIGHTING);
draw_color_spheres();
glEnable(GL_LIGHTING);
Multi-viewport๋ฅผ ์ด์ฉํด ์์ ์ ํ ์์ ๊ทธ๋ ธ๊ธฐ ๋๋ฌธ์, glGetIntegerv(GL_VIEWPORT, viewport)
๋์ viewport ํฌ๊ธฐ๋ฅผ ๋ฐ๋ก ์ง์ ํด์ผ ํจ
#include <mmsystem.h>
mypen->perform_click();
PlaySound(TEXT("res/click.wav"), NULL, SND_ASYNC);
ํค๋ณด๋ 2๋ฅผ ๋๋ฅด๋ฉด ์นด๋ฉ๋ผ๊ฐ ํ๋๋๊ณ ์นด๋ฉ๋ผ๋ฅผ ์ด๋ํ๋ฉฐ ๋ณผํ์ ๊ด์ฐฐํ ์ ์์
๋ณผํ ์์ด ๋ฐ๋๋ฉด ๋ณผํ ๋ชธํต์๋ ๋ฐ๋
void MyPen::Barrel::set_color(const Color& color) {
int width = image->get_width();
int height = image->get_height();
int channels = image->get_channels();
unsigned char* pixels = new unsigned char[width * height * channels];
std::memcpy(pixels, image->get_pixels(), width * height * channels);
for (int x = 0; x < width; x += 1) {
for (int y = 0; y < height; y += 1) {
if (pixels[channels * (y * width + x)] == 0 && pixels[channels * (y * width + x) + 1] == 0 && pixels[channels * (y * width + x) + 2] == 0) {
pixels[channels * (y * width + x)] = color.red * 120;
pixels[channels * (y * width + x) + 1] = color.green * 120;
pixels[channels * (y * width + x) + 2] = color.blue * 120;
}
}
}
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
delete[] pixels;
}
๋ณผํ ๋ชธํต ํ ์ค์ฒ์ ๊ฒ์ ๋ถ๋ถ์ ์ํ๋ ์์ผ๋ก ์นํํ๋ฉด ๋ณผํ ๋ชธํต์ ์์ ๋ฐ๊ฟ ์ ์์
ํ๋์ ํ ์ค์ฒ๋ก ๋ค์ํ ๋ณผํ ๋ชธํต ์์ ํํ ๊ฐ๋ฅ
void time_cb(int value) {
if (disassembling_animate >= 0.0f && disassembling_animate < 1.5f) {
disassembling_animate += 0.01f;
if (disassembling_animate >= 1.5f) {
disassembling_animate = 1.5f;
}
}
glutTimerFunc(interval, time_cb, NULL);
}
ํค๋ณด๋ 3๋ฅผ ๋๋ฅด๋ฉด ์นด๋ฉ๋ผ๊ฐ ํ๋๋๊ณ ๋ณผํ์ด ๋ถํด๋๋ ์ ๋๋ฉ์ด์ ์ด ์ฐ์ถ
F2๋ฅผ ๋๋ฅด๋ฉด ํ๋ฆฐํฐ๋ก ์ข ์ด๋ฅผ ์ธ์ํ๋ ๋ฏํ ์ ๋๋ฉ์ด์ ์ด ๋ณด์ฌ์ง๋ฉฐ ํ์ผ์ด ์ ์ฅ๋จ
// ๋ค๋ฅธ .bmp ํ์ผ ํค๋๋ฅผ ๋ณต์ฌํด ์๋ก์ด BMP ํ์ผ์ ๋ง๋ญ๋๋ค.
void Bitmap::save(const std::string& out_filename, const std::string& ref_filename) const {
FILE* ifp = fopen(ref_filename.c_str(), "rb");
if (!ifp) {
perror("File opening failed\n");
return;
}
fseek(ifp, 10, SEEK_SET);
int ref_offset;
fread(&ref_offset, sizeof(int), 1, ifp);
fseek(ifp, 18, SEEK_SET);
int ref_width;
int ref_height;
fread(&ref_width, sizeof(int), 1, ifp);
fread(&ref_height, sizeof(int), 1, ifp);
fseek(ifp, 0, SEEK_SET);
unsigned char* ref_header = new unsigned char[ref_offset];
fread(ref_header, sizeof(unsigned char), ref_offset, ifp);
fclose(ifp);
FILE* ofp = fopen(out_filename.c_str(), "wb");
if (!ofp) {
perror("File opening failed\n");
delete[] ref_header;
return;
}
fwrite(ref_header, sizeof(unsigned char), ref_offset, ofp);
delete[] ref_header;
int size = channels * width * height;
unsigned char* out_pixels = new unsigned char[size];
std::copy(pixels, pixels + size, out_pixels);
if (channels == 3) {
reverse_each_pixel(width, height, out_pixels);
}
fwrite(out_pixels, sizeof(unsigned char), size, ofp);
delete[] out_pixels;
fclose(ofp);
}
์ค์ต์๊ฐ์ ์ ๊ณต๋ฐ์ bmpfunc.cpp
์ฝ๋๋ฅผ ์ฐธ๊ณ ํด ์ข
์ด์ ์ ์ฉ๋ ํ
์ค์ฒ๋ฅผ BMP ํ์ผ๋ก ์ ์ฅํ๋ ๊ธฐ๋ฅ ๊ตฌํ
// main viewport
glViewport(0, 0, window_width, window_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (printing_animate < 0.0f) {
gluPerspective(45.0, (double) window_width / window_height, 0.1, 100.0);
} else {
gluPerspective(45.0, (double) window_width / window_height, printing_animate, 50.0);
}
Z near๋ฅผ ์กฐ์ ํด ํ๋ฆฐํธ ์ ๋๋ฉ์ด์ ํจ๊ณผ๋ฅผ ๊ตฌํ
void toggle_fullscreen() {
fullscreen = !fullscreen;
if (fullscreen) {
prev_window_width = glutGet(GLUT_WINDOW_WIDTH);
prev_window_height = glutGet(GLUT_WINDOW_HEIGHT);
glutFullScreen();
} else {
glutReshapeWindow(prev_window_width, prev_window_height);
}
}
void special_keyboard_cb(int key, int x, int y) {
switch (key) {
case GLUT_KEY_F11:
std::cout << "Toggle fullscreen\n";
toggle_fullscreen();
break;
}
}
glutFullScreen์ ์ด์ฉํด ํ๋ฉด์ ์ ์ฒดํ๋ฉด ๋ชจ๋๋ก ๋ณ๊ฒฝ
์ด์ ์๋์ฐ ํฌ๊ธฐ๋ฅผ ์ ์ฅํด๋๊ณ F11๋ฅผ ํ ๋ฒ ๋ ๋๋ฅด๋ฉด ์๋ ํฌ๊ธฐ๋ก ๋๋์์ด
#include <Windows.h>
HDC hdc; // handle display context
์ ์ญ๋ณ์ ์ ์ธ
void init_font(HDC& hdc) {
hdc = wglGetCurrentDC();
HFONT font = CreateFont(24, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0, HANGUL_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, TEXT("๋ง์ ๊ณ ๋"));
SelectObject(hdc, font);
}
init
ํจ์์์ ์ด๊ธฐํ
void draw_text(const HDC& hdc, const std::wstring& text) {
glDisable(GL_LIGHTING);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0.0, 10.0, 10.0, 0.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glRasterPos3f(0.5f, 1.0f, 0.0f);
for (int i = 0; i < text.size(); i += 1) {
int list = glGenLists(1);
wglUseFontBitmapsW(hdc, text[i], 1, list);
glCallList(list);
glDeleteLists(list, 1);
}
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glEnable(GL_LIGHTING);
}
draw_string
์์ ๊ธ์๋ฅผ ๋นํธ๋งต์ผ๋ก ๋ณํํ๊ณ glCallList
๋ก ํ๋ฉด์ ๊ทธ๋ฆผ
CubeMap::CubeMap(float size)
: size(size) {
glGenTextures(1, &texture);
glEnable(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
Bitmap image_px{ "res/cubemap/px.bmp" };
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, image_px.get_width(), image_px.get_height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image_px.get_pixels());
Bitmap image_nx{ "res/cubemap/nx.bmp" };
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, image_nx.get_width(), image_nx.get_height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image_nx.get_pixels());
Bitmap image_py{ "res/cubemap/py.bmp" };
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, image_py.get_width(), image_py.get_height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image_py.get_pixels());
Bitmap image_ny{ "res/cubemap/ny.bmp" };
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, image_ny.get_width(), image_ny.get_height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image_ny.get_pixels());
Bitmap image_pz{ "res/cubemap/pz.bmp" };
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, image_pz.get_width(), image_pz.get_height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image_pz.get_pixels());
Bitmap image_nz{ "res/cubemap/nz.bmp" };
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, image_nz.get_width(), image_nz.get_height(), 0, GL_RGB, GL_UNSIGNED_BYTE, image_nz.get_pixels());
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
}