- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 Bresenham 的中点算法作为家庭作业,在 OpenGL 上开发一个类似于 MS 绘图的应用程序。到目前为止,我可以画线和椭圆。调整窗口大小时,我将它们全部丢失。如何让它们保持绘制状态?
完整代码:
#include "GL/glut.h"
#include <stdio.h>
#include <math.h>
int i;
//int mainWindow, subWindow;
int X1, Y1, X2, Y2;
int modoDeDibujo;
int W = 1000, H = 1000;
/*void menuApp (int value)
{
if (value == 1) printf("Linea\n");
if (value == 2) printf("Circulo\n");
if (value == 3) printf("Elipsis\n");
if (value == 4) exit(0);
}
void crearMenu()
{
//inicio Creando el menu
int submenu;
submenu = glutCreateMenu(menuApp);
glutAddMenuEntry("Linea", 1);
glutAddMenuEntry("Elipse",3);
glutAddMenuEntry("Salir",4);
glutCreateMenu(menuApp);
glutAddSubMenu("SubMenu", submenu);
glutAttachMenu(GLUT_RIGHT_BUTTON);
//fin Creando el menu
}*/
void renderPoint(void) /*REVISAR ESTO*/
{
glClear (GL_COLOR_BUFFER_BIT);
glBegin (GL_POINTS);
glVertex2f (-0.98, 0.98);
glEnd ();
glFlush ();
}
void renderPoint(double x, double y)
{
//printf("BEFORE TRANSFORM %f\t%f\t# renderPoint\n", x, y);
W = glutGet(GLUT_WINDOW_WIDTH);
H = glutGet(GLUT_WINDOW_HEIGHT);
float X;
float Y;
glBegin (GL_POINTS);
X = (2*x/W) - 1;
Y = (-2*y/H) + 1;
glVertex2f (X, Y);
//printf("TRANSFORMED POINT %f\t%f\t# renderPoint\n", X, Y);
glEnd ();
glFlush ();
}
/*wiki pseudo:
function line(x0, x1, y0, y1) //x1
boolean steep := abs(y1 - y0) > abs(x1 - x0)//x2
if steep then//x3
swap(x0, y0) //x4
swap(x1, y1) //x5
if x0 > x1 then //x6
swap(x0, x1) //x7
swap(y0, y1) //x8
int deltax := x1 - x0 //x9
int deltay := abs(y1 - y0) //x10
int error := deltax / 2 //x11
int ystep //x12
int y := y0 //x13
if y0 < y1 then ystep := 1 else ystep := -1 //x14
for x from x0 to x1 //x15
if steep then plot(y,x) else plot(x,y) //x16
error := error - deltay //x17
if error < 0 then //x18
y := y + ystep //x19
error := error + deltax //x20
*/
void bresenham1(GLint x0, GLint x1, GLint y0, GLint y1) //function line(x0, x1, y0, y1)
{
//double result1 = fabs((double)y1 - y0); //abs(y1 - y0)
//double result2 = fabs((double)x1 - x0); //abs(x1 - x0)
int result1 = abs(y1-y0);
int result2 = abs(x1-x0);
bool steep = (result1 > result2); //boolean steep := abs(y1 - y0) > abs(x1 - x0)
if (steep){ //if steep then
GLint aux1 = x0; //swap(x0, y0)
x0=y0;
y0 = aux1;
GLint aux2 = x1; // swap (x1,y1)
x1=y1;
y1=aux2;
}
if(x0>x1){ // if (x0>x1)
GLint aux3=x0; //swap(x0,x1)
x0=x1;
x1=aux3;
GLint aux4=y0;//swap(y0,y1)
y0=y1;
y1=aux4;
}
int deltax = x1-x0; // deltax = x1-x0
int deltay = abs(y1-y0); // int deltay := abs(y1 - y0) - revisar
int error = (deltax / 2); //int error := deltax / 2
int ystep; // int ystep
int y = y0; //int y := y0
if (y0<y1){ //if y0 < y1 then ystep := 1 else ystep := -1
ystep=1;
}
else {ystep=-1;}
for (int x=x0; x<=x1; x++){ //for x from x0 to x1
if (steep){ // if steep then plot(y,x) else plot(x,y)
renderPoint(y,x);
}
else {
renderPoint(x,y);
}
error = error - deltay; //error := error - deltay
if (error<0) { //if error < 0 then
y = y + ystep; // y := y + ystep
error = error + deltax; //error := error + deltax
} // end if (error<0)
}// end for from x0 to x1
}// end bresenham
void Plot4EllipsePoints(int X, int Y,int CX,int CY){
renderPoint(CX+X, CY+Y); //point in quadrant 1
renderPoint(CX-X, CY+Y); // point in quadrant 2
renderPoint(CX-X, CY-Y); // point in quadrant 3
renderPoint(CX+X, CY-Y); // point in quadrant 4
}
void PlotEllipse (int CX, int CY, int XRadius, int YRadius) {
int X, Y;
int XChange, YChange;
int EllipseError;
int TwoASquare, TwoBSquare;
int StoppingX, StoppingY;
TwoASquare = 2 * XRadius * XRadius;
TwoBSquare = 2 * YRadius * YRadius;
X = XRadius;
Y =0;
XChange = YRadius*YRadius*(1-(2*XRadius));
YChange = XRadius * XRadius;
EllipseError =0;
StoppingX = TwoBSquare*XRadius;
StoppingY = 0;
while(StoppingX >= StoppingY){
Plot4EllipsePoints(X,Y,CX,CY);
Y++;
StoppingY=StoppingY + TwoASquare;
EllipseError= EllipseError+ YChange;
YChange= YChange+ TwoASquare;
if( ((2*EllipseError) + XChange)>0)
{
X--;
StoppingX = StoppingX - TwoBSquare;
EllipseError= EllipseError + XChange;
XChange = XChange + TwoBSquare;
}
}
//1st set of points done, start second set
X=0;
Y= YRadius;
XChange= YRadius*YRadius;
YChange = XRadius*XRadius*(1-2*YRadius);
EllipseError=0;
StoppingX =0;
StoppingY= TwoASquare * YRadius;
while(StoppingX <= StoppingY){ // 2nd set of points, y'<-1
Plot4EllipsePoints(X,Y, CX,CY);
X++;
StoppingX = StoppingX + TwoBSquare;
EllipseError = EllipseError + XChange;
XChange = XChange + TwoBSquare;
if (((2*EllipseError) + YChange)>0){
Y--;
StoppingY = StoppingY - TwoASquare;
EllipseError = EllipseError + YChange;
YChange = YChange + TwoASquare;
}
}
}
void renderAll (void)
{
/*glutSetWindow(mainWindow);
glutPostRedisplay();
glutSetWindow(subWindow);
glutPostRedisplay();*/
}
void movimiento(int boton, int estado, int x, int y)
{
if((estado == GLUT_DOWN) && (boton == GLUT_LEFT_BUTTON))//mouse down
{
X1 = x; Y1 = y;
PlotEllipse (x, y, 200, 100);
renderPoint(x,y);
}
if((estado == GLUT_UP) && (boton == GLUT_LEFT_BUTTON))//mouse up
{
//printf(" Up|x:%d, y:%d\n",x,y);
X2 = x; Y2 = y;
//renderLine();
bresenham1(X1,X2,Y1,Y2);
//PRUEBA USANDO LA PRIMITIVA DE OPENGL
glBegin( GL_LINES );
glEnd();
//renderPoint(x, y);
}
}
void MouseMove(int x, int y)
{
//printf("x:%d | y:%d\n", x,y);
X2 = x; Y2 = y;
//renderLine();
//bresenham1(X1, Y1, X2, Y2);
}
void teclado(unsigned char key, int x, int y)
{
if(key==1){
modoDeDibujo=1; // dibuja lineas
printf("Modo de dibujo: linea");
}
if (key==2){
modoDeDibujo=2; //dibuja elipses
}
if(key == 27)exit(0);
}
void especiales(int key, int x, int y)
{
if(key == GLUT_KEY_F1) exit(0);
}
static void
key(unsigned char k, int x, int y)
{
switch (k) {
case 27: /* Escape */
exit(0);
break;
default:
return;
}
glutPostRedisplay();
}
int main (int argc, char *argv [])
{
i = 0;
//inicializa las operaciones de OpenGL/GLUT, db cr antes de usar funciones GLUT
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGBA);
glutInitWindowPosition (100, 100);
glutInitWindowSize (W, H);
//Crea una ventana de Opengl
glutCreateWindow ("tarea");
glutDisplayFunc (renderPoint);
glutMouseFunc(movimiento);
glutKeyboardFunc(teclado);//teclas ASCII
glutSpecialFunc(especiales);//captura las teclas [f1..f12]
//glutPassiveMotionFunc(pasivo);
glutKeyboardFunc(key);
glutMotionFunc(MouseMove);
//crearMenu();
glutMainLoop ();
}
最佳答案
首先,你需要整理代码。你必须有一个且只有一个显示函数,它清除缓冲区,调用其他绘制函数并将它们刷新到屏幕(或者如果你使用双缓冲区则交换缓冲区)。
在调整窗口大小时,GLUT 将调用显示函数,如您所知,它是 renderPoint() :
glutDisplayFunc (renderPoint);
renderPoint 在重绘“点”之前清除缓冲区,例如:
void renderPoint(void) /*REVISAR ESTO*/
{
glClear (GL_COLOR_BUFFER_BIT);
glBegin (GL_POINTS);
glVertex2f (-0.98, 0.98);
glEnd ();
glFlush ();
}
由于缓冲区已被清除,所有在函数 renderPoint 之外绘制的点(圆的点,线的点..)都没有意义,因为你没有从“主显示函数”中调用它们是渲染点。
如何让点保持在屏幕上?
您必须将点(您想要绘制的任何点)存储在缓冲区中,例如数组、动态数组、std::vector 或其他任何东西。在显示函数中,编写一个循环语句来访问每个点并提取 x 和 y .. 然后绘制它们。
例如,将上面的函数替换为:
class MyPoint {
public:
float x;
float y;
MyPoint(float x, float y)
{
this->x = x;
this->y = y;
} };
#include <vector>
std::vector<MyPoint> testPoints;
void renderPoint(void) /*REVISAR ESTO*/ {
testPoints.push_back(MyPoint(-0.58,0.58));
testPoints.push_back(MyPoint(0.58,0.58));
testPoints.push_back(MyPoint(0.58,-0.58));
glClear (GL_COLOR_BUFFER_BIT);
glPointSize(2);
glBegin (GL_POINTS);
for(int i=0;i<testPoints.size();i++)
{
glVertex2f (testPoints[i].x, testPoints[i].y);
}
glEnd ();
glFlush ();
}
如您所见,通过使用 (std::vector) 等动态数组来存储点并使用 for 循环语句,我们能够使这三个点保持可见。
还有什么?
对其他形状执行相同的方法,以便对于每个“鼠标单击
”事件,您可以添加或 push_back
两个点代表一条线的端点在名为 lineArray
的数组或 std::vector 中。在display function
中,做一个for循环语句,在提取两个线点后绘制每条线。
您应该使用 glutReshapeFunc
和 glViewport
来确保在调整大小事件后视口(viewport)与窗口具有相同的尺寸。而且我认为 gluOrtho2d
比尝试从 Windows 坐标空间映射到 OpenGL 坐标空间更优雅
整理您的代码,以便您只使用一个显示功能。
你的程序可能是这样的:
void drawTestPoints()
{
for(int i=0;i<length;i++)
{
renderPoint(pointsArray[i].x,pointsArray[i].y);// vector of points/(MyPoint)
}
}
void drawLines()
{
for(int i=0;i<length;)
{
MyPoint startPoint = linesArray[i];
MyPoint endPoint = linesArray[i+1];
bresenham1(startPoint.x,endPoint.x,startPoint.y,endPoint.y);
i+=2;
}
}
void drawAll()
{
glClear (GL_COLOR_BUFFER_BIT);
drawTestPoints();
drawLines();
drawOtherShapes();
glFlush();
}
.
.
.
// in the main func:
glutDisplayFunc (drawAll);
==
关于c - opengl:如何在调整大小时将对象保留在窗口中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3939032/
我对 Swift 比较陌生。我在 pickerView 中使用 PFQuery 时遇到了问题。 我正在尝试实现一个 2 组件 pickerView,如下所示: 组件 0:组件 1 “A”:“Altiv
packageUrl="http://192.168.0.112" packageUrl_line=`grep -n "packageUrl" ${file} | head -1 | cut -d "
我遇到了一个烦人的问题。我正在做一个消息传递应用程序。在消息页面中,当用户滚动到顶部时,一旦最上面的单元格可见,它将加载更多消息以显示。因为在加载更多消息时, TableView 的位置在顶部(内容偏
可以屏蔽吗 Jsoup.connect("http://xyz.com").get().html(); 作为对网站的浏览器调用? 我尝试构建一个壁纸下载工具,但在从服务器下载页面时遇到问题。 如果我下
IntelliJ 给了我以下代码的提示: val l = List(0, "1", 2, "3") l.foreach{_ match {case xx:Int => println(xx);case
我正在尝试读取使用三个水平点表示缺失值的 excel 文件,例如... https://population.un.org/wpp/Download/Files/1_Indicators%20(Sta
我有一个 NSPopupButton,其内容绑定(bind)到 NSArray,假设该数组是 @[ @"Option 1", @"Option 2" ]; 其选择的对象绑定(bind)
大家好,我希望您能回答这个问题:) 基本上,我的index.html中有一些html 5视频,并且会自动播放背景音频。 我想发生的是在播放视频标签时将背景音频减少到50%。如果可能的话,如果我可以使用
需要一点帮助来解决这个问题。我的目标是拥有一个可执行的 jar 文件,它可以截取网页的屏幕截图,并且可以在 Windows 和 Linux 机器上运行。我尝试过使用 html2image 但 phan
我知道如何将 comboBox 值插入到 sql 中,但不知道如何在 sql 中用数字替换 comboBox 值。 这是我的组合框编码和处理按钮的一部分。 用户.java JComboBox com
我有一个像这样的 XML 片段: WEL SMIO 01/01/2015 12/31/9999 AAE 01/01/2015
好的,我知道每个人都认为 IFrame 不好,我知道这一点。但我“被要求”在极少数情况下使用一个。 所以我的问题是,当您有一个包含 IFrame 的 .aspx 页面,然后在该 IFrame 中有另一
我有一个 React 应用程序,我在其中使用 axios 库来获取一些值,并将它们设置为处于我状态的 javascript 对象数组 componentDidMount(){ axios.
我必须存储我的 HashMap通过Spring data导入数据库MySql。为了从 HashMap 检索数据,我使用键值,并且可能会发生键不存在的情况,在这种情况下,我必须避免使用 set 方法将值
我有 Size 模型,其中 value 作为字符串。我想根据 value 属性通过将其转换为十进制来排序 size。 has_many :sizes, -> {order 'value ASC'},这
嗨,我有一个 MYSQL 表,例如 PART{ part_id :long,Auto Increment parent_part_id :long root_part_id :long } 我需
我正在尝试将列名为“邮政编码”、“2010 年人口”、“Land-Sq-Mi”和“每平方英里密度”的 CSV 文件导入我的测试表,该表名为 derp--这就是我在开头使用 drop 语句的原因,这样我
我想写一个这样的存储过程: CREATE OR REPLACE FUNCTION my_function(param_1 text, param_2 text DEFAULT NULL::text)
我有一个 RecyclerView,在它之上,有一个 AdView。滚动 RecyclerView 时,我想将 Adview 留在固定位置。我该怎么做? 这是我打开应用程序时的 RecyclerVie
我有一个 UIScrollView,其中包含一个 UIView 容器,该容器包含多个 UITextField。 我想执行以下操作:如果我选择一个字段并且它位于键盘下方,则将文本字段提升到键盘上方 20
我是一名优秀的程序员,十分优秀!