- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 Android 中的 QCAR AR SDK,它使用 OpenGL 2.0,我是 2.0 的新手。 QCAR SDK 适用于基于 CV 的 AR 应用程序,并利用 OpenGL 渲染图像。
我只想在屏幕中央画一个小 X,并使用以下代码。但是 X 不是绘制到正确的坐标,而是延伸到屏幕的边缘。无论我为顶点分配什么值,都会发生这种情况。我无法确定这是缩放问题还是我正在使用的坐标系存在一些混淆。
关于为什么没有正确绘制这些线的任何想法? - 我知道这在 1.1 中会更容易,但我必须使用 2.0。
谢谢
// Clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
GLfloat diagVertices[12];
diagVertices[0] = -10;
diagVertices[1] = -10;
diagVertices[2] = 0.0f;
diagVertices[3] = 10;
diagVertices[4] = 10;
diagVertices[5] = 0.0f;
diagVertices[6] = -10;
diagVertices[7] = 10;
diagVertices[8] = 0.0f;
diagVertices[9] = 10;
diagVertices[10] = -10;
diagVertices[11] = 0.0f;
glUseProgram(diagonalShaderProgramID);
// map the border vertices
glVertexAttribPointer(diagVertexHandle, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) &diagVertices[0]);
// draw it
glEnableVertexAttribArray(diagVertexHandle);
glLineWidth(3.0f);
glDrawArrays(GL_LINES, 0, 4);
glDisableVertexAttribArray(diagVertexHandle);
这是我正在使用的着色器..
static const char* diagLineMeshVertexShader = " \
\
attribute vec4 vertexPosition; \
\
void main() \
{ \
gl_Position = vertexPosition; \
} \
";
static const char* diagLineFragmentShader = " \
\
precision mediump float; \
\
void main() \
{ \
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \
} \
";
因此,我使用 Eclipse 和 Cygwin 在 Windows 7 (64) 中建立了构建环境,并测试了相同的方法 - 绘制顶点属性数组。该代码库源自演示 GSLS 的简单 lighthouse3D 示例。我已经编译并运行示例以确认它按预期呈现。然后我实现了顶点数组,如上所述。我看到了完全相同的问题。无论其顶点值如何,这些线都会延伸到窗口的边缘。
这适用于 GL_VERSION 2.1.2。顶点属性数组的实现以及渲染它们的方法似乎与我通过引用资源找到的其他示例相同。
这是代码..- 我已经注释掉了我修改过的 lighthouse3d 代码部分。
#define WIN32
#include <stdio.h>
#include <stdlib.h>
#include <GL/Glee.h>
#include <GL/glut.h>
#include "textfile.h"
GLuint v,f,f2,p;
float lpos[4] = {1,0.5,1,0};
GLfloat crossVertices[12];
GLint lineVertexHandle = 0;
void changeSize(int w, int h) {
// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0)
h = 1;
float ratio = 1.0* w / h;
// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set the viewport to be the entire window
glViewport(0, 0, w, h);
// Set the correct perspective.
//gluPerspective(45,ratio,1,1000);
gluPerspective(45,ratio,1,10);
glMatrixMode(GL_MODELVIEW);
}
void renderScene(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0.0,0.0,5.0,
0.0,0.0,0.0,
0.0f,1.0f,0.0f);
glLightfv(GL_LIGHT0, GL_POSITION, lpos);
//glutSolidTeapot(1);
// map the border vertices
glVertexAttribPointer(lineVertexHandle, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*) &crossVertices[0]);
glEnableVertexAttribArray(lineVertexHandle);
glLineWidth(1.0f);
glDrawArrays(GL_LINES, 0, 4);
glDisableVertexAttribArray(lineVertexHandle);
glutSwapBuffers();
}
void processNormalKeys(unsigned char key, int x, int y) {
if (key == 27)
exit(0);
}
void setShaders() {
char *vs = NULL,*fs = NULL,*fs2 = NULL;
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
f2 = glCreateShader(GL_FRAGMENT_SHADER);
vs = textFileRead("toon.vert");
fs = textFileRead("toon.frag");
fs2 = textFileRead("toon2.frag");
const char * ff = fs;
const char * ff2 = fs2;
const char * vv = vs;
glShaderSource(v, 1, &vv,NULL);
glShaderSource(f, 1, &ff,NULL);
glShaderSource(f2, 1, &ff2,NULL);
free(vs);free(fs);
glCompileShader(v);
glCompileShader(f);
glCompileShader(f2);
p = glCreateProgram();
glAttachShader(p,f);
glAttachShader(p,f2);
glAttachShader(p,v);
glLinkProgram(p);
glUseProgram(p);
}
void defineVertices(){
crossVertices[0]= 10.0f;
crossVertices[1]=0.0f;
crossVertices[2]=0.0f;
crossVertices[3]= -1 * 10.0f;
crossVertices[4]=0.0f;
crossVertices[5]=0.0f;
crossVertices[6]=0.0f;
crossVertices[7]= 10.0f;
crossVertices[8]=0.0f;
crossVertices[9]=0.0f;
crossVertices[10]= -1 * 10.0f;
crossVertices[11]=0.0f;
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("MM 2004-05");
glutDisplayFunc(renderScene);
glutIdleFunc(renderScene);
glutReshapeFunc(changeSize);
glutKeyboardFunc(processNormalKeys);
glEnable(GL_DEPTH_TEST);
glClearColor(1.0,1.0,1.0,1.0);
glEnable(GL_CULL_FACE);
/*
glewInit();
if (glewIsSupported("GL_VERSION_2_0"))
printf("Ready for OpenGL 2.0\n");
else {
printf("OpenGL 2.0 not supported\n");
exit(1);
}
*/
setShaders();
defineVertices();
glutMainLoop();
// just for compatibiliy purposes
return 0;
}
这是来自 lighthouse3D 示例的顶点着色器...
varying vec3 normal, lightDir;
void main()
{
lightDir = normalize(vec3(gl_LightSource[0].position));
normal = normalize(gl_NormalMatrix * gl_Normal);
gl_Position = ftransform();
}
关于可能导致此问题的原因有什么想法吗?
最佳答案
在您的顶点着色器中,您只需将顶点位置传递给光栅化器,而无需通过模型 View 或投影矩阵来转换它们。尽管这是完全有效的,但您仍然需要注意坐标所在的范围。
在顶点处理阶段之后,你的坐标必须在 [-1,1]
-立方体中,那里的所有东西都被剪掉,然后这个立方体被视口(viewport)变换转换到屏幕空间,例如[0,w]x[0,h]x[0,1]
。所以你的坐标范围从 -10 到 10,所以你的线实际上是屏幕尺寸的 10 倍。如果您指的是像素,则应将 x、y 值从 [-w/2,w/2]x[-h/2,h/2]
缩小到 [- 1,1]
在顶点着色器中。
这与您提供的桌面 GL 项目中的问题相同,您在着色器中调用了 ftransform
,但是您的投影矩阵是一个简单的透视矩阵,不会将您的坐标缩小太多.因此,在此项目中,将对 gluPerspective
的调用替换为 glOrtho(-0.5*w, 0.5*w, -0.5*h, 0.5*h, -1.0, 1.0)
如果您希望线坐标为像素。
还要记住,默认情况下,OpenGL 中的 y 从下到上。因此,如果您希望它的行为有所不同(许多图像处理框架都这样做),那么您也必须在顶点着色器中否定您的 y 坐标(并且同样交换 glOrtho
中的第 3 和第 4 个值> 调用另一个项目)。但请记住,这将反转您渲染的任何三角形的方向,如果有的话。
所以例如在你的顶点着色器中做一些像这样的事情:
uniform vec2 screenSize; //contains the screen size in pixels
attribute vec2 vertexPosition; //why take 4 if you only need 2?
void main()
{
gl_Position = vec4(2.0*vertexPosition/screenSize, 0.0, 1.0);
}
这为您提供了一个以像素为单位的坐标系,原点在中心,y 轴从下到上。如果这不是您想要的,那么请随意尝试转换(它也可以通过 CPU 上的预计算 2.0/screenSize
进行一些优化)。但请始终牢记,在顶点着色器之后,屏幕空间实际上是 [-1,1]
-立方体,然后通过视口(viewport)转换将其转换为以像素为单位的真实屏幕空间(无论哪个值你给了 glViewport
)。
关于android - 帮助纠正 Android OpenGL 2.0 w/QCAR 中的线缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6912918/
我今天刚刚开始使用 while 循环,目前正在编写代码。我必须要求用户输入 while 循环的起始值和结束值。结果应显示起始值和结束值之间所有 4 的倍数。这是家庭作业,因此必须包含 while 循环
我需要一些帮助来了解导致我的应用程序泄漏的原因。应用程序使用 ARC。我在窗口上有一个 NSView,用作文件的放置区。当您将文件拖到窗口上时,我会选择路径和文件名以在应用程序的其他方面使用。 当我通
我在 prometheus 中配置了以下警报: alert: ClockSkewDetected expr: abs(node_timex_offset_seconds{job="node-expor
我在 stackoverflow.com 上看到了以下代码,并将其复制到您在 JMF 上提交的我的系统中: import Logging.LogRunner; //Logging.LogRunner
我正在尝试使用 AngularJS ( Project ) 进行 CRUD,我发现当我按下“Cadastrar”按钮时,它会不断插入数组,即使它是空的。我想要的是防止这种行为发生。 $sc
我有一个如下所示的数据框。我的 Date 字段的数据类型为 datetime64[ns]: symbol high low Date
我有一个 UINavigationControllers 数组,我想将其呈现在自定义侧面菜单 Controller 中。这一切都有效,但是当我将设备方向更改为横向,然后从之前以纵向呈现的数组中呈现 U
我正在处理需要加载到我的 postgresql 数据库中的第三方数据。我遇到了问题,有时我得到的时间是“24:00:30”,而实际上它应该是“00:00:30”。这拒绝了数据。 我尝试转换但没有成功。
我的主要目标是在 MySQL 中创建一个PROCEDURE,以根据传递的纬度和经度查询位置。该查询获取传递给 PROCEDURE 的特定半径内位置的 ID、纬度和经度。我还尝试添加一个 JOIN 来查
我正在创建以下测试触发器,以便在 UPDATE 操作发生时更新字段的值: CREATE TRIGGER `test_index` AFTER UPDATE ON `main_itemmaster` F
我正在尝试创建一个将时间转换为秒的过滤器,例如:01:30:10 到 5410 ,反之亦然,所以最后我的模型只有几秒钟的时间,用户可以看到更好的表示。 到目前为止,我设法使用指令创建了一个工作示例,但
我已经在 Google Play 上构建并发布了我的应用,一切正常。但我想知道如何才能提高我在市场上的知名度,如何出现在首页... 所以这是我的问题, 我是否必须纠正 Lint 警告面板(在 Ecli
我的问题是我有一个列,其中大量数据转储的格式略有错误。 VolumeNumber ------------ Volume 1Numbers 1 & 2 Volume 1Numbers 1 & 2 Vo
我只是在学习如何处理我的 C++ 代码中的错误。我写了这个例子,它寻找一个名为 some file 的文本文件,如果找不到就会抛出异常。 #include #include using names
我有 Project shell_script 和 virtualenv 的结构树是 shell_script/ENV/bin/python3这个目录树应该是什么样子的? 这是行不通的 #!/ENV/
我有 Project shell_script 和 virtualenv 的结构树是 shell_script/ENV/bin/python3这个目录树应该是什么样子的? 这是行不通的 #!/ENV/
使用 Gvim 的 vim-latexsuite,我正在编辑一个相当大的文档。 它由一个包含\begin{document}、\end{document} 等的主文档组成。 在这之间有很多部分写在另一
我需要为串行协议(protocol)进行一些设计,并且遇到了一些我认为其他地方必须考虑过的问题。 所以我想知道是否有一些关于设计串行协议(protocol)的最佳实践的建议。(请陈述一个易于验证的事实
我正在尝试使用 Django 创建一个简单的视频流网站。我使用 cv2 启动网络摄像头,使用 ZMQ 将数据从客户端传输到服务器。我发现了这个link 我用它编写了代码的网络部分。 代码本身工作正常,
我想编写一个自定义损失函数,该函数会惩罚低估权重的正目标值。它的工作方式类似于均方误差,唯一的区别是在所述情况下均方误差将乘以大于 1 的权重。 我是这样写的: def wmse(ground_tru
我是一名优秀的程序员,十分优秀!