在 OpenGL 中转换后获取顶点?
Obtain a vertex after a transform in OpenGL?
我有如下一段代码:
#include <gl/glut.h>
#include <stdio.h>
GLfloat xf, yf, win;
GLint view_w, view_h;
//auxiliary vector
GLfloat aux[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
GLfloat vertices[768] = { 0.0 };
//count for aux vector
int count = 0;
//Meant to be used for drawing different shapes, store the number of vertecies for each primitive
int primitives[64] = {};
//Index
int vIndex = 0;
int pIndex = 0;
bool flag = false;
//Dedraws the scene using the vertices vector
void Redisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
int j = 0;
int k;
for (int i = 0; i < pIndex; i++)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_TRIANGLES);
k = j;
for(; j < k + 2*primitives[i];j+=2)
glVertex2f(vertices[j], vertices[j + 1]);
glEnd();
glFlush();
}
}
//Store vertices in the vertices vector
void storePrimitive(GLfloat *vector, int nVertex)
{
for (int i = 0; i < nVertex * 2; i++)
vertices[vIndex++] = vector[i];
primitives[pIndex++] = nVertex;
}
//Draw scene
void draw(void)
{
if (count > 5)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//If flag is true, apply a transform
if (flag)
{
glPushMatrix();
glScalef(2, 2, 1);
}
glBegin(GL_TRIANGLES);
glVertex2f(aux[0], aux[1]);
glVertex2f(aux[2], aux[3]);
glVertex2f(aux[4], aux[5]);
storePrimitive(aux, 3);
if (flag)
glPopMatrix();
glEnd();
glFlush();
count = 0;
flag = false;
}
}
void init(void)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
xf = 50.0f;
yf = 50.0f;
win = 250.0f;
}
void resize(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
view_w = w;
view_h = h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-win, win, -win, win);
}
void keyboardFunc(unsigned char key, int x, int y)
{
switch (key) {
case 'r': //Clears the screen
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
break;
case 'd': //Redraw scene
Redisplay();
break;
case 't': //Apply a transform to the next primitive
flag = true;
break;
}
}
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON)
if (state == GLUT_DOWN) {
aux[count] = ((2 * win * x) / view_w) - win;
count++;
aux[count] = (((2 * win) * (y - view_h)) / -view_h) - win;
count++;
}
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(650, 600);
glutInitWindowPosition(10, 10);
glutCreateWindow("Example");
glutDisplayFunc(draw);
glutReshapeFunc(resize);
glutKeyboardFunc(keyboardFunc);
glutMouseFunc(mouse);
init();
glutMainLoop();
}
您可以看到可以在绘图函数中对图元应用变换。然而,我想要做的是将转换后的图元的顶点存储在顶点向量中。是否可以在不诉诸手动将变换应用于每个顶点的情况下这样做?
是的,可以使用 OpenGL 的 Transform Feedback。
但是,我发现您使用的是旧式 OpenGL,并且变换反馈仅在 OpenGL 3.0 之后可用。新的 OpenGL 风格非常不同。如果您想使用 TransformFeedback,您需要删除所有代码并从头开始。
OP 找到了从 glBegin/End
捕获 TransformFeedback 的方法:https://www.glprogramming.com/red/chapter13.html#name2
我有如下一段代码:
#include <gl/glut.h>
#include <stdio.h>
GLfloat xf, yf, win;
GLint view_w, view_h;
//auxiliary vector
GLfloat aux[6] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
GLfloat vertices[768] = { 0.0 };
//count for aux vector
int count = 0;
//Meant to be used for drawing different shapes, store the number of vertecies for each primitive
int primitives[64] = {};
//Index
int vIndex = 0;
int pIndex = 0;
bool flag = false;
//Dedraws the scene using the vertices vector
void Redisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
int j = 0;
int k;
for (int i = 0; i < pIndex; i++)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBegin(GL_TRIANGLES);
k = j;
for(; j < k + 2*primitives[i];j+=2)
glVertex2f(vertices[j], vertices[j + 1]);
glEnd();
glFlush();
}
}
//Store vertices in the vertices vector
void storePrimitive(GLfloat *vector, int nVertex)
{
for (int i = 0; i < nVertex * 2; i++)
vertices[vIndex++] = vector[i];
primitives[pIndex++] = nVertex;
}
//Draw scene
void draw(void)
{
if (count > 5)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//If flag is true, apply a transform
if (flag)
{
glPushMatrix();
glScalef(2, 2, 1);
}
glBegin(GL_TRIANGLES);
glVertex2f(aux[0], aux[1]);
glVertex2f(aux[2], aux[3]);
glVertex2f(aux[4], aux[5]);
storePrimitive(aux, 3);
if (flag)
glPopMatrix();
glEnd();
glFlush();
count = 0;
flag = false;
}
}
void init(void)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
xf = 50.0f;
yf = 50.0f;
win = 250.0f;
}
void resize(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
view_w = w;
view_h = h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-win, win, -win, win);
}
void keyboardFunc(unsigned char key, int x, int y)
{
switch (key) {
case 'r': //Clears the screen
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
break;
case 'd': //Redraw scene
Redisplay();
break;
case 't': //Apply a transform to the next primitive
flag = true;
break;
}
}
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON)
if (state == GLUT_DOWN) {
aux[count] = ((2 * win * x) / view_w) - win;
count++;
aux[count] = (((2 * win) * (y - view_h)) / -view_h) - win;
count++;
}
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(650, 600);
glutInitWindowPosition(10, 10);
glutCreateWindow("Example");
glutDisplayFunc(draw);
glutReshapeFunc(resize);
glutKeyboardFunc(keyboardFunc);
glutMouseFunc(mouse);
init();
glutMainLoop();
}
您可以看到可以在绘图函数中对图元应用变换。然而,我想要做的是将转换后的图元的顶点存储在顶点向量中。是否可以在不诉诸手动将变换应用于每个顶点的情况下这样做?
是的,可以使用 OpenGL 的 Transform Feedback。
但是,我发现您使用的是旧式 OpenGL,并且变换反馈仅在 OpenGL 3.0 之后可用。新的 OpenGL 风格非常不同。如果您想使用 TransformFeedback,您需要删除所有代码并从头开始。
OP 找到了从 glBegin/End
捕获 TransformFeedback 的方法:https://www.glprogramming.com/red/chapter13.html#name2