Поиск:

Ответ в темуСоздание новой темы Создание опроса
> проблема с opengl.. не могу найти ошибку 
:(
    Опции темы
NPLana
  Дата 8.11.2005, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 13.5.2005
Где: СПб

Репутация: нет
Всего: нет



всем привет!
помогите разобраться с прогой...суть - натягивание на сферу текстуры земли. мне надо сделать это на билдере. привожу текст своей программы. в ней пока лишь попытка создать сферу... о натягивании сферы пока молчу... кстати речь идет об opengl
было бы здорово, если бы кто-нибудь указал на ошибку именно в этом коде, а не отправлял в хелп....
Код

//---------------------------------------------------------------------------
#include <vcl.h>
#include <math.h>
#pragma hdrstop
#include "UForm1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
const LstEarth = 1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void  TForm1::SetPixelFormatDescriptor()
{     int PixelFormat;
    PIXELFORMATDESCRIPTOR pfd = {
     sizeof(PIXELFORMATDESCRIPTOR),
        1,
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
        PFD_TYPE_RGBA,
        24,
        0,0,0,0,0,0,
        0,0,
        0,0,0,0,0,
        32,
        0,
        0,
        PFD_MAIN_PLANE,
        0,
        0,0,
    };
    PixelFormat = ChoosePixelFormat(hdc, &pfd);
    SetPixelFormat(hdc, PixelFormat, &pfd);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormPaint(TObject *Sender)
{
   DrawScene();
}
//---------------------------------------------------------------------------

void TForm1 :: InitScene()
{
   const GLfloat LightPos[4] = {10.0, 10.0, 0.0, 1.0};

   //LIGHTNING
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
   glLightfv(GL_LIGHT0,GL_POSITION,LightPos);

   GLUquadricObj *Quadric;
   Quadric = gluNewQuadric();
   gluQuadricTexture(Quadric,GL_TRUE);

   //TEXTURE
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
   glEnable(GL_TEXTURE_2D);

   glNewList(LstEarth, GL_COMPILE);
   // PrepareImage("earth.bmp"); //пока эту функцию не беру
     gluSphere(Quadric,1.0,30,30);
   glEndList;

   gluDeleteQuadric(Quadric);

   glEnable(GL_DEPTH_TEST);
   glEnable(GL_COLOR_MATERIAL);

}


void __fastcall TForm1::FormCreate(TObject *Sender)
{
      hdc = GetDC(PView->Handle);
      SetPixelFormatDescriptor();
     hrc = wglCreateContext(hdc);  
     wglMakeCurrent(hdc,hrc);
     InitScene();
}
//---------------------------------------------------------------------------

void TForm1 :: DrawScene()
{  TPaintStruct *ps;


   glViewport(0,0,PView->Width,PView->Height);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 1500.0);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   glTranslatef(0.0,0.0,-6.0);
   glRotatef(-90.0,1.0,0.0,0.0);

  BeginPaint(Handle,ps);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glPushMatrix();
       glRotatef(0.0, 0.0, 0.0, 1.0);
       glRotatef(0, 1, 0, 0.0);
       glCallList(LstEarth);
     glPopMatrix();
     SwapBuffers(hdc);
  EndPaint(Handle,ps);
}

void __fastcall TForm1::FormDestroy(TObject *Sender)
{
  glDeleteLists(LstEarth,1);
  wglMakeCurrent(0,0);
  wglDeleteContext(hrc);
  ReleaseDC(Handle,hdc);
  DeleteDC(hdc);

}
//---------------------------------------------------------------------------


void __fastcall TForm1::FormResize(TObject *Sender)
{
   if (ClientWidth < 518) ClientWidth = 518;
   if (ClientHeight < 546) ClientHeight = 546;
}
//---------------------------------------------------------------------------


Код

//---------------------------------------------------------------------------

#ifndef UForm1H
#define UForm1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <ExtCtrls.hpp>
#include <Graphics.hpp>
#include <Buttons.hpp>

#include <gl\gl.h>
#include <gl\glu.h>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TPanel *PView;
        void __fastcall FormPaint(TObject *Sender);
        void __fastcall FormCreate(TObject *Sender);
        void __fastcall FormDestroy(TObject *Sender);
        void __fastcall FormResize(TObject *Sender);
  private:    // User declarations
        HDC hdc;  
        HGLRC hrc;
    public:        // User declarations
        __fastcall TForm1(TComponent* Owner);
        void SetPixelFormatDescriptor();
        void PrepareImage(AnsiString bmap) ;
        void InitScene();
        void DrawScene();

};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
 

PM MAIL   Вверх
PPS05
Дата 8.11.2005, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 262
Регистрация: 6.11.2005
Где: Беларусь, Минск

Репутация: нет
Всего: 7



Строки 102 и 110: утверждать не буду, но по-моему BeginPaint и EndPaint не нужны. Я всегда писал без них и всё рисовалось.

Строка 103: попробуй поставить перед ней
Код

glClearColor(0.0, 0.0f, 0.0f, 1.0f);  //цвет фона


...а после неё
Код

glClearDepth(1.0);


P.S. Сферу можно рисовать и без создания списка (стр. 64) прямо вместо glCallList


--------------------
Ушел с форума и не вернулся.
PM MAIL ICQ   Вверх
NPLana
Дата 8.11.2005, 19:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 13.5.2005
Где: СПб

Репутация: нет
Всего: нет



не рисуется smile
PM MAIL   Вверх
PPS05
Дата 8.11.2005, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 262
Регистрация: 6.11.2005
Где: Беларусь, Минск

Репутация: нет
Всего: 7



1. (Главная ошибка) В строке 67 после идентификатора функции нет круглых скобок:

glEndList();

Поэтому функция не вызывается, а компилятор её просто игнорирует (таким же образом можно написать имя переменной - ошибки не будет).

2. В обработчике OnResize ты меняешь ClientWidth и ClientHeight, т.е. размеры формы, поэтому OnResize вызыватся циклически ещё 1 раз.

3. Строки 102 и 110 действительно не нужны.

4. Строки 91-97: будет красивее, если напишешь:

Код

...
glViewport(0,0,PView->Width,PView->Height);
gluPerspective(50, (double)PView->Width/PView->Height, 0.1, 200);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
...


Если и после этого не будет работать, пиши: [email protected], я вышлю исходники(я отладил - всё работало).


--------------------
Ушел с форума и не вернулся.
PM MAIL ICQ   Вверх
NPLana
Дата 8.11.2005, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 13.5.2005
Где: СПб

Репутация: нет
Всего: нет



спасибо!!!! действительно дело было в каких-то скобках.... теперь бы наложить текстуру.... к тому же большую - изображение 1024х512...
там у меня был вызов функции PrepareImage("earth.bmp"); - с 65
есть для этих целей код на дельфи.. только вот никак корректно не переписать на си...
Код

procedure TForm1.PrepareImage(bmap: string);
type
  PPixelArray = ^TPixelArray;
  TPixelArray = array [0..0] of Byte;
var
  Bitmap : TBitmap;
  Data : PPixelArray;
  BMInfo : TBitmapInfo;
  I, ImageSize : Integer;
  Temp : Byte;
  MemDC : HDC;
begin
  Bitmap := TBitmap.Create;
  Bitmap.LoadFromFile (bmap);
  with BMinfo.bmiHeader do begin
    FillChar (BMInfo, SizeOf(BMInfo), 0);
    biSize := sizeof (TBitmapInfoHeader);
    biBitCount := 24;
    biWidth := Bitmap.Width;
    biHeight := Bitmap.Height;
    ImageSize := biWidth * biHeight;
    biPlanes := 1;
    biCompression := BI_RGB;
    MemDC := CreateCompatibleDC (0);
    GetMem (Data, ImageSize * 3);
    try
      GetDIBits (MemDC, Bitmap.Handle, 0, biHeight, Data,
                 BMInfo, DIB_RGB_COLORS);
      For I := 0 to ImageSize - 1 do begin
          Temp := Data [I * 3];
          Data [I * 3] := Data [I * 3 + 2];
          Data [I * 3 + 2] := Temp;
      end;
      glTexImage2d(GL_TEXTURE_2D, 0, 3, biWidth,
                   biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, Data);
    finally
      FreeMem (Data);
      DeleteDC (MemDC);
      Bitmap.Free;
    end;
  end;
end;



Это сообщение отредактировал(а) NPLana - 8.11.2005, 23:52
PM MAIL   Вверх
PPS05
Дата 9.11.2005, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 262
Регистрация: 6.11.2005
Где: Беларусь, Минск

Репутация: нет
Всего: 7



Можно проще (скорей - понятней):

Код

unsigned char pixels[W*H*3]; //буфер для текстуры

Graphics::TBitmap * bmp = new Graphics::TBitmap();
bmp->LoadFromFile(FileName);
bmp->PixelFormat = pf24bit; //преобразование глубины цвета в 24 бита

int W3 = W*3;

for (int i=0 ; i<H ; i++) //по всем строкам...
  {
  memcpy(&pixels[i*W3], bmp->ScanLine[i], 3*W); //скопировать стороку из bmp в буфер
  for (int j=0 ; j<W3 ; j+=3) //по всем пикселам в этой строке...
    {
    unsigned char buf = pixels[i*W3+j];
    pixels[i*W3+j] = pixels[i*W3+j+2];
    pixels[i*W3+j+2] = buf;
    }
  }

glTexImage2D(GL_TEXTURE_2D, 0, 3, W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);


Поясню:

FileName - .bmp файл с текстурой
W - ширина текстуры
H - высота
W и H должны быть объявлены как const, т.е.

Код

const W = 1024;
const H = 512;


Чтбы читать текстуры любого размера, придётся отводить память для pixels динамически, но в данном случае это просто не нужно.


--------------------
Ушел с форума и не вернулся.
PM MAIL ICQ   Вверх
NPLana
Дата 9.11.2005, 18:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 13.5.2005
Где: СПб

Репутация: нет
Всего: нет



добавила этот код в функцию PrepareImage, соотвественно раскомметировала строку 65 с вызовом ее.... не пашет!!!:((( пишет :
Project ... faulted witk message: 'access violation at 0x7c90eddc: write of address 0x00030fec'....

PM MAIL   Вверх
PPS05
Дата 9.11.2005, 18:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 262
Регистрация: 6.11.2005
Где: Беларусь, Минск

Репутация: нет
Всего: 7



У меня тоже такое было, пока BeginPaint/EndPaint не убрал.

Приведу полный текст работающей программы (на всякий случай).
В качестве текстуры брал bmp-файл 1024x512.

На форме Form1:
PView : TPanel
Timer1 : TTimer (Interval = 1000)

Unit1.cpp:

Код

//---------------------------------------------------------------------------    
#include <vcl.h>    
#include <math.h>    
#pragma hdrstop    
#include "Unit1.h"    
//---------------------------------------------------------------------------    
#pragma package(smart_init)    
#pragma resource "*.dfm"    
TForm1 *Form1;    
const LstEarth = 1;

const W = 1024, H = 512;
unsigned char pixels[W*H*3];

//---------------------------------------------------------------------------    
__fastcall TForm1::TForm1(TComponent* Owner)    
        : TForm(Owner)    
{    
}    
//---------------------------------------------------------------------------    
void  TForm1::SetPixelFormatDescriptor()    
{     int PixelFormat;    
    PIXELFORMATDESCRIPTOR pfd = {    
     sizeof(PIXELFORMATDESCRIPTOR),    
        1,    
        PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,    
        PFD_TYPE_RGBA,    
        24,    
        0,0,0,0,0,0,    
        0,0,    
        0,0,0,0,0,    
        32,    
        0,    
        0,    
        PFD_MAIN_PLANE,    
        0,    
        0,0,    
    };    
    PixelFormat = ChoosePixelFormat(hdc, &pfd);    
    SetPixelFormat(hdc, PixelFormat, &pfd);    
}    
//---------------------------------------------------------------------------    
void __fastcall TForm1::FormPaint(TObject *Sender)    
{    
   DrawScene();    
}    
//---------------------------------------------------------------------------    

void PrepareImage(AnsiString FileName)
{
Graphics::TBitmap * bmp = new Graphics::TBitmap();    
bmp->LoadFromFile(FileName);    
bmp->PixelFormat = pf24bit;
int W3 = W*3;    
for (int i=0 ; i<H ; i++) //ïî âñåì ñòðîêàì...    
  {    
  memcpy(&pixels[i*W3], bmp->ScanLine[i], 3*W);    
  for (int j=0 ; j<W3 ; j+=3)
    {    
    unsigned char buf = pixels[i*W3+j];    
    pixels[i*W3+j] = pixels[i*W3+j+2];    
    pixels[i*W3+j+2] = buf;    
    }    
  }    
glTexImage2D(GL_TEXTURE_2D, 0, 3, W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
}

void TForm1 :: InitScene()
{    
   const GLfloat LightPos[4] = {10.0, 10.0, 0.0, 1.0};    
   //LIGHTNING    
   glEnable(GL_LIGHTING);    

   glLightfv(GL_LIGHT0,GL_POSITION,LightPos);
   glEnable(GL_LIGHT0);    
   GLUquadricObj *Quadric;    
   Quadric = gluNewQuadric();
   
   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
   PrepareImage("1.bmp");
   glEnable(GL_TEXTURE_2D);
   gluQuadricTexture(Quadric,GL_TRUE);
   
   glNewList(LstEarth, GL_COMPILE);
     gluSphere(Quadric,1.0,30,30);
   glEndList();
    
   gluDeleteQuadric(Quadric);    
   glEnable(GL_DEPTH_TEST);    
   glEnable(GL_COLOR_MATERIAL);

   glEnable(GL_NORMALIZE);    
}    
void __fastcall TForm1::FormCreate(TObject *Sender)    
{    
     hdc = GetDC(PView->Handle);    
     SetPixelFormatDescriptor();
     hrc = wglCreateContext(hdc);    
     wglMakeCurrent(hdc,hrc);    
     InitScene();    
}    
//---------------------------------------------------------------------------    
void TForm1 :: DrawScene()    
{
     glClearColor(0.0, 0.0f, 0.0f, 1.0f);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glClearDepth(1.0);
     glEnable(GL_DEPTH_TEST);

     glViewport(0,0,PView->Width,PView->Height);
     gluPerspective(50, (double)PView->Width/PView->Height, 0.1, 200);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();

     glTranslatef(0.0,0.0,-6.0);
     glRotatef(-90.0,1.0,0.0,0.0);

     glPushMatrix();
       glTranslatef(0, 0, 0);
       glRotatef(0.0, 0.0, 0.0, 1.0);    
       glRotatef(0, 1, 0, 0.0);
       glColor3f(1.0f, 1.0f, 1.0f);    
       glCallList(LstEarth);    
     glPopMatrix();    
     SwapBuffers(hdc);    
    
}    
void __fastcall TForm1::FormDestroy(TObject *Sender)    
{    
  glDeleteLists(LstEarth,1);
  wglMakeCurrent(NULL, NULL);    
  wglDeleteContext(hrc);    
  ReleaseDC(Handle,hdc);    
  DeleteDC(hdc);    
}    
//---------------------------------------------------------------------------    
void __fastcall TForm1::FormResize(TObject *Sender)    
{    
glViewport(0,0,PView->Width,PView->Height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
}    
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
FormPaint(NULL);        
}
//---------------------------------------------------------------------------


Unit1.h:

Код

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>    
#include <Controls.hpp>    
#include <StdCtrls.hpp>    
#include <Forms.hpp>    
#include <ExtCtrls.hpp>    
#include <Graphics.hpp>    
#include <Buttons.hpp>    
#include <gl\gl.h>    
#include <gl\glu.h>    
//---------------------------------------------------------------------------    
class TForm1 : public TForm    
{    
__published:    // IDE-managed Component
        TPanel *PView;
        TTimer *Timer1;
        void __fastcall FormPaint(TObject *Sender);
        void __fastcall FormCreate(TObject *Sender);
        void __fastcall FormDestroy(TObject *Sender);
        void __fastcall FormResize(TObject *Sender);
        void __fastcall Timer1Timer(TObject *Sender);
  private:    // User declarations
        HDC hdc;    
        HGLRC hrc;    
    public:        // User declarations    
        __fastcall TForm1(TComponent* Owner);    
        void SetPixelFormatDescriptor();
        void InitScene();
        void DrawScene();    
};    
//---------------------------------------------------------------------------    
extern PACKAGE TForm1 *Form1;    
//---------------------------------------------------------------------------
#endif



--------------------
Ушел с форума и не вернулся.
PM MAIL ICQ   Вверх
NPLana
Дата 9.11.2005, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 13.5.2005
Где: СПб

Репутация: нет
Всего: нет



спасибо огромное!!!!! буду теперь разбираться
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.3185 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.