glOrtho
: 2 डी खेल, करीब वस्तुओं और अब तक एक ही आकार के दिखाई देते हैं:
glFrustrum
: 3 डी की तरह अधिक वास्तविक जीवन, समान वस्तुओं और दूर दिखाई छोटे:
कोड
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
static int ortho = 0;
static void display(void) {
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
if (ortho) {
} else {
/* This only rotates and translates the world around to look like the camera moved. */
gluLookAt(0.0, 0.0, -3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
glColor3f(1.0f, 1.0f, 1.0f);
glutWireCube(2);
glFlush();
}
static void reshape(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (ortho) {
glOrtho(-2.0, 2.0, -2.0, 2.0, -1.5, 1.5);
} else {
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
}
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
if (argc > 1) {
ortho = 1;
}
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return EXIT_SUCCESS;
}
स्कीमा
ऑर्थो: कैमरा एक विमान है, दिखाई मात्रा एक आयत:
Frustrum:
: कैमरा एक बिंदु, दिखाई मात्रा एक पिरामिड का एक टुकड़ा है
Image source।
पैरामीटर
हम हमेशा साथ + y ऊपर की तरफ -z लिए + z से देख रहे हैं:
glOrtho(left, right, bottom, top, near, far)
left
: न्यूनतम x
हम
right
देखें: अधिकतम x
हम देखते हैं
bottom
: minim उम y
हम देखते हैं
top
: अधिकतम y
हम
-near
देखें: न्यूनतम z
हम देखते हैं। हां, यह -1
बार near
है। तो एक नकारात्मक इनपुट का अर्थ सकारात्मक z
है।
-far
: अधिकतम z
हम देखते हैं। नकारात्मक भी।
स्कीमा:
Image source।
यह कैसे, ओपन हमेशा "का उपयोग करता है" हुड
तहत काम करता है अंत में:
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
अगर हम न glOrtho
है और न ही glFrustrum
उपयोग करते हैं, कि हम क्या मिलता है।
glOrtho
और glFrustrum
सिर्फ रैखिक परिवर्तनों हैं (उर्फ आव्यूह गुणन) ऐसी है कि:
glOrtho
: डिफ़ॉल्ट घन
glFrustrum
में एक दिया 3 डी आयत लेता है: डिफ़ॉल्ट घन में एक दिया पिरामिड खंड लेता है
यह परिवर्तन तब सभी vertexes लिए आवेदन किया है। यह मैं 2 डी में क्या मतलब है:
Image source।
परिवर्तन के बाद अंतिम चरण सरल है:
- घन (culling) के बाहर किसी भी अंक निकालने के लिए: बस यह सुनिश्चित करें कि
x
, y
और z
[-1, +1]
- में हैं
z
घटक ध्यान न दें और केवल ले x
और y
, जिसे अब 2 डी स्क्रीन
के साथ रखा जा सकता है, z
को अनदेखा किया गया है, इसलिए आप हमेशा 0
का उपयोग कर सकते हैं।
एक कारण है कि आप z != 0
का उपयोग करना चाहते हैं, sprites को गहराई बफर के साथ पृष्ठभूमि छुपाएं।
डेप्रिकेशन
glOrtho
OpenGL 4.5 के रूप में हटा दिया गया है: संगतता प्रोफाइल 12.1। "फिक्स्ड-फंक्शन वर्टेक्स ट्रांसफरेशन" लाल रंग में है।
तो उत्पादन के लिए इसका उपयोग न करें। किसी भी मामले में, समझना कुछ ओपनजीएल अंतर्दृष्टि प्राप्त करने का एक अच्छा तरीका है।
आधुनिक ओपनजीएल 4 प्रोग्राम सीपीयू पर रूपांतरण मैट्रिक्स (जो छोटा है) की गणना करते हैं, और उसके बाद मैट्रिक्स और सभी बिंदुओं को ओपनजीएल में परिवर्तित किया जाता है, जो अलग-अलग बिंदुओं के लिए हजारों मैट्रिक्स गुणाओं को वास्तव में समानांतर में कर सकता है ।
मैन्युअल रूप से vertex shaders लिखा गया है, तो ओपनजीएल छायांकन भाषा के सुविधाजनक वेक्टर डेटा प्रकारों के साथ आमतौर पर गुणा को स्पष्ट रूप से करें।
चूंकि आप स्पष्ट रूप से शेडर लिखते हैं, इससे आपको अपनी आवश्यकताओं के लिए एल्गोरिदम को ट्विक करने की अनुमति मिलती है। इस तरह की लचीलापन अधिक आधुनिक जीपीयू की एक प्रमुख विशेषता है, जो पुराने इनपुट के साथ कुछ इनपुट पैरामीटर के साथ एक निश्चित एल्गोरिदम था, अब मनमानी गणना कर सकते हैं।यह भी देखें: https://stackoverflow.com/a/36211337/895245
एक स्पष्ट GLfloat transform[]
के साथ यह कुछ इस तरह दिखेगा:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "common.h"
static const GLuint WIDTH = 800;
static const GLuint HEIGHT = 600;
/* ourColor is passed on to the fragment shader. */
static const GLchar* vertex_shader_source =
"#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"layout (location = 1) in vec3 color;\n"
"out vec3 ourColor;\n"
"uniform mat4 transform;\n"
"void main() {\n"
" gl_Position = transform * vec4(position, 1.0f);\n"
" ourColor = color;\n"
"}\n";
static const GLchar* fragment_shader_source =
"#version 330 core\n"
"in vec3 ourColor;\n"
"out vec4 color;\n"
"void main() {\n"
" color = vec4(ourColor, 1.0f);\n"
"}\n";
static GLfloat vertices[] = {
/* Positions Colors */
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f
};
int main(void) {
GLint shader_program;
GLint transform_location;
GLuint vbo;
GLuint vao;
GLFWwindow* window;
double time;
glfwInit();
window = glfwCreateWindow(WIDTH, HEIGHT, __FILE__, NULL, NULL);
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
glewInit();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glViewport(0, 0, WIDTH, HEIGHT);
shader_program = common_get_shader_program(vertex_shader_source, fragment_shader_source);
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
/* Position attribute */
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
/* Color attribute */
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader_program);
transform_location = glGetUniformLocation(shader_program, "transform");
/* THIS is just a dummy transform. */
GLfloat transform[] = {
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f,
};
time = glfwGetTime();
transform[0] = 2.0f * sin(time);
transform[5] = 2.0f * cos(time);
glUniformMatrix4fv(transform_location, 1, GL_FALSE, transform);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
glfwTerminate();
return EXIT_SUCCESS;
}
जेनरेट किए गए उत्पादन: http://imgur.com/QVW14Gu
glOrtho
के लिए मैट्रिक्स वास्तव में सरल है, केवल स्केलिंग और अनुवाद से बना है:
scalex, 0, 0, translatex,
0, scaley, 0, translatey,
0, 0, scalez, translatez,
0, 0, 0, 1
जैसा कि OpenGL 2 docs में उल्लिखित है।
glFrustum
matrix हाथ से गणना करना बहुत कठिन नहीं है, लेकिन परेशान होना शुरू हो जाता है। ध्यान दें कि कैसे छिन्नक केवल पर स्केलिंग और glOrtho
तरह अनुवाद, अधिक जानकारी के साथ नहीं किया जा सकता: https://gamedev.stackexchange.com/a/118848/25171
GLM ओपन सी ++ गणित पुस्तकालय ऐसे मैट्रिक्स की गणना के लिए एक लोकप्रिय पसंद है। http://glm.g-truc.net/0.9.2/api/a00245.html दस्तावेज ortho
और frustum
संचालन दोनों दस्तावेज।
[यह] (https://www.youtube.com/watch?v=8ryJMO6rBT4) वीडियो ने मुझे बहुत मदद की। – ViniciusArruda