25 Ağustos 2020 Salı

OpenGL

OpenGL Neden Ortaya Çıktı
Açıklaması şöyle.
Early on, you had to explicitly code your game for each graphics card you wanted to support: Hercules, CGA, Tandy, EGA, VGA. You had to know how to put the card into graphics mode and you had to know the memory layout, palette, and so on. You had to figure out how to avoid flicker and how to prevent tearing. You had to write your own line drawing and fill routines, and if you wanted 3-D, you had to know how to project it onto a 2-D screen, how to remove hidden lines and so on.

Later when graphics cards started gaining accelerated functionality, SGI created the IrisGL API, which later became OpenGL, in order to simplify CAD (computer aided drafting/design) software development for those graphics cards by providing a standard API that video hardware manufacturers could support and developers could design their software against. OpenGL provided access to underlying hardware features, and if a feature did not exist on the hardware, OpenGL provided a software implementation.
IrisGL ve OpenGL saatin tersine yönü kullanır. Açıklaması şöyle
OpenGL is an open source version of the former proprietary IRIS GL library offered by SGI for their graphics workstation. This was done as a move to get a wider acceptance than the the standard PHIGS. The move worked out fine, as IRIS GL was a way lower, more hardware orientated approach, better fitting the less capable nature of back then machines.

Using counterclockwise sequence as mark for orientation was at that time already standard.Both system (IRIS GL and PHIGS) use CCW as default. IRIS GL allows to specify clockwise direction as a system wide setting via pfBboardAxis(). This is offered as a support for customer specific systems with a data set made on assuming CW orientation.
OpenGL'den önce DOS dünyasında çizilecek şeyler direkt bellek alanına yazılırdır. Açıklaması şöyle.
 Early graphics cards had virtually no callable code associated with them at all, the concept of "drivers" had not quite become a reality yet. There was the concept of a Video BIOS, which were extensions to the INT 10h BIOS video services, that were effectively limited to initialization and switching video modes.

Instead, graphics cards, at least in DOS land, all had memory mapped display RAM, and extensive documentation was available about exactly how setting various bits in display RAM would affect the pixels that appeared on the screen. There were no drawing APIs to call, if you wanted something to appear on the screen (whether it be a pixel, a character, a line, a circle, a sprite, etc) you would write the code to move the bytes into the right places in display RAM. Entire books were written about how to write efficient code to draw graphics.
MacOS İşletim Sistemi
Açıklaması şöyle.
... OpenGL was deprecated in macOS Mojave 10.14 in the favour of Metal, Apple's proprietary low-level graphics API.
Graphics Pipeline
Pipeline şu şekilde çalışıyor.
Application Stage > Geometry Stage -> Rasterizer Stage
Biz yazılım olarak sadece Application Stage ile ilgileniyoruz. Bu aşamada ışık kaynağı, kamera, texture gibi şeyleri programlıyoruz.

Header Dosyaları
Şu satır dahil edilir
#include <GL/gl.h>
HitTest
Point in Polygon aka hit test sorusunda Point in polygon kavramı çok iyi açıklanmış.

Döndürme
Buradaki soruda 2D olan bir cisme 3D efekt vermek için Rotation matrix kullanımından bahsediyor. Bir cismi döndürmek için kullanılan formül aşağıda.

Quaternion ile de döndürme yapılabildiği söyleniyor.

Buradaki sorunun OpenGL ile alakası yok ancak bir vektörü 3D nasıl döndüreceğimiz gösterdiği için ekliyorum.

FrameBuffer
FrameBuffer Object (FBO) stateleri tutan bir nesne.

glFramebufferTexture2D()
glFramebufferRenderbuffer()
glDrawBuffers()
glReadBuffer()

gibi metodlar seçili FBO'daki veriyi kullanarak işlem yapar. FBO seçmek için şöyle yapılır. İkinci parametre FBO numarasıdır.
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glBegin metodu
Dikdörtgen çizmek için şöyle yaparız
glBegin(GL_POLYGON);
        glVertex2i(x,h);
        glVertex2i(x+w,h);
        glVertex2i(x+w,y);
        glVertex2i(x,y);
glEnd();
glBufferData
Belirtilen noktaları ekran çizer.

Örnek
Üçgen çizmek için şöyle yaparız.
float firstTriangle[] = {
  -0.9f, -0.5f, 0.0f,  // left
  -0.0f, -0.5f, 0.0f,  // right
  -0.45f, 0.5f, 0.0f,  // top
};

glBufferData(GL_ARRAY_BUFFER, sizeof(firstTriangle), firstTriangle, GL_STATIC_DRAW);
glEnable metodu
Bu metodun tersini glDisable() yapar.
Örnek
Şöyle yaparız.
glEnable(GL_DEPTH_TEST);
Örnek
Şöyle yaparız.
glEnable(GL_TEXTURE_2D);

glEnable(GL_BLEND);

glEnable(GL_LIGHTING);
glDrawPixels metodu
Açıklaması şöyle. Belirtilen bellekteki resmi çizer.
width x height pixels are read from memory, starting at location data. By default, these pixels are taken from adjacent memory locations, except that after all width pixels are read, the read pointer is advanced to the next four-byte boundary. The four-byte row alignment is specified by glPixelStore with argument GL_UNPACK_ALIGNMENT, and it can be set to one, two, four, or eight bytes.
Örnek
Elimizde şöyle bir kod olsun
int _w = 300;
int _h = 300;
GLubyte ***_data = ...;
Şöyle yaparız.
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glDrawPixels(_w, _h, GL_RGB, GL_UNSIGNED_BYTE, _data);
glFrontFace metodu
İmzası şöyle
void glFrontFace(GLenum mode)

mode
    Specifies the orientation of front-facing polygons. GL_CW
    and GL_CCW are accepted. The initial value is GL_CCW.

glGenBuffers metodu
Polygon çizmek için bir buffer yaratır. glGenBuffers() ile yaratılan bellek glDeleteBuffers() ile silinir.
Örnek
Elimizde şöyle bir kod olsun
template<size_t N>
class BufferObjects
{
  std::array<GLuint, N>  buffer;
  bool                   valid;
  ...

};
Şöyle yaparız
template<size_t N>
BufferObjects<N>::~BufferObjects()
{
  if (valid) {
    glDeleteBuffers(N, buffer.data());
  }
}

template<size_t N>
void BufferObjects::reset()
{
  if (!valid) {
    glGenBuffers(N, buffer.data());
    valid = true;
  }
}
Örnek
Polygon çizmek için bir buffer şöyle yaratılır.
glGenBuffers(1, &verticesbuffer);
Daha sonra buffer bind edilir. Bu niye yapılıyor bilmiyorum.
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, verticesbuffer);
Buffer doldurulur.
std::vector<float> vertices;
// ...add vertices with push_back()...
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
             vertices.size()*sizeof(float),&vertices[0],GL_STATIC_DRAW);
Sonra çizilir.

glVertexPointer metodu
2 veya 3 boyutlu nokta belirtir.
glVertexPointer(3, GL_FLOAT, sizeof(3dPoint), Mesh);
veya
glVertexPointer(2, GL_FLOAT, sizeof(2dPoint), Mesh);

Shader
glCreateShader metodu
Vertex shader şöyle yaratılır.
GLuint vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource metodu
Şöyle yaparız.
char *vs_source =
    "attribute vec3 pos;\n"
    "void main() {\n"
    "   gl_Position = vec4(pos,1.0);\n"
    "}\n";
glShaderSource(vertexShader, 1, (const GLchar**)&vs_source, NULL);

Hiç yorum yok:

Yorum Gönder